diff --git a/.github/workflows/check-change-note.yml b/.github/workflows/check-change-note.yml index f80864ed0199..e701090420dc 100644 --- a/.github/workflows/check-change-note.yml +++ b/.github/workflows/check-change-note.yml @@ -9,6 +9,8 @@ on: - "*/ql/lib/**/*.ql" - "*/ql/lib/**/*.qll" - "*/ql/lib/**/*.yml" + - "shared/**/*.ql" + - "shared/**/*.qll" - "!**/experimental/**" - "!ql/**" - ".github/workflows/check-change-note.yml" diff --git a/.github/workflows/csharp-qltest.yml b/.github/workflows/csharp-qltest.yml index 1dc62c49caff..542a230446f9 100644 --- a/.github/workflows/csharp-qltest.yml +++ b/.github/workflows/csharp-qltest.yml @@ -91,7 +91,7 @@ jobs: run: | # Generate (Asp)NetCore stubs STUBS_PATH=stubs_output - python3 ql/src/Stubs/make_stubs_nuget.py webapp Swashbuckle.AspNetCore.Swagger 6.5.0 "$STUBS_PATH" + python3 scripts/stubs/make_stubs_nuget.py webapp Swashbuckle.AspNetCore.Swagger 6.5.0 "$STUBS_PATH" rm -rf ql/test/resources/stubs/_frameworks # Update existing stubs in the repo with the freshly generated ones mv "$STUBS_PATH/output/stubs/_frameworks" ql/test/resources/stubs/ diff --git a/.github/workflows/csv-coverage-pr-artifacts.yml b/.github/workflows/csv-coverage-pr-artifacts.yml index 48c55b2a6301..8e2df456260f 100644 --- a/.github/workflows/csv-coverage-pr-artifacts.yml +++ b/.github/workflows/csv-coverage-pr-artifacts.yml @@ -89,9 +89,32 @@ jobs: - name: Save PR number run: | mkdir -p pr - echo ${{ github.event.pull_request.number }} > pr/NR + echo ${PR_NUMBER} > pr/NR + env: + PR_NUMBER: ${{ github.event.pull_request.number }} - name: Upload PR number uses: actions/upload-artifact@v3 with: name: pr path: pr/ + - name: Save comment ID (if it exists) + run: | + # Find the latest comment starting with COMMENT_PREFIX + COMMENT_PREFIX=":warning: The head of this PR and the base branch were compared for differences in the framework coverage reports." + COMMENT_ID=$(gh api "repos/${GITHUB_REPOSITORY}/issues/${PR_NUMBER}/comments" --paginate | jq --arg prefix "${COMMENT_PREFIX}" 'map(select(.body|startswith($prefix)) | .id) | max // empty') + if [[ -z ${COMMENT_ID} ]] + then + echo "Comment not found. Not uploading 'comment/ID' artifact." + else + mkdir -p comment + echo ${COMMENT_ID} > comment/ID + fi + env: + GITHUB_TOKEN: ${{ github.token }} + PR_NUMBER: ${{ github.event.pull_request.number }} + - name: Upload comment ID (if it exists) + uses: actions/upload-artifact@v3 + with: + name: comment + path: comment/ + if-no-files-found: ignore diff --git a/codeql-workspace.yml b/codeql-workspace.yml index 2d86498cbeae..03f5866a0c28 100644 --- a/codeql-workspace.yml +++ b/codeql-workspace.yml @@ -6,7 +6,7 @@ provide: - "*/ql/consistency-queries/qlpack.yml" - "*/ql/automodel/src/qlpack.yml" - "*/ql/automodel/test/qlpack.yml" - - "shared/*/qlpack.yml" + - "shared/**/qlpack.yml" - "cpp/ql/test/query-tests/Security/CWE/CWE-190/semmle/tainted/qlpack.yml" - "go/ql/config/legacy-support/qlpack.yml" - "go/build/codeql-extractor-go/codeql-extractor.yml" diff --git a/cpp/downgrades/f79ce79e3b751aeeed59e594633ba5c07a27ef3e/old.dbscheme b/cpp/downgrades/f79ce79e3b751aeeed59e594633ba5c07a27ef3e/old.dbscheme new file mode 100644 index 000000000000..f79ce79e3b75 --- /dev/null +++ b/cpp/downgrades/f79ce79e3b751aeeed59e594633ba5c07a27ef3e/old.dbscheme @@ -0,0 +1,2226 @@ + +/** + * An invocation of the compiler. Note that more than one file may be + * compiled per invocation. For example, this command compiles three + * source files: + * + * gcc -c f1.c f2.c f3.c + * + * The `id` simply identifies the invocation, while `cwd` is the working + * directory from which the compiler was invoked. + */ +compilations( + /** + * An invocation of the compiler. Note that more than one file may + * be compiled per invocation. For example, this command compiles + * three source files: + * + * gcc -c f1.c f2.c f3.c + */ + unique int id : @compilation, + string cwd : string ref +); + +/** + * The arguments that were passed to the extractor for a compiler + * invocation. If `id` is for the compiler invocation + * + * gcc -c f1.c f2.c f3.c + * + * then typically there will be rows for + * + * num | arg + * --- | --- + * 0 | *path to extractor* + * 1 | `--mimic` + * 2 | `/usr/bin/gcc` + * 3 | `-c` + * 4 | f1.c + * 5 | f2.c + * 6 | f3.c + */ +#keyset[id, num] +compilation_args( + int id : @compilation ref, + int num : int ref, + string arg : string ref +); + +/** + * The source files that are compiled by a compiler invocation. + * If `id` is for the compiler invocation + * + * gcc -c f1.c f2.c f3.c + * + * then there will be rows for + * + * num | arg + * --- | --- + * 0 | f1.c + * 1 | f2.c + * 2 | f3.c + * + * Note that even if those files `#include` headers, those headers + * do not appear as rows. + */ +#keyset[id, num] +compilation_compiling_files( + int id : @compilation ref, + int num : int ref, + int file : @file ref +); + +/** + * The time taken by the extractor for a compiler invocation. + * + * For each file `num`, there will be rows for + * + * kind | seconds + * ---- | --- + * 1 | CPU seconds used by the extractor frontend + * 2 | Elapsed seconds during the extractor frontend + * 3 | CPU seconds used by the extractor backend + * 4 | Elapsed seconds during the extractor backend + */ +#keyset[id, num, kind] +compilation_time( + int id : @compilation ref, + int num : int ref, + /* kind: + 1 = frontend_cpu_seconds + 2 = frontend_elapsed_seconds + 3 = extractor_cpu_seconds + 4 = extractor_elapsed_seconds + */ + int kind : int ref, + float seconds : float ref +); + +/** + * An error or warning generated by the extractor. + * The diagnostic message `diagnostic` was generated during compiler + * invocation `compilation`, and is the `file_number_diagnostic_number`th + * message generated while extracting the `file_number`th file of that + * invocation. + */ +#keyset[compilation, file_number, file_number_diagnostic_number] +diagnostic_for( + int diagnostic : @diagnostic ref, + int compilation : @compilation ref, + int file_number : int ref, + int file_number_diagnostic_number : int ref +); + +/** + * If extraction was successful, then `cpu_seconds` and + * `elapsed_seconds` are the CPU time and elapsed time (respectively) + * that extraction took for compiler invocation `id`. + */ +compilation_finished( + unique int id : @compilation ref, + float cpu_seconds : float ref, + float elapsed_seconds : float ref +); + + +/** + * External data, loaded from CSV files during snapshot creation. See + * [Tutorial: Incorporating external data](https://help.semmle.com/wiki/display/SD/Tutorial%3A+Incorporating+external+data) + * for more information. + */ +externalData( + int id : @externalDataElement, + string path : string ref, + int column: int ref, + string value : string ref +); + +/** + * The source location of the snapshot. + */ +sourceLocationPrefix(string prefix : string ref); + +/** + * Information about packages that provide code used during compilation. + * The `id` is just a unique identifier. + * The `namespace` is typically the name of the package manager that + * provided the package (e.g. "dpkg" or "yum"). + * The `package_name` is the name of the package, and `version` is its + * version (as a string). + */ +external_packages( + unique int id: @external_package, + string namespace : string ref, + string package_name : string ref, + string version : string ref +); + +/** + * Holds if File `fileid` was provided by package `package`. + */ +header_to_external_package( + int fileid : @file ref, + int package : @external_package ref +); + +/* + * Version history + */ + +svnentries( + unique int id : @svnentry, + string revision : string ref, + string author : string ref, + date revisionDate : date ref, + int changeSize : int ref +) + +svnaffectedfiles( + int id : @svnentry ref, + int file : @file ref, + string action : string ref +) + +svnentrymsg( + unique int id : @svnentry ref, + string message : string ref +) + +svnchurn( + int commit : @svnentry ref, + int file : @file ref, + int addedLines : int ref, + int deletedLines : int ref +) + +/* + * C++ dbscheme + */ + +extractor_version( + string codeql_version: string ref, + string frontend_version: string ref +) + +@location = @location_stmt | @location_expr | @location_default ; + +/** + * The location of an element that is not an expression or a statement. + * The location spans column `startcolumn` of line `startline` to + * column `endcolumn` of line `endline` in file `file`. + * For more information, see + * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). + */ +locations_default( + /** The location of an element that is not an expression or a statement. */ + unique int id: @location_default, + int container: @container ref, + int startLine: int ref, + int startColumn: int ref, + int endLine: int ref, + int endColumn: int ref +); + +/** + * The location of a statement. + * The location spans column `startcolumn` of line `startline` to + * column `endcolumn` of line `endline` in file `file`. + * For more information, see + * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). + */ +locations_stmt( + /** The location of a statement. */ + unique int id: @location_stmt, + int container: @container ref, + int startLine: int ref, + int startColumn: int ref, + int endLine: int ref, + int endColumn: int ref +); + +/** + * The location of an expression. + * The location spans column `startcolumn` of line `startline` to + * column `endcolumn` of line `endline` in file `file`. + * For more information, see + * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). + */ +locations_expr( + /** The location of an expression. */ + unique int id: @location_expr, + int container: @container ref, + int startLine: int ref, + int startColumn: int ref, + int endLine: int ref, + int endColumn: int ref +); + +/** An element for which line-count information is available. */ +@sourceline = @file | @function | @variable | @enumconstant | @xmllocatable; + +numlines( + int element_id: @sourceline ref, + int num_lines: int ref, + int num_code: int ref, + int num_comment: int ref +); + +diagnostics( + unique int id: @diagnostic, + int severity: int ref, + string error_tag: string ref, + string error_message: string ref, + string full_error_message: string ref, + int location: @location_default ref +); + +files( + unique int id: @file, + string name: string ref +); + +folders( + unique int id: @folder, + string name: string ref +); + +@container = @folder | @file + +containerparent( + int parent: @container ref, + unique int child: @container ref +); + +fileannotations( + int id: @file ref, + int kind: int ref, + string name: string ref, + string value: string ref +); + +inmacroexpansion( + int id: @element ref, + int inv: @macroinvocation ref +); + +affectedbymacroexpansion( + int id: @element ref, + int inv: @macroinvocation ref +); + +case @macroinvocation.kind of + 1 = @macro_expansion +| 2 = @other_macro_reference +; + +macroinvocations( + unique int id: @macroinvocation, + int macro_id: @ppd_define ref, + int location: @location_default ref, + int kind: int ref +); + +macroparent( + unique int id: @macroinvocation ref, + int parent_id: @macroinvocation ref +); + +// a macroinvocation may be part of another location +// the way to find a constant expression that uses a macro +// is thus to find a constant expression that has a location +// to which a macro invocation is bound +macrolocationbind( + int id: @macroinvocation ref, + int location: @location ref +); + +#keyset[invocation, argument_index] +macro_argument_unexpanded( + int invocation: @macroinvocation ref, + int argument_index: int ref, + string text: string ref +); + +#keyset[invocation, argument_index] +macro_argument_expanded( + int invocation: @macroinvocation ref, + int argument_index: int ref, + string text: string ref +); + +/* +case @function.kind of + 1 = @normal_function +| 2 = @constructor +| 3 = @destructor +| 4 = @conversion_function +| 5 = @operator +| 6 = @builtin_function // GCC built-in functions, e.g. __builtin___memcpy_chk +; +*/ + +functions( + unique int id: @function, + string name: string ref, + int kind: int ref +); + +function_entry_point( + int id: @function ref, + unique int entry_point: @stmt ref +); + +function_return_type( + int id: @function ref, + int return_type: @type ref +); + +/** + * If `function` is a coroutine, then this gives the `std::experimental::resumable_traits` + * instance associated with it, and the variables representing the `handle` and `promise` + * for it. + */ +coroutine( + unique int function: @function ref, + int traits: @type ref, + int handle: @variable ref, + int promise: @variable ref +); + +/** The `new` function used for allocating the coroutine state, if any. */ +coroutine_new( + unique int function: @function ref, + int new: @function ref +); + +/** The `delete` function used for deallocating the coroutine state, if any. */ +coroutine_delete( + unique int function: @function ref, + int delete: @function ref +); + +purefunctions(unique int id: @function ref); + +function_deleted(unique int id: @function ref); + +function_defaulted(unique int id: @function ref); + +member_function_this_type( + unique int id: @function ref, + int this_type: @type ref +); + +#keyset[id, type_id] +fun_decls( + int id: @fun_decl, + int function: @function ref, + int type_id: @type ref, + string name: string ref, + int location: @location_default ref +); +fun_def(unique int id: @fun_decl ref); +fun_specialized(unique int id: @fun_decl ref); +fun_implicit(unique int id: @fun_decl ref); +fun_decl_specifiers( + int id: @fun_decl ref, + string name: string ref +) +#keyset[fun_decl, index] +fun_decl_throws( + int fun_decl: @fun_decl ref, + int index: int ref, + int type_id: @type ref +); +/* an empty throw specification is different from none */ +fun_decl_empty_throws(unique int fun_decl: @fun_decl ref); +fun_decl_noexcept( + int fun_decl: @fun_decl ref, + int constant: @expr ref +); +fun_decl_empty_noexcept(int fun_decl: @fun_decl ref); +fun_decl_typedef_type( + unique int fun_decl: @fun_decl ref, + int typedeftype_id: @usertype ref +); + +param_decl_bind( + unique int id: @var_decl ref, + int index: int ref, + int fun_decl: @fun_decl ref +); + +#keyset[id, type_id] +var_decls( + int id: @var_decl, + int variable: @variable ref, + int type_id: @type ref, + string name: string ref, + int location: @location_default ref +); +var_def(unique int id: @var_decl ref); +var_decl_specifiers( + int id: @var_decl ref, + string name: string ref +) +is_structured_binding(unique int id: @variable ref); + +type_decls( + unique int id: @type_decl, + int type_id: @type ref, + int location: @location_default ref +); +type_def(unique int id: @type_decl ref); +type_decl_top( + unique int type_decl: @type_decl ref +); + +namespace_decls( + unique int id: @namespace_decl, + int namespace_id: @namespace ref, + int location: @location_default ref, + int bodylocation: @location_default ref +); + +usings( + unique int id: @using, + int element_id: @element ref, + int location: @location_default ref +); + +/** The element which contains the `using` declaration. */ +using_container( + int parent: @element ref, + int child: @using ref +); + +static_asserts( + unique int id: @static_assert, + int condition : @expr ref, + string message : string ref, + int location: @location_default ref, + int enclosing : @element ref +); + +// each function has an ordered list of parameters +#keyset[id, type_id] +#keyset[function, index, type_id] +params( + int id: @parameter, + int function: @functionorblock ref, + int index: int ref, + int type_id: @type ref +); + +overrides( + int new: @function ref, + int old: @function ref +); + +#keyset[id, type_id] +membervariables( + int id: @membervariable, + int type_id: @type ref, + string name: string ref +); + +#keyset[id, type_id] +globalvariables( + int id: @globalvariable, + int type_id: @type ref, + string name: string ref +); + +#keyset[id, type_id] +localvariables( + int id: @localvariable, + int type_id: @type ref, + string name: string ref +); + +autoderivation( + unique int var: @variable ref, + int derivation_type: @type ref +); + +orphaned_variables( + int var: @localvariable ref, + int function: @function ref +) + +enumconstants( + unique int id: @enumconstant, + int parent: @usertype ref, + int index: int ref, + int type_id: @type ref, + string name: string ref, + int location: @location_default ref +); + +@variable = @localscopevariable | @globalvariable | @membervariable; + +@localscopevariable = @localvariable | @parameter; + +/** + * Built-in types are the fundamental types, e.g., integral, floating, and void. + */ +case @builtintype.kind of + 1 = @errortype +| 2 = @unknowntype +| 3 = @void +| 4 = @boolean +| 5 = @char +| 6 = @unsigned_char +| 7 = @signed_char +| 8 = @short +| 9 = @unsigned_short +| 10 = @signed_short +| 11 = @int +| 12 = @unsigned_int +| 13 = @signed_int +| 14 = @long +| 15 = @unsigned_long +| 16 = @signed_long +| 17 = @long_long +| 18 = @unsigned_long_long +| 19 = @signed_long_long +// ... 20 Microsoft-specific __int8 +// ... 21 Microsoft-specific __int16 +// ... 22 Microsoft-specific __int32 +// ... 23 Microsoft-specific __int64 +| 24 = @float +| 25 = @double +| 26 = @long_double +| 27 = @complex_float // C99-specific _Complex float +| 28 = @complex_double // C99-specific _Complex double +| 29 = @complex_long_double // C99-specific _Complex long double +| 30 = @imaginary_float // C99-specific _Imaginary float +| 31 = @imaginary_double // C99-specific _Imaginary double +| 32 = @imaginary_long_double // C99-specific _Imaginary long double +| 33 = @wchar_t // Microsoft-specific +| 34 = @decltype_nullptr // C++11 +| 35 = @int128 // __int128 +| 36 = @unsigned_int128 // unsigned __int128 +| 37 = @signed_int128 // signed __int128 +| 38 = @float128 // __float128 +| 39 = @complex_float128 // _Complex __float128 +| 40 = @decimal32 // _Decimal32 +| 41 = @decimal64 // _Decimal64 +| 42 = @decimal128 // _Decimal128 +| 43 = @char16_t +| 44 = @char32_t +| 45 = @std_float32 // _Float32 +| 46 = @float32x // _Float32x +| 47 = @std_float64 // _Float64 +| 48 = @float64x // _Float64x +| 49 = @std_float128 // _Float128 +// ... 50 _Float128x +| 51 = @char8_t +| 52 = @float16 // _Float16 +| 53 = @complex_float16 // _Complex _Float16 +| 54 = @fp16 // __fp16 +| 55 = @std_bfloat16 // __bf16 +| 56 = @std_float16 // std::float16_t +| 57 = @complex_std_float32 // _Complex _Float32 +| 58 = @complex_float32x // _Complex _Float32x +| 59 = @complex_std_float64 // _Complex _Float64 +| 60 = @complex_float64x // _Complex _Float64x +| 61 = @complex_std_float128 // _Complex _Float128 +; + +builtintypes( + unique int id: @builtintype, + string name: string ref, + int kind: int ref, + int size: int ref, + int sign: int ref, + int alignment: int ref +); + +/** + * Derived types are types that are directly derived from existing types and + * point to, refer to, transform type data to return a new type. + */ +case @derivedtype.kind of + 1 = @pointer +| 2 = @reference +| 3 = @type_with_specifiers +| 4 = @array +| 5 = @gnu_vector +| 6 = @routineptr +| 7 = @routinereference +| 8 = @rvalue_reference // C++11 +// ... 9 type_conforming_to_protocols deprecated +| 10 = @block +; + +derivedtypes( + unique int id: @derivedtype, + string name: string ref, + int kind: int ref, + int type_id: @type ref +); + +pointerishsize(unique int id: @derivedtype ref, + int size: int ref, + int alignment: int ref); + +arraysizes( + unique int id: @derivedtype ref, + int num_elements: int ref, + int bytesize: int ref, + int alignment: int ref +); + +typedefbase( + unique int id: @usertype ref, + int type_id: @type ref +); + +/** + * An instance of the C++11 `decltype` operator. For example: + * ``` + * int a; + * decltype(1+a) b; + * ``` + * Here `expr` is `1+a`. + * + * Sometimes an additional pair of parentheses around the expression + * would change the semantics of this decltype, e.g. + * ``` + * struct A { double x; }; + * const A* a = new A(); + * decltype( a->x ); // type is double + * decltype((a->x)); // type is const double& + * ``` + * (Please consult the C++11 standard for more details). + * `parentheses_would_change_meaning` is `true` iff that is the case. + */ +#keyset[id, expr] +decltypes( + int id: @decltype, + int expr: @expr ref, + int base_type: @type ref, + boolean parentheses_would_change_meaning: boolean ref +); + +/* +case @usertype.kind of + 1 = @struct +| 2 = @class +| 3 = @union +| 4 = @enum +| 5 = @typedef // classic C: typedef typedef type name +| 6 = @template +| 7 = @template_parameter +| 8 = @template_template_parameter +| 9 = @proxy_class // a proxy class associated with a template parameter +// ... 10 objc_class deprecated +// ... 11 objc_protocol deprecated +// ... 12 objc_category deprecated +| 13 = @scoped_enum +| 14 = @using_alias // a using name = type style typedef +; +*/ + +usertypes( + unique int id: @usertype, + string name: string ref, + int kind: int ref +); + +usertypesize( + unique int id: @usertype ref, + int size: int ref, + int alignment: int ref +); + +usertype_final(unique int id: @usertype ref); + +usertype_uuid( + unique int id: @usertype ref, + string uuid: string ref +); + +mangled_name( + unique int id: @declaration ref, + int mangled_name : @mangledname +); + +is_pod_class(unique int id: @usertype ref); +is_standard_layout_class(unique int id: @usertype ref); + +is_complete(unique int id: @usertype ref); + +is_class_template(unique int id: @usertype ref); +class_instantiation( + int to: @usertype ref, + int from: @usertype ref +); +class_template_argument( + int type_id: @usertype ref, + int index: int ref, + int arg_type: @type ref +); +class_template_argument_value( + int type_id: @usertype ref, + int index: int ref, + int arg_value: @expr ref +); + +is_proxy_class_for( + unique int id: @usertype ref, + unique int templ_param_id: @usertype ref +); + +type_mentions( + unique int id: @type_mention, + int type_id: @type ref, + int location: @location ref, + // a_symbol_reference_kind from the frontend. + int kind: int ref +); + +is_function_template(unique int id: @function ref); +function_instantiation( + unique int to: @function ref, + int from: @function ref +); +function_template_argument( + int function_id: @function ref, + int index: int ref, + int arg_type: @type ref +); +function_template_argument_value( + int function_id: @function ref, + int index: int ref, + int arg_value: @expr ref +); + +is_variable_template(unique int id: @variable ref); +variable_instantiation( + unique int to: @variable ref, + int from: @variable ref +); +variable_template_argument( + int variable_id: @variable ref, + int index: int ref, + int arg_type: @type ref +); +variable_template_argument_value( + int variable_id: @variable ref, + int index: int ref, + int arg_value: @expr ref +); + +/* + Fixed point types + precision(1) = short, precision(2) = default, precision(3) = long + is_unsigned(1) = unsigned is_unsigned(2) = signed + is_fract_type(1) = declared with _Fract + saturating(1) = declared with _Sat +*/ +/* TODO +fixedpointtypes( + unique int id: @fixedpointtype, + int precision: int ref, + int is_unsigned: int ref, + int is_fract_type: int ref, + int saturating: int ref); +*/ + +routinetypes( + unique int id: @routinetype, + int return_type: @type ref +); + +routinetypeargs( + int routine: @routinetype ref, + int index: int ref, + int type_id: @type ref +); + +ptrtomembers( + unique int id: @ptrtomember, + int type_id: @type ref, + int class_id: @type ref +); + +/* + specifiers for types, functions, and variables + + "public", + "protected", + "private", + + "const", + "volatile", + "static", + + "pure", + "virtual", + "sealed", // Microsoft + "__interface", // Microsoft + "inline", + "explicit", + + "near", // near far extension + "far", // near far extension + "__ptr32", // Microsoft + "__ptr64", // Microsoft + "__sptr", // Microsoft + "__uptr", // Microsoft + "dllimport", // Microsoft + "dllexport", // Microsoft + "thread", // Microsoft + "naked", // Microsoft + "microsoft_inline", // Microsoft + "forceinline", // Microsoft + "selectany", // Microsoft + "nothrow", // Microsoft + "novtable", // Microsoft + "noreturn", // Microsoft + "noinline", // Microsoft + "noalias", // Microsoft + "restrict", // Microsoft +*/ + +specifiers( + unique int id: @specifier, + unique string str: string ref +); + +typespecifiers( + int type_id: @type ref, + int spec_id: @specifier ref +); + +funspecifiers( + int func_id: @function ref, + int spec_id: @specifier ref +); + +varspecifiers( + int var_id: @accessible ref, + int spec_id: @specifier ref +); + +attributes( + unique int id: @attribute, + int kind: int ref, + string name: string ref, + string name_space: string ref, + int location: @location_default ref +); + +case @attribute.kind of + 0 = @gnuattribute +| 1 = @stdattribute +| 2 = @declspec +| 3 = @msattribute +| 4 = @alignas +// ... 5 @objc_propertyattribute deprecated +; + +attribute_args( + unique int id: @attribute_arg, + int kind: int ref, + int attribute: @attribute ref, + int index: int ref, + int location: @location_default ref +); + +case @attribute_arg.kind of + 0 = @attribute_arg_empty +| 1 = @attribute_arg_token +| 2 = @attribute_arg_constant +| 3 = @attribute_arg_type +| 4 = @attribute_arg_constant_expr +; + +attribute_arg_value( + unique int arg: @attribute_arg ref, + string value: string ref +); +attribute_arg_type( + unique int arg: @attribute_arg ref, + int type_id: @type ref +); +attribute_arg_constant( + unique int arg: @attribute_arg ref, + int constant: @expr ref +) +attribute_arg_name( + unique int arg: @attribute_arg ref, + string name: string ref +); + +typeattributes( + int type_id: @type ref, + int spec_id: @attribute ref +); + +funcattributes( + int func_id: @function ref, + int spec_id: @attribute ref +); + +varattributes( + int var_id: @accessible ref, + int spec_id: @attribute ref +); + +stmtattributes( + int stmt_id: @stmt ref, + int spec_id: @attribute ref +); + +@type = @builtintype + | @derivedtype + | @usertype + /* TODO | @fixedpointtype */ + | @routinetype + | @ptrtomember + | @decltype; + +unspecifiedtype( + unique int type_id: @type ref, + int unspecified_type_id: @type ref +); + +member( + int parent: @type ref, + int index: int ref, + int child: @member ref +); + +@enclosingfunction_child = @usertype | @variable | @namespace + +enclosingfunction( + unique int child: @enclosingfunction_child ref, + int parent: @function ref +); + +derivations( + unique int derivation: @derivation, + int sub: @type ref, + int index: int ref, + int super: @type ref, + int location: @location_default ref +); + +derspecifiers( + int der_id: @derivation ref, + int spec_id: @specifier ref +); + +/** + * Contains the byte offset of the base class subobject within the derived + * class. Only holds for non-virtual base classes, but see table + * `virtual_base_offsets` for offsets of virtual base class subobjects. + */ +direct_base_offsets( + unique int der_id: @derivation ref, + int offset: int ref +); + +/** + * Contains the byte offset of the virtual base class subobject for class + * `super` within a most-derived object of class `sub`. `super` can be either a + * direct or indirect base class. + */ +#keyset[sub, super] +virtual_base_offsets( + int sub: @usertype ref, + int super: @usertype ref, + int offset: int ref +); + +frienddecls( + unique int id: @frienddecl, + int type_id: @type ref, + int decl_id: @declaration ref, + int location: @location_default ref +); + +@declaredtype = @usertype ; + +@declaration = @function + | @declaredtype + | @variable + | @enumconstant + | @frienddecl; + +@member = @membervariable + | @function + | @declaredtype + | @enumconstant; + +@locatable = @diagnostic + | @declaration + | @ppd_include + | @ppd_define + | @macroinvocation + /*| @funcall*/ + | @xmllocatable + | @attribute + | @attribute_arg; + +@namedscope = @namespace | @usertype; + +@element = @locatable + | @file + | @folder + | @specifier + | @type + | @expr + | @namespace + | @initialiser + | @stmt + | @derivation + | @comment + | @preprocdirect + | @fun_decl + | @var_decl + | @type_decl + | @namespace_decl + | @using + | @namequalifier + | @specialnamequalifyingelement + | @static_assert + | @type_mention + | @lambdacapture; + +@exprparent = @element; + +comments( + unique int id: @comment, + string contents: string ref, + int location: @location_default ref +); + +commentbinding( + int id: @comment ref, + int element: @element ref +); + +exprconv( + int converted: @expr ref, + unique int conversion: @expr ref +); + +compgenerated(unique int id: @element ref); + +/** + * `destructor_call` destructs the `i`'th entity that should be + * destructed following `element`. Note that entities should be + * destructed in reverse construction order, so for a given `element` + * these should be called from highest to lowest `i`. + */ +#keyset[element, destructor_call] +#keyset[element, i] +synthetic_destructor_call( + int element: @element ref, + int i: int ref, + int destructor_call: @routineexpr ref +); + +namespaces( + unique int id: @namespace, + string name: string ref +); + +namespace_inline( + unique int id: @namespace ref +); + +namespacembrs( + int parentid: @namespace ref, + unique int memberid: @namespacembr ref +); + +@namespacembr = @declaration | @namespace; + +exprparents( + int expr_id: @expr ref, + int child_index: int ref, + int parent_id: @exprparent ref +); + +expr_isload(unique int expr_id: @expr ref); + +@cast = @c_style_cast + | @const_cast + | @dynamic_cast + | @reinterpret_cast + | @static_cast + ; + +/* +case @conversion.kind of + 0 = @simple_conversion // a numeric conversion, qualification conversion, or a reinterpret_cast +| 1 = @bool_conversion // conversion to 'bool' +| 2 = @base_class_conversion // a derived-to-base conversion +| 3 = @derived_class_conversion // a base-to-derived conversion +| 4 = @pm_base_class_conversion // a derived-to-base conversion of a pointer to member +| 5 = @pm_derived_class_conversion // a base-to-derived conversion of a pointer to member +| 6 = @glvalue_adjust // an adjustment of the type of a glvalue +| 7 = @prvalue_adjust // an adjustment of the type of a prvalue +; +*/ +/** + * Describes the semantics represented by a cast expression. This is largely + * independent of the source syntax of the cast, so it is separate from the + * regular expression kind. + */ +conversionkinds( + unique int expr_id: @cast ref, + int kind: int ref +); + +@conversion = @cast + | @array_to_pointer + | @parexpr + | @reference_to + | @ref_indirect + | @temp_init + ; + +/* +case @funbindexpr.kind of + 0 = @normal_call // a normal call +| 1 = @virtual_call // a virtual call +| 2 = @adl_call // a call whose target is only found by ADL +; +*/ +iscall( + unique int caller: @funbindexpr ref, + int kind: int ref +); + +numtemplatearguments( + unique int expr_id: @expr ref, + int num: int ref +); + +specialnamequalifyingelements( + unique int id: @specialnamequalifyingelement, + unique string name: string ref +); + +@namequalifiableelement = @expr | @namequalifier; +@namequalifyingelement = @namespace + | @specialnamequalifyingelement + | @usertype; + +namequalifiers( + unique int id: @namequalifier, + unique int qualifiableelement: @namequalifiableelement ref, + int qualifyingelement: @namequalifyingelement ref, + int location: @location_default ref +); + +varbind( + int expr: @varbindexpr ref, + int var: @accessible ref +); + +funbind( + int expr: @funbindexpr ref, + int fun: @function ref +); + +@any_new_expr = @new_expr + | @new_array_expr; + +@new_or_delete_expr = @any_new_expr + | @delete_expr + | @delete_array_expr; + +@prefix_crement_expr = @preincrexpr | @predecrexpr; + +@postfix_crement_expr = @postincrexpr | @postdecrexpr; + +@increment_expr = @preincrexpr | @postincrexpr; + +@decrement_expr = @predecrexpr | @postdecrexpr; + +@crement_expr = @increment_expr | @decrement_expr; + +@un_arith_op_expr = @arithnegexpr + | @unaryplusexpr + | @conjugation + | @realpartexpr + | @imagpartexpr + | @crement_expr + ; + +@un_bitwise_op_expr = @complementexpr; + +@un_log_op_expr = @notexpr; + +@un_op_expr = @address_of + | @indirect + | @un_arith_op_expr + | @un_bitwise_op_expr + | @builtinaddressof + | @vec_fill + | @un_log_op_expr + | @co_await + | @co_yield + ; + +@bin_log_op_expr = @andlogicalexpr | @orlogicalexpr; + +@cmp_op_expr = @eq_op_expr | @rel_op_expr; + +@eq_op_expr = @eqexpr | @neexpr; + +@rel_op_expr = @gtexpr + | @ltexpr + | @geexpr + | @leexpr + | @spaceshipexpr + ; + +@bin_bitwise_op_expr = @lshiftexpr + | @rshiftexpr + | @andexpr + | @orexpr + | @xorexpr + ; + +@p_arith_op_expr = @paddexpr + | @psubexpr + | @pdiffexpr + ; + +@bin_arith_op_expr = @addexpr + | @subexpr + | @mulexpr + | @divexpr + | @remexpr + | @jmulexpr + | @jdivexpr + | @fjaddexpr + | @jfaddexpr + | @fjsubexpr + | @jfsubexpr + | @minexpr + | @maxexpr + | @p_arith_op_expr + ; + +@bin_op_expr = @bin_arith_op_expr + | @bin_bitwise_op_expr + | @cmp_op_expr + | @bin_log_op_expr + ; + +@op_expr = @un_op_expr + | @bin_op_expr + | @assign_expr + | @conditionalexpr + ; + +@assign_arith_expr = @assignaddexpr + | @assignsubexpr + | @assignmulexpr + | @assigndivexpr + | @assignremexpr + ; + +@assign_bitwise_expr = @assignandexpr + | @assignorexpr + | @assignxorexpr + | @assignlshiftexpr + | @assignrshiftexpr + | @assignpaddexpr + | @assignpsubexpr + ; + +@assign_op_expr = @assign_arith_expr | @assign_bitwise_expr + +@assign_expr = @assignexpr | @assign_op_expr | @blockassignexpr + +/* + case @allocator.form of + 0 = plain + | 1 = alignment + ; +*/ + +/** + * The allocator function associated with a `new` or `new[]` expression. + * The `form` column specified whether the allocation call contains an alignment + * argument. + */ +expr_allocator( + unique int expr: @any_new_expr ref, + int func: @function ref, + int form: int ref +); + +/* + case @deallocator.form of + 0 = plain + | 1 = size + | 2 = alignment + | 3 = size_and_alignment + ; +*/ + +/** + * The deallocator function associated with a `delete`, `delete[]`, `new`, or + * `new[]` expression. For a `new` or `new[]` expression, the deallocator is the + * one used to free memory if the initialization throws an exception. + * The `form` column specifies whether the deallocation call contains a size + * argument, and alignment argument, or both. + */ +expr_deallocator( + unique int expr: @new_or_delete_expr ref, + int func: @function ref, + int form: int ref +); + +/** + * Holds if the `@conditionalexpr` is of the two operand form + * `guard ? : false`. + */ +expr_cond_two_operand( + unique int cond: @conditionalexpr ref +); + +/** + * The guard of `@conditionalexpr` `guard ? true : false` + */ +expr_cond_guard( + unique int cond: @conditionalexpr ref, + int guard: @expr ref +); + +/** + * The expression used when the guard of `@conditionalexpr` + * `guard ? true : false` holds. For the two operand form + * `guard ?: false` consider using `expr_cond_guard` instead. + */ +expr_cond_true( + unique int cond: @conditionalexpr ref, + int true: @expr ref +); + +/** + * The expression used when the guard of `@conditionalexpr` + * `guard ? true : false` does not hold. + */ +expr_cond_false( + unique int cond: @conditionalexpr ref, + int false: @expr ref +); + +/** A string representation of the value. */ +values( + unique int id: @value, + string str: string ref +); + +/** The actual text in the source code for the value, if any. */ +valuetext( + unique int id: @value ref, + string text: string ref +); + +valuebind( + int val: @value ref, + unique int expr: @expr ref +); + +fieldoffsets( + unique int id: @variable ref, + int byteoffset: int ref, + int bitoffset: int ref +); + +bitfield( + unique int id: @variable ref, + int bits: int ref, + int declared_bits: int ref +); + +/* TODO +memberprefix( + int member: @expr ref, + int prefix: @expr ref +); +*/ + +/* + kind(1) = mbrcallexpr + kind(2) = mbrptrcallexpr + kind(3) = mbrptrmbrcallexpr + kind(4) = ptrmbrptrmbrcallexpr + kind(5) = mbrreadexpr // x.y + kind(6) = mbrptrreadexpr // p->y + kind(7) = mbrptrmbrreadexpr // x.*pm + kind(8) = mbrptrmbrptrreadexpr // x->*pm + kind(9) = staticmbrreadexpr // static x.y + kind(10) = staticmbrptrreadexpr // static p->y +*/ +/* TODO +memberaccess( + int member: @expr ref, + int kind: int ref +); +*/ + +initialisers( + unique int init: @initialiser, + int var: @accessible ref, + unique int expr: @expr ref, + int location: @location_expr ref +); + +braced_initialisers( + int init: @initialiser ref +); + +/** + * An ancestor for the expression, for cases in which we cannot + * otherwise find the expression's parent. + */ +expr_ancestor( + int exp: @expr ref, + int ancestor: @element ref +); + +exprs( + unique int id: @expr, + int kind: int ref, + int location: @location_expr ref +); + +/* + case @value.category of + 1 = prval + | 2 = xval + | 3 = lval + ; +*/ +expr_types( + int id: @expr ref, + int typeid: @type ref, + int value_category: int ref +); + +case @expr.kind of + 1 = @errorexpr +| 2 = @address_of // & AddressOfExpr +| 3 = @reference_to // ReferenceToExpr (implicit?) +| 4 = @indirect // * PointerDereferenceExpr +| 5 = @ref_indirect // ReferenceDereferenceExpr (implicit?) +// ... +| 8 = @array_to_pointer // (???) +| 9 = @vacuous_destructor_call // VacuousDestructorCall +// ... +| 11 = @assume // Microsoft +| 12 = @parexpr +| 13 = @arithnegexpr +| 14 = @unaryplusexpr +| 15 = @complementexpr +| 16 = @notexpr +| 17 = @conjugation // GNU ~ operator +| 18 = @realpartexpr // GNU __real +| 19 = @imagpartexpr // GNU __imag +| 20 = @postincrexpr +| 21 = @postdecrexpr +| 22 = @preincrexpr +| 23 = @predecrexpr +| 24 = @conditionalexpr +| 25 = @addexpr +| 26 = @subexpr +| 27 = @mulexpr +| 28 = @divexpr +| 29 = @remexpr +| 30 = @jmulexpr // C99 mul imaginary +| 31 = @jdivexpr // C99 div imaginary +| 32 = @fjaddexpr // C99 add real + imaginary +| 33 = @jfaddexpr // C99 add imaginary + real +| 34 = @fjsubexpr // C99 sub real - imaginary +| 35 = @jfsubexpr // C99 sub imaginary - real +| 36 = @paddexpr // pointer add (pointer + int or int + pointer) +| 37 = @psubexpr // pointer sub (pointer - integer) +| 38 = @pdiffexpr // difference between two pointers +| 39 = @lshiftexpr +| 40 = @rshiftexpr +| 41 = @andexpr +| 42 = @orexpr +| 43 = @xorexpr +| 44 = @eqexpr +| 45 = @neexpr +| 46 = @gtexpr +| 47 = @ltexpr +| 48 = @geexpr +| 49 = @leexpr +| 50 = @minexpr // GNU minimum +| 51 = @maxexpr // GNU maximum +| 52 = @assignexpr +| 53 = @assignaddexpr +| 54 = @assignsubexpr +| 55 = @assignmulexpr +| 56 = @assigndivexpr +| 57 = @assignremexpr +| 58 = @assignlshiftexpr +| 59 = @assignrshiftexpr +| 60 = @assignandexpr +| 61 = @assignorexpr +| 62 = @assignxorexpr +| 63 = @assignpaddexpr // assign pointer add +| 64 = @assignpsubexpr // assign pointer sub +| 65 = @andlogicalexpr +| 66 = @orlogicalexpr +| 67 = @commaexpr +| 68 = @subscriptexpr // access to member of an array, e.g., a[5] +// ... 69 @objc_subscriptexpr deprecated +// ... 70 @cmdaccess deprecated +// ... +| 73 = @virtfunptrexpr +| 74 = @callexpr +// ... 75 @msgexpr_normal deprecated +// ... 76 @msgexpr_super deprecated +// ... 77 @atselectorexpr deprecated +// ... 78 @atprotocolexpr deprecated +| 79 = @vastartexpr +| 80 = @vaargexpr +| 81 = @vaendexpr +| 82 = @vacopyexpr +// ... 83 @atencodeexpr deprecated +| 84 = @varaccess +| 85 = @thisaccess +// ... 86 @objc_box_expr deprecated +| 87 = @new_expr +| 88 = @delete_expr +| 89 = @throw_expr +| 90 = @condition_decl // a variable declared in a condition, e.g., if(int x = y > 2) +| 91 = @braced_init_list +| 92 = @type_id +| 93 = @runtime_sizeof +| 94 = @runtime_alignof +| 95 = @sizeof_pack +| 96 = @expr_stmt // GNU extension +| 97 = @routineexpr +| 98 = @type_operand // used to access a type in certain contexts (haven't found any examples yet....) +| 99 = @offsetofexpr // offsetof ::= type and field +| 100 = @hasassignexpr // __has_assign ::= type +| 101 = @hascopyexpr // __has_copy ::= type +| 102 = @hasnothrowassign // __has_nothrow_assign ::= type +| 103 = @hasnothrowconstr // __has_nothrow_constructor ::= type +| 104 = @hasnothrowcopy // __has_nothrow_copy ::= type +| 105 = @hastrivialassign // __has_trivial_assign ::= type +| 106 = @hastrivialconstr // __has_trivial_constructor ::= type +| 107 = @hastrivialcopy // __has_trivial_copy ::= type +| 108 = @hasuserdestr // __has_user_destructor ::= type +| 109 = @hasvirtualdestr // __has_virtual_destructor ::= type +| 110 = @isabstractexpr // __is_abstract ::= type +| 111 = @isbaseofexpr // __is_base_of ::= type type +| 112 = @isclassexpr // __is_class ::= type +| 113 = @isconvtoexpr // __is_convertible_to ::= type type +| 114 = @isemptyexpr // __is_empty ::= type +| 115 = @isenumexpr // __is_enum ::= type +| 116 = @ispodexpr // __is_pod ::= type +| 117 = @ispolyexpr // __is_polymorphic ::= type +| 118 = @isunionexpr // __is_union ::= type +| 119 = @typescompexpr // GNU __builtin_types_compatible ::= type type +| 120 = @intaddrexpr // frontend internal builtin, used to implement offsetof +// ... +| 122 = @hastrivialdestructor // __has_trivial_destructor ::= type +| 123 = @literal +| 124 = @uuidof +| 127 = @aggregateliteral +| 128 = @delete_array_expr +| 129 = @new_array_expr +// ... 130 @objc_array_literal deprecated +// ... 131 @objc_dictionary_literal deprecated +| 132 = @foldexpr +// ... +| 200 = @ctordirectinit +| 201 = @ctorvirtualinit +| 202 = @ctorfieldinit +| 203 = @ctordelegatinginit +| 204 = @dtordirectdestruct +| 205 = @dtorvirtualdestruct +| 206 = @dtorfielddestruct +// ... +| 210 = @static_cast +| 211 = @reinterpret_cast +| 212 = @const_cast +| 213 = @dynamic_cast +| 214 = @c_style_cast +| 215 = @lambdaexpr +| 216 = @param_ref +| 217 = @noopexpr +// ... +| 294 = @istriviallyconstructibleexpr +| 295 = @isdestructibleexpr +| 296 = @isnothrowdestructibleexpr +| 297 = @istriviallydestructibleexpr +| 298 = @istriviallyassignableexpr +| 299 = @isnothrowassignableexpr +| 300 = @istrivialexpr +| 301 = @isstandardlayoutexpr +| 302 = @istriviallycopyableexpr +| 303 = @isliteraltypeexpr +| 304 = @hastrivialmoveconstructorexpr +| 305 = @hastrivialmoveassignexpr +| 306 = @hasnothrowmoveassignexpr +| 307 = @isconstructibleexpr +| 308 = @isnothrowconstructibleexpr +| 309 = @hasfinalizerexpr +| 310 = @isdelegateexpr +| 311 = @isinterfaceclassexpr +| 312 = @isrefarrayexpr +| 313 = @isrefclassexpr +| 314 = @issealedexpr +| 315 = @issimplevalueclassexpr +| 316 = @isvalueclassexpr +| 317 = @isfinalexpr +| 319 = @noexceptexpr +| 320 = @builtinshufflevector +| 321 = @builtinchooseexpr +| 322 = @builtinaddressof +| 323 = @vec_fill +| 324 = @builtinconvertvector +| 325 = @builtincomplex +| 326 = @spaceshipexpr +| 327 = @co_await +| 328 = @co_yield +| 329 = @temp_init +| 330 = @isassignable +| 331 = @isaggregate +| 332 = @hasuniqueobjectrepresentations +| 333 = @builtinbitcast +| 334 = @builtinshuffle +| 335 = @blockassignexpr +| 336 = @issame +| 337 = @isfunction +| 338 = @islayoutcompatible +| 339 = @ispointerinterconvertiblebaseof +| 340 = @isarray +| 341 = @arrayrank +| 342 = @arrayextent +| 343 = @isarithmetic +| 344 = @iscompletetype +| 345 = @iscompound +| 346 = @isconst +| 347 = @isfloatingpoint +| 348 = @isfundamental +| 349 = @isintegral +| 350 = @islvaluereference +| 351 = @ismemberfunctionpointer +| 352 = @ismemberobjectpointer +| 353 = @ismemberpointer +| 354 = @isobject +| 355 = @ispointer +| 356 = @isreference +| 357 = @isrvaluereference +| 358 = @isscalar +| 359 = @issigned +| 360 = @isunsigned +| 361 = @isvoid +| 362 = @isvolatile +; + +@var_args_expr = @vastartexpr + | @vaendexpr + | @vaargexpr + | @vacopyexpr + ; + +@builtin_op = @var_args_expr + | @noopexpr + | @offsetofexpr + | @intaddrexpr + | @hasassignexpr + | @hascopyexpr + | @hasnothrowassign + | @hasnothrowconstr + | @hasnothrowcopy + | @hastrivialassign + | @hastrivialconstr + | @hastrivialcopy + | @hastrivialdestructor + | @hasuserdestr + | @hasvirtualdestr + | @isabstractexpr + | @isbaseofexpr + | @isclassexpr + | @isconvtoexpr + | @isemptyexpr + | @isenumexpr + | @ispodexpr + | @ispolyexpr + | @isunionexpr + | @typescompexpr + | @builtinshufflevector + | @builtinconvertvector + | @builtinaddressof + | @istriviallyconstructibleexpr + | @isdestructibleexpr + | @isnothrowdestructibleexpr + | @istriviallydestructibleexpr + | @istriviallyassignableexpr + | @isnothrowassignableexpr + | @istrivialexpr + | @isstandardlayoutexpr + | @istriviallycopyableexpr + | @isliteraltypeexpr + | @hastrivialmoveconstructorexpr + | @hastrivialmoveassignexpr + | @hasnothrowmoveassignexpr + | @isconstructibleexpr + | @isnothrowconstructibleexpr + | @hasfinalizerexpr + | @isdelegateexpr + | @isinterfaceclassexpr + | @isrefarrayexpr + | @isrefclassexpr + | @issealedexpr + | @issimplevalueclassexpr + | @isvalueclassexpr + | @isfinalexpr + | @builtinchooseexpr + | @builtincomplex + | @isassignable + | @isaggregate + | @hasuniqueobjectrepresentations + | @builtinbitcast + | @builtinshuffle + | @issame + | @isfunction + | @islayoutcompatible + | @ispointerinterconvertiblebaseof + | @isarray + | @arrayrank + | @arrayextent + | @isarithmetic + | @iscompletetype + | @iscompound + | @isconst + | @isfloatingpoint + | @isfundamental + | @isintegral + | @islvaluereference + | @ismemberfunctionpointer + | @ismemberobjectpointer + | @ismemberpointer + | @isobject + | @ispointer + | @isreference + | @isrvaluereference + | @isscalar + | @issigned + | @isunsigned + | @isvoid + | @isvolatile + ; + +new_allocated_type( + unique int expr: @new_expr ref, + int type_id: @type ref +); + +new_array_allocated_type( + unique int expr: @new_array_expr ref, + int type_id: @type ref +); + +/** + * The field being initialized by an initializer expression within an aggregate + * initializer for a class/struct/union. Position is used to sort repeated initializers. + */ +#keyset[aggregate, position] +aggregate_field_init( + int aggregate: @aggregateliteral ref, + int initializer: @expr ref, + int field: @membervariable ref, + int position: int ref +); + +/** + * The index of the element being initialized by an initializer expression + * within an aggregate initializer for an array. Position is used to sort repeated initializers. + */ +#keyset[aggregate, position] +aggregate_array_init( + int aggregate: @aggregateliteral ref, + int initializer: @expr ref, + int element_index: int ref, + int position: int ref +); + +@ctorinit = @ctordirectinit + | @ctorvirtualinit + | @ctorfieldinit + | @ctordelegatinginit; +@dtordestruct = @dtordirectdestruct + | @dtorvirtualdestruct + | @dtorfielddestruct; + + +condition_decl_bind( + unique int expr: @condition_decl ref, + unique int decl: @declaration ref +); + +typeid_bind( + unique int expr: @type_id ref, + int type_id: @type ref +); + +uuidof_bind( + unique int expr: @uuidof ref, + int type_id: @type ref +); + +@runtime_sizeof_or_alignof = @runtime_sizeof | @runtime_alignof; + +sizeof_bind( + unique int expr: @runtime_sizeof_or_alignof ref, + int type_id: @type ref +); + +code_block( + unique int block: @literal ref, + unique int routine: @function ref +); + +lambdas( + unique int expr: @lambdaexpr ref, + string default_capture: string ref, + boolean has_explicit_return_type: boolean ref +); + +lambda_capture( + unique int id: @lambdacapture, + int lambda: @lambdaexpr ref, + int index: int ref, + int field: @membervariable ref, + boolean captured_by_reference: boolean ref, + boolean is_implicit: boolean ref, + int location: @location_default ref +); + +@funbindexpr = @routineexpr + | @new_expr + | @delete_expr + | @delete_array_expr + | @ctordirectinit + | @ctorvirtualinit + | @ctordelegatinginit + | @dtordirectdestruct + | @dtorvirtualdestruct; + +@varbindexpr = @varaccess | @ctorfieldinit | @dtorfielddestruct; +@addressable = @function | @variable ; +@accessible = @addressable | @enumconstant ; + +@access = @varaccess | @routineexpr ; + +fold( + int expr: @foldexpr ref, + string operator: string ref, + boolean is_left_fold: boolean ref +); + +stmts( + unique int id: @stmt, + int kind: int ref, + int location: @location_stmt ref +); + +case @stmt.kind of + 1 = @stmt_expr +| 2 = @stmt_if +| 3 = @stmt_while +| 4 = @stmt_goto +| 5 = @stmt_label +| 6 = @stmt_return +| 7 = @stmt_block +| 8 = @stmt_end_test_while // do { ... } while ( ... ) +| 9 = @stmt_for +| 10 = @stmt_switch_case +| 11 = @stmt_switch +| 13 = @stmt_asm // "asm" statement or the body of an asm function +| 15 = @stmt_try_block +| 16 = @stmt_microsoft_try // Microsoft +| 17 = @stmt_decl +| 18 = @stmt_set_vla_size // C99 +| 19 = @stmt_vla_decl // C99 +| 25 = @stmt_assigned_goto // GNU +| 26 = @stmt_empty +| 27 = @stmt_continue +| 28 = @stmt_break +| 29 = @stmt_range_based_for // C++11 +// ... 30 @stmt_at_autoreleasepool_block deprecated +// ... 31 @stmt_objc_for_in deprecated +// ... 32 @stmt_at_synchronized deprecated +| 33 = @stmt_handler +// ... 34 @stmt_finally_end deprecated +| 35 = @stmt_constexpr_if +| 37 = @stmt_co_return +; + +type_vla( + int type_id: @type ref, + int decl: @stmt_vla_decl ref +); + +variable_vla( + int var: @variable ref, + int decl: @stmt_vla_decl ref +); + +if_initialization( + unique int if_stmt: @stmt_if ref, + int init_id: @stmt ref +); + +if_then( + unique int if_stmt: @stmt_if ref, + int then_id: @stmt ref +); + +if_else( + unique int if_stmt: @stmt_if ref, + int else_id: @stmt ref +); + +constexpr_if_initialization( + unique int constexpr_if_stmt: @stmt_constexpr_if ref, + int init_id: @stmt ref +); + +constexpr_if_then( + unique int constexpr_if_stmt: @stmt_constexpr_if ref, + int then_id: @stmt ref +); + +constexpr_if_else( + unique int constexpr_if_stmt: @stmt_constexpr_if ref, + int else_id: @stmt ref +); + +while_body( + unique int while_stmt: @stmt_while ref, + int body_id: @stmt ref +); + +do_body( + unique int do_stmt: @stmt_end_test_while ref, + int body_id: @stmt ref +); + +switch_initialization( + unique int switch_stmt: @stmt_switch ref, + int init_id: @stmt ref +); + +#keyset[switch_stmt, index] +switch_case( + int switch_stmt: @stmt_switch ref, + int index: int ref, + int case_id: @stmt_switch_case ref +); + +switch_body( + unique int switch_stmt: @stmt_switch ref, + int body_id: @stmt ref +); + +for_initialization( + unique int for_stmt: @stmt_for ref, + int init_id: @stmt ref +); + +for_condition( + unique int for_stmt: @stmt_for ref, + int condition_id: @expr ref +); + +for_update( + unique int for_stmt: @stmt_for ref, + int update_id: @expr ref +); + +for_body( + unique int for_stmt: @stmt_for ref, + int body_id: @stmt ref +); + +@stmtparent = @stmt | @expr_stmt ; +stmtparents( + unique int id: @stmt ref, + int index: int ref, + int parent: @stmtparent ref +); + +ishandler(unique int block: @stmt_block ref); + +@cfgnode = @stmt | @expr | @function | @initialiser ; + +stmt_decl_bind( + int stmt: @stmt_decl ref, + int num: int ref, + int decl: @declaration ref +); + +stmt_decl_entry_bind( + int stmt: @stmt_decl ref, + int num: int ref, + int decl_entry: @element ref +); + +@functionorblock = @function | @stmt_block; + +blockscope( + unique int block: @stmt_block ref, + int enclosing: @functionorblock ref +); + +@jump = @stmt_goto | @stmt_break | @stmt_continue; + +@jumporlabel = @jump | @stmt_label | @literal; + +jumpinfo( + unique int id: @jumporlabel ref, + string str: string ref, + int target: @stmt ref +); + +preprocdirects( + unique int id: @preprocdirect, + int kind: int ref, + int location: @location_default ref +); +case @preprocdirect.kind of + 0 = @ppd_if +| 1 = @ppd_ifdef +| 2 = @ppd_ifndef +| 3 = @ppd_elif +| 4 = @ppd_else +| 5 = @ppd_endif +| 6 = @ppd_plain_include +| 7 = @ppd_define +| 8 = @ppd_undef +| 9 = @ppd_line +| 10 = @ppd_error +| 11 = @ppd_pragma +| 12 = @ppd_objc_import +| 13 = @ppd_include_next +| 18 = @ppd_warning +; + +@ppd_include = @ppd_plain_include | @ppd_objc_import | @ppd_include_next; + +@ppd_branch = @ppd_if | @ppd_ifdef | @ppd_ifndef | @ppd_elif; + +preprocpair( + int begin : @ppd_branch ref, + int elseelifend : @preprocdirect ref +); + +preproctrue(int branch : @ppd_branch ref); +preprocfalse(int branch : @ppd_branch ref); + +preproctext( + unique int id: @preprocdirect ref, + string head: string ref, + string body: string ref +); + +includes( + unique int id: @ppd_include ref, + int included: @file ref +); + +link_targets( + unique int id: @link_target, + int binary: @file ref +); + +link_parent( + int element : @element ref, + int link_target : @link_target ref +); + +/* XML Files */ + +xmlEncoding(unique int id: @file ref, string encoding: string ref); + +xmlDTDs( + unique int id: @xmldtd, + string root: string ref, + string publicId: string ref, + string systemId: string ref, + int fileid: @file ref +); + +xmlElements( + unique int id: @xmlelement, + string name: string ref, + int parentid: @xmlparent ref, + int idx: int ref, + int fileid: @file ref +); + +xmlAttrs( + unique int id: @xmlattribute, + int elementid: @xmlelement ref, + string name: string ref, + string value: string ref, + int idx: int ref, + int fileid: @file ref +); + +xmlNs( + int id: @xmlnamespace, + string prefixName: string ref, + string 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, + string text: string ref, + int parentid: @xmlparent ref, + int fileid: @file ref +); + +xmlChars( + unique int id: @xmlcharacters, + string 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; diff --git a/cpp/downgrades/f79ce79e3b751aeeed59e594633ba5c07a27ef3e/semmlecode.cpp.dbscheme b/cpp/downgrades/f79ce79e3b751aeeed59e594633ba5c07a27ef3e/semmlecode.cpp.dbscheme new file mode 100644 index 000000000000..5b388693c66d --- /dev/null +++ b/cpp/downgrades/f79ce79e3b751aeeed59e594633ba5c07a27ef3e/semmlecode.cpp.dbscheme @@ -0,0 +1,2221 @@ + +/** + * An invocation of the compiler. Note that more than one file may be + * compiled per invocation. For example, this command compiles three + * source files: + * + * gcc -c f1.c f2.c f3.c + * + * The `id` simply identifies the invocation, while `cwd` is the working + * directory from which the compiler was invoked. + */ +compilations( + /** + * An invocation of the compiler. Note that more than one file may + * be compiled per invocation. For example, this command compiles + * three source files: + * + * gcc -c f1.c f2.c f3.c + */ + unique int id : @compilation, + string cwd : string ref +); + +/** + * The arguments that were passed to the extractor for a compiler + * invocation. If `id` is for the compiler invocation + * + * gcc -c f1.c f2.c f3.c + * + * then typically there will be rows for + * + * num | arg + * --- | --- + * 0 | *path to extractor* + * 1 | `--mimic` + * 2 | `/usr/bin/gcc` + * 3 | `-c` + * 4 | f1.c + * 5 | f2.c + * 6 | f3.c + */ +#keyset[id, num] +compilation_args( + int id : @compilation ref, + int num : int ref, + string arg : string ref +); + +/** + * The source files that are compiled by a compiler invocation. + * If `id` is for the compiler invocation + * + * gcc -c f1.c f2.c f3.c + * + * then there will be rows for + * + * num | arg + * --- | --- + * 0 | f1.c + * 1 | f2.c + * 2 | f3.c + * + * Note that even if those files `#include` headers, those headers + * do not appear as rows. + */ +#keyset[id, num] +compilation_compiling_files( + int id : @compilation ref, + int num : int ref, + int file : @file ref +); + +/** + * The time taken by the extractor for a compiler invocation. + * + * For each file `num`, there will be rows for + * + * kind | seconds + * ---- | --- + * 1 | CPU seconds used by the extractor frontend + * 2 | Elapsed seconds during the extractor frontend + * 3 | CPU seconds used by the extractor backend + * 4 | Elapsed seconds during the extractor backend + */ +#keyset[id, num, kind] +compilation_time( + int id : @compilation ref, + int num : int ref, + /* kind: + 1 = frontend_cpu_seconds + 2 = frontend_elapsed_seconds + 3 = extractor_cpu_seconds + 4 = extractor_elapsed_seconds + */ + int kind : int ref, + float seconds : float ref +); + +/** + * An error or warning generated by the extractor. + * The diagnostic message `diagnostic` was generated during compiler + * invocation `compilation`, and is the `file_number_diagnostic_number`th + * message generated while extracting the `file_number`th file of that + * invocation. + */ +#keyset[compilation, file_number, file_number_diagnostic_number] +diagnostic_for( + int diagnostic : @diagnostic ref, + int compilation : @compilation ref, + int file_number : int ref, + int file_number_diagnostic_number : int ref +); + +/** + * If extraction was successful, then `cpu_seconds` and + * `elapsed_seconds` are the CPU time and elapsed time (respectively) + * that extraction took for compiler invocation `id`. + */ +compilation_finished( + unique int id : @compilation ref, + float cpu_seconds : float ref, + float elapsed_seconds : float ref +); + + +/** + * External data, loaded from CSV files during snapshot creation. See + * [Tutorial: Incorporating external data](https://help.semmle.com/wiki/display/SD/Tutorial%3A+Incorporating+external+data) + * for more information. + */ +externalData( + int id : @externalDataElement, + string path : string ref, + int column: int ref, + string value : string ref +); + +/** + * The source location of the snapshot. + */ +sourceLocationPrefix(string prefix : string ref); + +/** + * Information about packages that provide code used during compilation. + * The `id` is just a unique identifier. + * The `namespace` is typically the name of the package manager that + * provided the package (e.g. "dpkg" or "yum"). + * The `package_name` is the name of the package, and `version` is its + * version (as a string). + */ +external_packages( + unique int id: @external_package, + string namespace : string ref, + string package_name : string ref, + string version : string ref +); + +/** + * Holds if File `fileid` was provided by package `package`. + */ +header_to_external_package( + int fileid : @file ref, + int package : @external_package ref +); + +/* + * Version history + */ + +svnentries( + unique int id : @svnentry, + string revision : string ref, + string author : string ref, + date revisionDate : date ref, + int changeSize : int ref +) + +svnaffectedfiles( + int id : @svnentry ref, + int file : @file ref, + string action : string ref +) + +svnentrymsg( + unique int id : @svnentry ref, + string message : string ref +) + +svnchurn( + int commit : @svnentry ref, + int file : @file ref, + int addedLines : int ref, + int deletedLines : int ref +) + +/* + * C++ dbscheme + */ + +@location = @location_stmt | @location_expr | @location_default ; + +/** + * The location of an element that is not an expression or a statement. + * The location spans column `startcolumn` of line `startline` to + * column `endcolumn` of line `endline` in file `file`. + * For more information, see + * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). + */ +locations_default( + /** The location of an element that is not an expression or a statement. */ + unique int id: @location_default, + int container: @container ref, + int startLine: int ref, + int startColumn: int ref, + int endLine: int ref, + int endColumn: int ref +); + +/** + * The location of a statement. + * The location spans column `startcolumn` of line `startline` to + * column `endcolumn` of line `endline` in file `file`. + * For more information, see + * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). + */ +locations_stmt( + /** The location of a statement. */ + unique int id: @location_stmt, + int container: @container ref, + int startLine: int ref, + int startColumn: int ref, + int endLine: int ref, + int endColumn: int ref +); + +/** + * The location of an expression. + * The location spans column `startcolumn` of line `startline` to + * column `endcolumn` of line `endline` in file `file`. + * For more information, see + * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). + */ +locations_expr( + /** The location of an expression. */ + unique int id: @location_expr, + int container: @container ref, + int startLine: int ref, + int startColumn: int ref, + int endLine: int ref, + int endColumn: int ref +); + +/** An element for which line-count information is available. */ +@sourceline = @file | @function | @variable | @enumconstant | @xmllocatable; + +numlines( + int element_id: @sourceline ref, + int num_lines: int ref, + int num_code: int ref, + int num_comment: int ref +); + +diagnostics( + unique int id: @diagnostic, + int severity: int ref, + string error_tag: string ref, + string error_message: string ref, + string full_error_message: string ref, + int location: @location_default ref +); + +files( + unique int id: @file, + string name: string ref +); + +folders( + unique int id: @folder, + string name: string ref +); + +@container = @folder | @file + +containerparent( + int parent: @container ref, + unique int child: @container ref +); + +fileannotations( + int id: @file ref, + int kind: int ref, + string name: string ref, + string value: string ref +); + +inmacroexpansion( + int id: @element ref, + int inv: @macroinvocation ref +); + +affectedbymacroexpansion( + int id: @element ref, + int inv: @macroinvocation ref +); + +case @macroinvocation.kind of + 1 = @macro_expansion +| 2 = @other_macro_reference +; + +macroinvocations( + unique int id: @macroinvocation, + int macro_id: @ppd_define ref, + int location: @location_default ref, + int kind: int ref +); + +macroparent( + unique int id: @macroinvocation ref, + int parent_id: @macroinvocation ref +); + +// a macroinvocation may be part of another location +// the way to find a constant expression that uses a macro +// is thus to find a constant expression that has a location +// to which a macro invocation is bound +macrolocationbind( + int id: @macroinvocation ref, + int location: @location ref +); + +#keyset[invocation, argument_index] +macro_argument_unexpanded( + int invocation: @macroinvocation ref, + int argument_index: int ref, + string text: string ref +); + +#keyset[invocation, argument_index] +macro_argument_expanded( + int invocation: @macroinvocation ref, + int argument_index: int ref, + string text: string ref +); + +/* +case @function.kind of + 1 = @normal_function +| 2 = @constructor +| 3 = @destructor +| 4 = @conversion_function +| 5 = @operator +| 6 = @builtin_function // GCC built-in functions, e.g. __builtin___memcpy_chk +; +*/ + +functions( + unique int id: @function, + string name: string ref, + int kind: int ref +); + +function_entry_point( + int id: @function ref, + unique int entry_point: @stmt ref +); + +function_return_type( + int id: @function ref, + int return_type: @type ref +); + +/** + * If `function` is a coroutine, then this gives the `std::experimental::resumable_traits` + * instance associated with it, and the variables representing the `handle` and `promise` + * for it. + */ +coroutine( + unique int function: @function ref, + int traits: @type ref, + int handle: @variable ref, + int promise: @variable ref +); + +/** The `new` function used for allocating the coroutine state, if any. */ +coroutine_new( + unique int function: @function ref, + int new: @function ref +); + +/** The `delete` function used for deallocating the coroutine state, if any. */ +coroutine_delete( + unique int function: @function ref, + int delete: @function ref +); + +purefunctions(unique int id: @function ref); + +function_deleted(unique int id: @function ref); + +function_defaulted(unique int id: @function ref); + +member_function_this_type( + unique int id: @function ref, + int this_type: @type ref +); + +#keyset[id, type_id] +fun_decls( + int id: @fun_decl, + int function: @function ref, + int type_id: @type ref, + string name: string ref, + int location: @location_default ref +); +fun_def(unique int id: @fun_decl ref); +fun_specialized(unique int id: @fun_decl ref); +fun_implicit(unique int id: @fun_decl ref); +fun_decl_specifiers( + int id: @fun_decl ref, + string name: string ref +) +#keyset[fun_decl, index] +fun_decl_throws( + int fun_decl: @fun_decl ref, + int index: int ref, + int type_id: @type ref +); +/* an empty throw specification is different from none */ +fun_decl_empty_throws(unique int fun_decl: @fun_decl ref); +fun_decl_noexcept( + int fun_decl: @fun_decl ref, + int constant: @expr ref +); +fun_decl_empty_noexcept(int fun_decl: @fun_decl ref); +fun_decl_typedef_type( + unique int fun_decl: @fun_decl ref, + int typedeftype_id: @usertype ref +); + +param_decl_bind( + unique int id: @var_decl ref, + int index: int ref, + int fun_decl: @fun_decl ref +); + +#keyset[id, type_id] +var_decls( + int id: @var_decl, + int variable: @variable ref, + int type_id: @type ref, + string name: string ref, + int location: @location_default ref +); +var_def(unique int id: @var_decl ref); +var_decl_specifiers( + int id: @var_decl ref, + string name: string ref +) +is_structured_binding(unique int id: @variable ref); + +type_decls( + unique int id: @type_decl, + int type_id: @type ref, + int location: @location_default ref +); +type_def(unique int id: @type_decl ref); +type_decl_top( + unique int type_decl: @type_decl ref +); + +namespace_decls( + unique int id: @namespace_decl, + int namespace_id: @namespace ref, + int location: @location_default ref, + int bodylocation: @location_default ref +); + +usings( + unique int id: @using, + int element_id: @element ref, + int location: @location_default ref +); + +/** The element which contains the `using` declaration. */ +using_container( + int parent: @element ref, + int child: @using ref +); + +static_asserts( + unique int id: @static_assert, + int condition : @expr ref, + string message : string ref, + int location: @location_default ref, + int enclosing : @element ref +); + +// each function has an ordered list of parameters +#keyset[id, type_id] +#keyset[function, index, type_id] +params( + int id: @parameter, + int function: @functionorblock ref, + int index: int ref, + int type_id: @type ref +); + +overrides( + int new: @function ref, + int old: @function ref +); + +#keyset[id, type_id] +membervariables( + int id: @membervariable, + int type_id: @type ref, + string name: string ref +); + +#keyset[id, type_id] +globalvariables( + int id: @globalvariable, + int type_id: @type ref, + string name: string ref +); + +#keyset[id, type_id] +localvariables( + int id: @localvariable, + int type_id: @type ref, + string name: string ref +); + +autoderivation( + unique int var: @variable ref, + int derivation_type: @type ref +); + +orphaned_variables( + int var: @localvariable ref, + int function: @function ref +) + +enumconstants( + unique int id: @enumconstant, + int parent: @usertype ref, + int index: int ref, + int type_id: @type ref, + string name: string ref, + int location: @location_default ref +); + +@variable = @localscopevariable | @globalvariable | @membervariable; + +@localscopevariable = @localvariable | @parameter; + +/** + * Built-in types are the fundamental types, e.g., integral, floating, and void. + */ +case @builtintype.kind of + 1 = @errortype +| 2 = @unknowntype +| 3 = @void +| 4 = @boolean +| 5 = @char +| 6 = @unsigned_char +| 7 = @signed_char +| 8 = @short +| 9 = @unsigned_short +| 10 = @signed_short +| 11 = @int +| 12 = @unsigned_int +| 13 = @signed_int +| 14 = @long +| 15 = @unsigned_long +| 16 = @signed_long +| 17 = @long_long +| 18 = @unsigned_long_long +| 19 = @signed_long_long +// ... 20 Microsoft-specific __int8 +// ... 21 Microsoft-specific __int16 +// ... 22 Microsoft-specific __int32 +// ... 23 Microsoft-specific __int64 +| 24 = @float +| 25 = @double +| 26 = @long_double +| 27 = @complex_float // C99-specific _Complex float +| 28 = @complex_double // C99-specific _Complex double +| 29 = @complex_long_double // C99-specific _Complex long double +| 30 = @imaginary_float // C99-specific _Imaginary float +| 31 = @imaginary_double // C99-specific _Imaginary double +| 32 = @imaginary_long_double // C99-specific _Imaginary long double +| 33 = @wchar_t // Microsoft-specific +| 34 = @decltype_nullptr // C++11 +| 35 = @int128 // __int128 +| 36 = @unsigned_int128 // unsigned __int128 +| 37 = @signed_int128 // signed __int128 +| 38 = @float128 // __float128 +| 39 = @complex_float128 // _Complex __float128 +| 40 = @decimal32 // _Decimal32 +| 41 = @decimal64 // _Decimal64 +| 42 = @decimal128 // _Decimal128 +| 43 = @char16_t +| 44 = @char32_t +| 45 = @std_float32 // _Float32 +| 46 = @float32x // _Float32x +| 47 = @std_float64 // _Float64 +| 48 = @float64x // _Float64x +| 49 = @std_float128 // _Float128 +// ... 50 _Float128x +| 51 = @char8_t +| 52 = @float16 // _Float16 +| 53 = @complex_float16 // _Complex _Float16 +| 54 = @fp16 // __fp16 +| 55 = @std_bfloat16 // __bf16 +| 56 = @std_float16 // std::float16_t +| 57 = @complex_std_float32 // _Complex _Float32 +| 58 = @complex_float32x // _Complex _Float32x +| 59 = @complex_std_float64 // _Complex _Float64 +| 60 = @complex_float64x // _Complex _Float64x +| 61 = @complex_std_float128 // _Complex _Float128 +; + +builtintypes( + unique int id: @builtintype, + string name: string ref, + int kind: int ref, + int size: int ref, + int sign: int ref, + int alignment: int ref +); + +/** + * Derived types are types that are directly derived from existing types and + * point to, refer to, transform type data to return a new type. + */ +case @derivedtype.kind of + 1 = @pointer +| 2 = @reference +| 3 = @type_with_specifiers +| 4 = @array +| 5 = @gnu_vector +| 6 = @routineptr +| 7 = @routinereference +| 8 = @rvalue_reference // C++11 +// ... 9 type_conforming_to_protocols deprecated +| 10 = @block +; + +derivedtypes( + unique int id: @derivedtype, + string name: string ref, + int kind: int ref, + int type_id: @type ref +); + +pointerishsize(unique int id: @derivedtype ref, + int size: int ref, + int alignment: int ref); + +arraysizes( + unique int id: @derivedtype ref, + int num_elements: int ref, + int bytesize: int ref, + int alignment: int ref +); + +typedefbase( + unique int id: @usertype ref, + int type_id: @type ref +); + +/** + * An instance of the C++11 `decltype` operator. For example: + * ``` + * int a; + * decltype(1+a) b; + * ``` + * Here `expr` is `1+a`. + * + * Sometimes an additional pair of parentheses around the expression + * would change the semantics of this decltype, e.g. + * ``` + * struct A { double x; }; + * const A* a = new A(); + * decltype( a->x ); // type is double + * decltype((a->x)); // type is const double& + * ``` + * (Please consult the C++11 standard for more details). + * `parentheses_would_change_meaning` is `true` iff that is the case. + */ +#keyset[id, expr] +decltypes( + int id: @decltype, + int expr: @expr ref, + int base_type: @type ref, + boolean parentheses_would_change_meaning: boolean ref +); + +/* +case @usertype.kind of + 1 = @struct +| 2 = @class +| 3 = @union +| 4 = @enum +| 5 = @typedef // classic C: typedef typedef type name +| 6 = @template +| 7 = @template_parameter +| 8 = @template_template_parameter +| 9 = @proxy_class // a proxy class associated with a template parameter +// ... 10 objc_class deprecated +// ... 11 objc_protocol deprecated +// ... 12 objc_category deprecated +| 13 = @scoped_enum +| 14 = @using_alias // a using name = type style typedef +; +*/ + +usertypes( + unique int id: @usertype, + string name: string ref, + int kind: int ref +); + +usertypesize( + unique int id: @usertype ref, + int size: int ref, + int alignment: int ref +); + +usertype_final(unique int id: @usertype ref); + +usertype_uuid( + unique int id: @usertype ref, + string uuid: string ref +); + +mangled_name( + unique int id: @declaration ref, + int mangled_name : @mangledname +); + +is_pod_class(unique int id: @usertype ref); +is_standard_layout_class(unique int id: @usertype ref); + +is_complete(unique int id: @usertype ref); + +is_class_template(unique int id: @usertype ref); +class_instantiation( + int to: @usertype ref, + int from: @usertype ref +); +class_template_argument( + int type_id: @usertype ref, + int index: int ref, + int arg_type: @type ref +); +class_template_argument_value( + int type_id: @usertype ref, + int index: int ref, + int arg_value: @expr ref +); + +is_proxy_class_for( + unique int id: @usertype ref, + unique int templ_param_id: @usertype ref +); + +type_mentions( + unique int id: @type_mention, + int type_id: @type ref, + int location: @location ref, + // a_symbol_reference_kind from the frontend. + int kind: int ref +); + +is_function_template(unique int id: @function ref); +function_instantiation( + unique int to: @function ref, + int from: @function ref +); +function_template_argument( + int function_id: @function ref, + int index: int ref, + int arg_type: @type ref +); +function_template_argument_value( + int function_id: @function ref, + int index: int ref, + int arg_value: @expr ref +); + +is_variable_template(unique int id: @variable ref); +variable_instantiation( + unique int to: @variable ref, + int from: @variable ref +); +variable_template_argument( + int variable_id: @variable ref, + int index: int ref, + int arg_type: @type ref +); +variable_template_argument_value( + int variable_id: @variable ref, + int index: int ref, + int arg_value: @expr ref +); + +/* + Fixed point types + precision(1) = short, precision(2) = default, precision(3) = long + is_unsigned(1) = unsigned is_unsigned(2) = signed + is_fract_type(1) = declared with _Fract + saturating(1) = declared with _Sat +*/ +/* TODO +fixedpointtypes( + unique int id: @fixedpointtype, + int precision: int ref, + int is_unsigned: int ref, + int is_fract_type: int ref, + int saturating: int ref); +*/ + +routinetypes( + unique int id: @routinetype, + int return_type: @type ref +); + +routinetypeargs( + int routine: @routinetype ref, + int index: int ref, + int type_id: @type ref +); + +ptrtomembers( + unique int id: @ptrtomember, + int type_id: @type ref, + int class_id: @type ref +); + +/* + specifiers for types, functions, and variables + + "public", + "protected", + "private", + + "const", + "volatile", + "static", + + "pure", + "virtual", + "sealed", // Microsoft + "__interface", // Microsoft + "inline", + "explicit", + + "near", // near far extension + "far", // near far extension + "__ptr32", // Microsoft + "__ptr64", // Microsoft + "__sptr", // Microsoft + "__uptr", // Microsoft + "dllimport", // Microsoft + "dllexport", // Microsoft + "thread", // Microsoft + "naked", // Microsoft + "microsoft_inline", // Microsoft + "forceinline", // Microsoft + "selectany", // Microsoft + "nothrow", // Microsoft + "novtable", // Microsoft + "noreturn", // Microsoft + "noinline", // Microsoft + "noalias", // Microsoft + "restrict", // Microsoft +*/ + +specifiers( + unique int id: @specifier, + unique string str: string ref +); + +typespecifiers( + int type_id: @type ref, + int spec_id: @specifier ref +); + +funspecifiers( + int func_id: @function ref, + int spec_id: @specifier ref +); + +varspecifiers( + int var_id: @accessible ref, + int spec_id: @specifier ref +); + +attributes( + unique int id: @attribute, + int kind: int ref, + string name: string ref, + string name_space: string ref, + int location: @location_default ref +); + +case @attribute.kind of + 0 = @gnuattribute +| 1 = @stdattribute +| 2 = @declspec +| 3 = @msattribute +| 4 = @alignas +// ... 5 @objc_propertyattribute deprecated +; + +attribute_args( + unique int id: @attribute_arg, + int kind: int ref, + int attribute: @attribute ref, + int index: int ref, + int location: @location_default ref +); + +case @attribute_arg.kind of + 0 = @attribute_arg_empty +| 1 = @attribute_arg_token +| 2 = @attribute_arg_constant +| 3 = @attribute_arg_type +| 4 = @attribute_arg_constant_expr +; + +attribute_arg_value( + unique int arg: @attribute_arg ref, + string value: string ref +); +attribute_arg_type( + unique int arg: @attribute_arg ref, + int type_id: @type ref +); +attribute_arg_constant( + unique int arg: @attribute_arg ref, + int constant: @expr ref +) +attribute_arg_name( + unique int arg: @attribute_arg ref, + string name: string ref +); + +typeattributes( + int type_id: @type ref, + int spec_id: @attribute ref +); + +funcattributes( + int func_id: @function ref, + int spec_id: @attribute ref +); + +varattributes( + int var_id: @accessible ref, + int spec_id: @attribute ref +); + +stmtattributes( + int stmt_id: @stmt ref, + int spec_id: @attribute ref +); + +@type = @builtintype + | @derivedtype + | @usertype + /* TODO | @fixedpointtype */ + | @routinetype + | @ptrtomember + | @decltype; + +unspecifiedtype( + unique int type_id: @type ref, + int unspecified_type_id: @type ref +); + +member( + int parent: @type ref, + int index: int ref, + int child: @member ref +); + +@enclosingfunction_child = @usertype | @variable | @namespace + +enclosingfunction( + unique int child: @enclosingfunction_child ref, + int parent: @function ref +); + +derivations( + unique int derivation: @derivation, + int sub: @type ref, + int index: int ref, + int super: @type ref, + int location: @location_default ref +); + +derspecifiers( + int der_id: @derivation ref, + int spec_id: @specifier ref +); + +/** + * Contains the byte offset of the base class subobject within the derived + * class. Only holds for non-virtual base classes, but see table + * `virtual_base_offsets` for offsets of virtual base class subobjects. + */ +direct_base_offsets( + unique int der_id: @derivation ref, + int offset: int ref +); + +/** + * Contains the byte offset of the virtual base class subobject for class + * `super` within a most-derived object of class `sub`. `super` can be either a + * direct or indirect base class. + */ +#keyset[sub, super] +virtual_base_offsets( + int sub: @usertype ref, + int super: @usertype ref, + int offset: int ref +); + +frienddecls( + unique int id: @frienddecl, + int type_id: @type ref, + int decl_id: @declaration ref, + int location: @location_default ref +); + +@declaredtype = @usertype ; + +@declaration = @function + | @declaredtype + | @variable + | @enumconstant + | @frienddecl; + +@member = @membervariable + | @function + | @declaredtype + | @enumconstant; + +@locatable = @diagnostic + | @declaration + | @ppd_include + | @ppd_define + | @macroinvocation + /*| @funcall*/ + | @xmllocatable + | @attribute + | @attribute_arg; + +@namedscope = @namespace | @usertype; + +@element = @locatable + | @file + | @folder + | @specifier + | @type + | @expr + | @namespace + | @initialiser + | @stmt + | @derivation + | @comment + | @preprocdirect + | @fun_decl + | @var_decl + | @type_decl + | @namespace_decl + | @using + | @namequalifier + | @specialnamequalifyingelement + | @static_assert + | @type_mention + | @lambdacapture; + +@exprparent = @element; + +comments( + unique int id: @comment, + string contents: string ref, + int location: @location_default ref +); + +commentbinding( + int id: @comment ref, + int element: @element ref +); + +exprconv( + int converted: @expr ref, + unique int conversion: @expr ref +); + +compgenerated(unique int id: @element ref); + +/** + * `destructor_call` destructs the `i`'th entity that should be + * destructed following `element`. Note that entities should be + * destructed in reverse construction order, so for a given `element` + * these should be called from highest to lowest `i`. + */ +#keyset[element, destructor_call] +#keyset[element, i] +synthetic_destructor_call( + int element: @element ref, + int i: int ref, + int destructor_call: @routineexpr ref +); + +namespaces( + unique int id: @namespace, + string name: string ref +); + +namespace_inline( + unique int id: @namespace ref +); + +namespacembrs( + int parentid: @namespace ref, + unique int memberid: @namespacembr ref +); + +@namespacembr = @declaration | @namespace; + +exprparents( + int expr_id: @expr ref, + int child_index: int ref, + int parent_id: @exprparent ref +); + +expr_isload(unique int expr_id: @expr ref); + +@cast = @c_style_cast + | @const_cast + | @dynamic_cast + | @reinterpret_cast + | @static_cast + ; + +/* +case @conversion.kind of + 0 = @simple_conversion // a numeric conversion, qualification conversion, or a reinterpret_cast +| 1 = @bool_conversion // conversion to 'bool' +| 2 = @base_class_conversion // a derived-to-base conversion +| 3 = @derived_class_conversion // a base-to-derived conversion +| 4 = @pm_base_class_conversion // a derived-to-base conversion of a pointer to member +| 5 = @pm_derived_class_conversion // a base-to-derived conversion of a pointer to member +| 6 = @glvalue_adjust // an adjustment of the type of a glvalue +| 7 = @prvalue_adjust // an adjustment of the type of a prvalue +; +*/ +/** + * Describes the semantics represented by a cast expression. This is largely + * independent of the source syntax of the cast, so it is separate from the + * regular expression kind. + */ +conversionkinds( + unique int expr_id: @cast ref, + int kind: int ref +); + +@conversion = @cast + | @array_to_pointer + | @parexpr + | @reference_to + | @ref_indirect + | @temp_init + ; + +/* +case @funbindexpr.kind of + 0 = @normal_call // a normal call +| 1 = @virtual_call // a virtual call +| 2 = @adl_call // a call whose target is only found by ADL +; +*/ +iscall( + unique int caller: @funbindexpr ref, + int kind: int ref +); + +numtemplatearguments( + unique int expr_id: @expr ref, + int num: int ref +); + +specialnamequalifyingelements( + unique int id: @specialnamequalifyingelement, + unique string name: string ref +); + +@namequalifiableelement = @expr | @namequalifier; +@namequalifyingelement = @namespace + | @specialnamequalifyingelement + | @usertype; + +namequalifiers( + unique int id: @namequalifier, + unique int qualifiableelement: @namequalifiableelement ref, + int qualifyingelement: @namequalifyingelement ref, + int location: @location_default ref +); + +varbind( + int expr: @varbindexpr ref, + int var: @accessible ref +); + +funbind( + int expr: @funbindexpr ref, + int fun: @function ref +); + +@any_new_expr = @new_expr + | @new_array_expr; + +@new_or_delete_expr = @any_new_expr + | @delete_expr + | @delete_array_expr; + +@prefix_crement_expr = @preincrexpr | @predecrexpr; + +@postfix_crement_expr = @postincrexpr | @postdecrexpr; + +@increment_expr = @preincrexpr | @postincrexpr; + +@decrement_expr = @predecrexpr | @postdecrexpr; + +@crement_expr = @increment_expr | @decrement_expr; + +@un_arith_op_expr = @arithnegexpr + | @unaryplusexpr + | @conjugation + | @realpartexpr + | @imagpartexpr + | @crement_expr + ; + +@un_bitwise_op_expr = @complementexpr; + +@un_log_op_expr = @notexpr; + +@un_op_expr = @address_of + | @indirect + | @un_arith_op_expr + | @un_bitwise_op_expr + | @builtinaddressof + | @vec_fill + | @un_log_op_expr + | @co_await + | @co_yield + ; + +@bin_log_op_expr = @andlogicalexpr | @orlogicalexpr; + +@cmp_op_expr = @eq_op_expr | @rel_op_expr; + +@eq_op_expr = @eqexpr | @neexpr; + +@rel_op_expr = @gtexpr + | @ltexpr + | @geexpr + | @leexpr + | @spaceshipexpr + ; + +@bin_bitwise_op_expr = @lshiftexpr + | @rshiftexpr + | @andexpr + | @orexpr + | @xorexpr + ; + +@p_arith_op_expr = @paddexpr + | @psubexpr + | @pdiffexpr + ; + +@bin_arith_op_expr = @addexpr + | @subexpr + | @mulexpr + | @divexpr + | @remexpr + | @jmulexpr + | @jdivexpr + | @fjaddexpr + | @jfaddexpr + | @fjsubexpr + | @jfsubexpr + | @minexpr + | @maxexpr + | @p_arith_op_expr + ; + +@bin_op_expr = @bin_arith_op_expr + | @bin_bitwise_op_expr + | @cmp_op_expr + | @bin_log_op_expr + ; + +@op_expr = @un_op_expr + | @bin_op_expr + | @assign_expr + | @conditionalexpr + ; + +@assign_arith_expr = @assignaddexpr + | @assignsubexpr + | @assignmulexpr + | @assigndivexpr + | @assignremexpr + ; + +@assign_bitwise_expr = @assignandexpr + | @assignorexpr + | @assignxorexpr + | @assignlshiftexpr + | @assignrshiftexpr + | @assignpaddexpr + | @assignpsubexpr + ; + +@assign_op_expr = @assign_arith_expr | @assign_bitwise_expr + +@assign_expr = @assignexpr | @assign_op_expr | @blockassignexpr + +/* + case @allocator.form of + 0 = plain + | 1 = alignment + ; +*/ + +/** + * The allocator function associated with a `new` or `new[]` expression. + * The `form` column specified whether the allocation call contains an alignment + * argument. + */ +expr_allocator( + unique int expr: @any_new_expr ref, + int func: @function ref, + int form: int ref +); + +/* + case @deallocator.form of + 0 = plain + | 1 = size + | 2 = alignment + | 3 = size_and_alignment + ; +*/ + +/** + * The deallocator function associated with a `delete`, `delete[]`, `new`, or + * `new[]` expression. For a `new` or `new[]` expression, the deallocator is the + * one used to free memory if the initialization throws an exception. + * The `form` column specifies whether the deallocation call contains a size + * argument, and alignment argument, or both. + */ +expr_deallocator( + unique int expr: @new_or_delete_expr ref, + int func: @function ref, + int form: int ref +); + +/** + * Holds if the `@conditionalexpr` is of the two operand form + * `guard ? : false`. + */ +expr_cond_two_operand( + unique int cond: @conditionalexpr ref +); + +/** + * The guard of `@conditionalexpr` `guard ? true : false` + */ +expr_cond_guard( + unique int cond: @conditionalexpr ref, + int guard: @expr ref +); + +/** + * The expression used when the guard of `@conditionalexpr` + * `guard ? true : false` holds. For the two operand form + * `guard ?: false` consider using `expr_cond_guard` instead. + */ +expr_cond_true( + unique int cond: @conditionalexpr ref, + int true: @expr ref +); + +/** + * The expression used when the guard of `@conditionalexpr` + * `guard ? true : false` does not hold. + */ +expr_cond_false( + unique int cond: @conditionalexpr ref, + int false: @expr ref +); + +/** A string representation of the value. */ +values( + unique int id: @value, + string str: string ref +); + +/** The actual text in the source code for the value, if any. */ +valuetext( + unique int id: @value ref, + string text: string ref +); + +valuebind( + int val: @value ref, + unique int expr: @expr ref +); + +fieldoffsets( + unique int id: @variable ref, + int byteoffset: int ref, + int bitoffset: int ref +); + +bitfield( + unique int id: @variable ref, + int bits: int ref, + int declared_bits: int ref +); + +/* TODO +memberprefix( + int member: @expr ref, + int prefix: @expr ref +); +*/ + +/* + kind(1) = mbrcallexpr + kind(2) = mbrptrcallexpr + kind(3) = mbrptrmbrcallexpr + kind(4) = ptrmbrptrmbrcallexpr + kind(5) = mbrreadexpr // x.y + kind(6) = mbrptrreadexpr // p->y + kind(7) = mbrptrmbrreadexpr // x.*pm + kind(8) = mbrptrmbrptrreadexpr // x->*pm + kind(9) = staticmbrreadexpr // static x.y + kind(10) = staticmbrptrreadexpr // static p->y +*/ +/* TODO +memberaccess( + int member: @expr ref, + int kind: int ref +); +*/ + +initialisers( + unique int init: @initialiser, + int var: @accessible ref, + unique int expr: @expr ref, + int location: @location_expr ref +); + +braced_initialisers( + int init: @initialiser ref +); + +/** + * An ancestor for the expression, for cases in which we cannot + * otherwise find the expression's parent. + */ +expr_ancestor( + int exp: @expr ref, + int ancestor: @element ref +); + +exprs( + unique int id: @expr, + int kind: int ref, + int location: @location_expr ref +); + +/* + case @value.category of + 1 = prval + | 2 = xval + | 3 = lval + ; +*/ +expr_types( + int id: @expr ref, + int typeid: @type ref, + int value_category: int ref +); + +case @expr.kind of + 1 = @errorexpr +| 2 = @address_of // & AddressOfExpr +| 3 = @reference_to // ReferenceToExpr (implicit?) +| 4 = @indirect // * PointerDereferenceExpr +| 5 = @ref_indirect // ReferenceDereferenceExpr (implicit?) +// ... +| 8 = @array_to_pointer // (???) +| 9 = @vacuous_destructor_call // VacuousDestructorCall +// ... +| 11 = @assume // Microsoft +| 12 = @parexpr +| 13 = @arithnegexpr +| 14 = @unaryplusexpr +| 15 = @complementexpr +| 16 = @notexpr +| 17 = @conjugation // GNU ~ operator +| 18 = @realpartexpr // GNU __real +| 19 = @imagpartexpr // GNU __imag +| 20 = @postincrexpr +| 21 = @postdecrexpr +| 22 = @preincrexpr +| 23 = @predecrexpr +| 24 = @conditionalexpr +| 25 = @addexpr +| 26 = @subexpr +| 27 = @mulexpr +| 28 = @divexpr +| 29 = @remexpr +| 30 = @jmulexpr // C99 mul imaginary +| 31 = @jdivexpr // C99 div imaginary +| 32 = @fjaddexpr // C99 add real + imaginary +| 33 = @jfaddexpr // C99 add imaginary + real +| 34 = @fjsubexpr // C99 sub real - imaginary +| 35 = @jfsubexpr // C99 sub imaginary - real +| 36 = @paddexpr // pointer add (pointer + int or int + pointer) +| 37 = @psubexpr // pointer sub (pointer - integer) +| 38 = @pdiffexpr // difference between two pointers +| 39 = @lshiftexpr +| 40 = @rshiftexpr +| 41 = @andexpr +| 42 = @orexpr +| 43 = @xorexpr +| 44 = @eqexpr +| 45 = @neexpr +| 46 = @gtexpr +| 47 = @ltexpr +| 48 = @geexpr +| 49 = @leexpr +| 50 = @minexpr // GNU minimum +| 51 = @maxexpr // GNU maximum +| 52 = @assignexpr +| 53 = @assignaddexpr +| 54 = @assignsubexpr +| 55 = @assignmulexpr +| 56 = @assigndivexpr +| 57 = @assignremexpr +| 58 = @assignlshiftexpr +| 59 = @assignrshiftexpr +| 60 = @assignandexpr +| 61 = @assignorexpr +| 62 = @assignxorexpr +| 63 = @assignpaddexpr // assign pointer add +| 64 = @assignpsubexpr // assign pointer sub +| 65 = @andlogicalexpr +| 66 = @orlogicalexpr +| 67 = @commaexpr +| 68 = @subscriptexpr // access to member of an array, e.g., a[5] +// ... 69 @objc_subscriptexpr deprecated +// ... 70 @cmdaccess deprecated +// ... +| 73 = @virtfunptrexpr +| 74 = @callexpr +// ... 75 @msgexpr_normal deprecated +// ... 76 @msgexpr_super deprecated +// ... 77 @atselectorexpr deprecated +// ... 78 @atprotocolexpr deprecated +| 79 = @vastartexpr +| 80 = @vaargexpr +| 81 = @vaendexpr +| 82 = @vacopyexpr +// ... 83 @atencodeexpr deprecated +| 84 = @varaccess +| 85 = @thisaccess +// ... 86 @objc_box_expr deprecated +| 87 = @new_expr +| 88 = @delete_expr +| 89 = @throw_expr +| 90 = @condition_decl // a variable declared in a condition, e.g., if(int x = y > 2) +| 91 = @braced_init_list +| 92 = @type_id +| 93 = @runtime_sizeof +| 94 = @runtime_alignof +| 95 = @sizeof_pack +| 96 = @expr_stmt // GNU extension +| 97 = @routineexpr +| 98 = @type_operand // used to access a type in certain contexts (haven't found any examples yet....) +| 99 = @offsetofexpr // offsetof ::= type and field +| 100 = @hasassignexpr // __has_assign ::= type +| 101 = @hascopyexpr // __has_copy ::= type +| 102 = @hasnothrowassign // __has_nothrow_assign ::= type +| 103 = @hasnothrowconstr // __has_nothrow_constructor ::= type +| 104 = @hasnothrowcopy // __has_nothrow_copy ::= type +| 105 = @hastrivialassign // __has_trivial_assign ::= type +| 106 = @hastrivialconstr // __has_trivial_constructor ::= type +| 107 = @hastrivialcopy // __has_trivial_copy ::= type +| 108 = @hasuserdestr // __has_user_destructor ::= type +| 109 = @hasvirtualdestr // __has_virtual_destructor ::= type +| 110 = @isabstractexpr // __is_abstract ::= type +| 111 = @isbaseofexpr // __is_base_of ::= type type +| 112 = @isclassexpr // __is_class ::= type +| 113 = @isconvtoexpr // __is_convertible_to ::= type type +| 114 = @isemptyexpr // __is_empty ::= type +| 115 = @isenumexpr // __is_enum ::= type +| 116 = @ispodexpr // __is_pod ::= type +| 117 = @ispolyexpr // __is_polymorphic ::= type +| 118 = @isunionexpr // __is_union ::= type +| 119 = @typescompexpr // GNU __builtin_types_compatible ::= type type +| 120 = @intaddrexpr // frontend internal builtin, used to implement offsetof +// ... +| 122 = @hastrivialdestructor // __has_trivial_destructor ::= type +| 123 = @literal +| 124 = @uuidof +| 127 = @aggregateliteral +| 128 = @delete_array_expr +| 129 = @new_array_expr +// ... 130 @objc_array_literal deprecated +// ... 131 @objc_dictionary_literal deprecated +| 132 = @foldexpr +// ... +| 200 = @ctordirectinit +| 201 = @ctorvirtualinit +| 202 = @ctorfieldinit +| 203 = @ctordelegatinginit +| 204 = @dtordirectdestruct +| 205 = @dtorvirtualdestruct +| 206 = @dtorfielddestruct +// ... +| 210 = @static_cast +| 211 = @reinterpret_cast +| 212 = @const_cast +| 213 = @dynamic_cast +| 214 = @c_style_cast +| 215 = @lambdaexpr +| 216 = @param_ref +| 217 = @noopexpr +// ... +| 294 = @istriviallyconstructibleexpr +| 295 = @isdestructibleexpr +| 296 = @isnothrowdestructibleexpr +| 297 = @istriviallydestructibleexpr +| 298 = @istriviallyassignableexpr +| 299 = @isnothrowassignableexpr +| 300 = @istrivialexpr +| 301 = @isstandardlayoutexpr +| 302 = @istriviallycopyableexpr +| 303 = @isliteraltypeexpr +| 304 = @hastrivialmoveconstructorexpr +| 305 = @hastrivialmoveassignexpr +| 306 = @hasnothrowmoveassignexpr +| 307 = @isconstructibleexpr +| 308 = @isnothrowconstructibleexpr +| 309 = @hasfinalizerexpr +| 310 = @isdelegateexpr +| 311 = @isinterfaceclassexpr +| 312 = @isrefarrayexpr +| 313 = @isrefclassexpr +| 314 = @issealedexpr +| 315 = @issimplevalueclassexpr +| 316 = @isvalueclassexpr +| 317 = @isfinalexpr +| 319 = @noexceptexpr +| 320 = @builtinshufflevector +| 321 = @builtinchooseexpr +| 322 = @builtinaddressof +| 323 = @vec_fill +| 324 = @builtinconvertvector +| 325 = @builtincomplex +| 326 = @spaceshipexpr +| 327 = @co_await +| 328 = @co_yield +| 329 = @temp_init +| 330 = @isassignable +| 331 = @isaggregate +| 332 = @hasuniqueobjectrepresentations +| 333 = @builtinbitcast +| 334 = @builtinshuffle +| 335 = @blockassignexpr +| 336 = @issame +| 337 = @isfunction +| 338 = @islayoutcompatible +| 339 = @ispointerinterconvertiblebaseof +| 340 = @isarray +| 341 = @arrayrank +| 342 = @arrayextent +| 343 = @isarithmetic +| 344 = @iscompletetype +| 345 = @iscompound +| 346 = @isconst +| 347 = @isfloatingpoint +| 348 = @isfundamental +| 349 = @isintegral +| 350 = @islvaluereference +| 351 = @ismemberfunctionpointer +| 352 = @ismemberobjectpointer +| 353 = @ismemberpointer +| 354 = @isobject +| 355 = @ispointer +| 356 = @isreference +| 357 = @isrvaluereference +| 358 = @isscalar +| 359 = @issigned +| 360 = @isunsigned +| 361 = @isvoid +| 362 = @isvolatile +; + +@var_args_expr = @vastartexpr + | @vaendexpr + | @vaargexpr + | @vacopyexpr + ; + +@builtin_op = @var_args_expr + | @noopexpr + | @offsetofexpr + | @intaddrexpr + | @hasassignexpr + | @hascopyexpr + | @hasnothrowassign + | @hasnothrowconstr + | @hasnothrowcopy + | @hastrivialassign + | @hastrivialconstr + | @hastrivialcopy + | @hastrivialdestructor + | @hasuserdestr + | @hasvirtualdestr + | @isabstractexpr + | @isbaseofexpr + | @isclassexpr + | @isconvtoexpr + | @isemptyexpr + | @isenumexpr + | @ispodexpr + | @ispolyexpr + | @isunionexpr + | @typescompexpr + | @builtinshufflevector + | @builtinconvertvector + | @builtinaddressof + | @istriviallyconstructibleexpr + | @isdestructibleexpr + | @isnothrowdestructibleexpr + | @istriviallydestructibleexpr + | @istriviallyassignableexpr + | @isnothrowassignableexpr + | @istrivialexpr + | @isstandardlayoutexpr + | @istriviallycopyableexpr + | @isliteraltypeexpr + | @hastrivialmoveconstructorexpr + | @hastrivialmoveassignexpr + | @hasnothrowmoveassignexpr + | @isconstructibleexpr + | @isnothrowconstructibleexpr + | @hasfinalizerexpr + | @isdelegateexpr + | @isinterfaceclassexpr + | @isrefarrayexpr + | @isrefclassexpr + | @issealedexpr + | @issimplevalueclassexpr + | @isvalueclassexpr + | @isfinalexpr + | @builtinchooseexpr + | @builtincomplex + | @isassignable + | @isaggregate + | @hasuniqueobjectrepresentations + | @builtinbitcast + | @builtinshuffle + | @issame + | @isfunction + | @islayoutcompatible + | @ispointerinterconvertiblebaseof + | @isarray + | @arrayrank + | @arrayextent + | @isarithmetic + | @iscompletetype + | @iscompound + | @isconst + | @isfloatingpoint + | @isfundamental + | @isintegral + | @islvaluereference + | @ismemberfunctionpointer + | @ismemberobjectpointer + | @ismemberpointer + | @isobject + | @ispointer + | @isreference + | @isrvaluereference + | @isscalar + | @issigned + | @isunsigned + | @isvoid + | @isvolatile + ; + +new_allocated_type( + unique int expr: @new_expr ref, + int type_id: @type ref +); + +new_array_allocated_type( + unique int expr: @new_array_expr ref, + int type_id: @type ref +); + +/** + * The field being initialized by an initializer expression within an aggregate + * initializer for a class/struct/union. Position is used to sort repeated initializers. + */ +#keyset[aggregate, position] +aggregate_field_init( + int aggregate: @aggregateliteral ref, + int initializer: @expr ref, + int field: @membervariable ref, + int position: int ref +); + +/** + * The index of the element being initialized by an initializer expression + * within an aggregate initializer for an array. Position is used to sort repeated initializers. + */ +#keyset[aggregate, position] +aggregate_array_init( + int aggregate: @aggregateliteral ref, + int initializer: @expr ref, + int element_index: int ref, + int position: int ref +); + +@ctorinit = @ctordirectinit + | @ctorvirtualinit + | @ctorfieldinit + | @ctordelegatinginit; +@dtordestruct = @dtordirectdestruct + | @dtorvirtualdestruct + | @dtorfielddestruct; + + +condition_decl_bind( + unique int expr: @condition_decl ref, + unique int decl: @declaration ref +); + +typeid_bind( + unique int expr: @type_id ref, + int type_id: @type ref +); + +uuidof_bind( + unique int expr: @uuidof ref, + int type_id: @type ref +); + +@runtime_sizeof_or_alignof = @runtime_sizeof | @runtime_alignof; + +sizeof_bind( + unique int expr: @runtime_sizeof_or_alignof ref, + int type_id: @type ref +); + +code_block( + unique int block: @literal ref, + unique int routine: @function ref +); + +lambdas( + unique int expr: @lambdaexpr ref, + string default_capture: string ref, + boolean has_explicit_return_type: boolean ref +); + +lambda_capture( + unique int id: @lambdacapture, + int lambda: @lambdaexpr ref, + int index: int ref, + int field: @membervariable ref, + boolean captured_by_reference: boolean ref, + boolean is_implicit: boolean ref, + int location: @location_default ref +); + +@funbindexpr = @routineexpr + | @new_expr + | @delete_expr + | @delete_array_expr + | @ctordirectinit + | @ctorvirtualinit + | @ctordelegatinginit + | @dtordirectdestruct + | @dtorvirtualdestruct; + +@varbindexpr = @varaccess | @ctorfieldinit | @dtorfielddestruct; +@addressable = @function | @variable ; +@accessible = @addressable | @enumconstant ; + +@access = @varaccess | @routineexpr ; + +fold( + int expr: @foldexpr ref, + string operator: string ref, + boolean is_left_fold: boolean ref +); + +stmts( + unique int id: @stmt, + int kind: int ref, + int location: @location_stmt ref +); + +case @stmt.kind of + 1 = @stmt_expr +| 2 = @stmt_if +| 3 = @stmt_while +| 4 = @stmt_goto +| 5 = @stmt_label +| 6 = @stmt_return +| 7 = @stmt_block +| 8 = @stmt_end_test_while // do { ... } while ( ... ) +| 9 = @stmt_for +| 10 = @stmt_switch_case +| 11 = @stmt_switch +| 13 = @stmt_asm // "asm" statement or the body of an asm function +| 15 = @stmt_try_block +| 16 = @stmt_microsoft_try // Microsoft +| 17 = @stmt_decl +| 18 = @stmt_set_vla_size // C99 +| 19 = @stmt_vla_decl // C99 +| 25 = @stmt_assigned_goto // GNU +| 26 = @stmt_empty +| 27 = @stmt_continue +| 28 = @stmt_break +| 29 = @stmt_range_based_for // C++11 +// ... 30 @stmt_at_autoreleasepool_block deprecated +// ... 31 @stmt_objc_for_in deprecated +// ... 32 @stmt_at_synchronized deprecated +| 33 = @stmt_handler +// ... 34 @stmt_finally_end deprecated +| 35 = @stmt_constexpr_if +| 37 = @stmt_co_return +; + +type_vla( + int type_id: @type ref, + int decl: @stmt_vla_decl ref +); + +variable_vla( + int var: @variable ref, + int decl: @stmt_vla_decl ref +); + +if_initialization( + unique int if_stmt: @stmt_if ref, + int init_id: @stmt ref +); + +if_then( + unique int if_stmt: @stmt_if ref, + int then_id: @stmt ref +); + +if_else( + unique int if_stmt: @stmt_if ref, + int else_id: @stmt ref +); + +constexpr_if_initialization( + unique int constexpr_if_stmt: @stmt_constexpr_if ref, + int init_id: @stmt ref +); + +constexpr_if_then( + unique int constexpr_if_stmt: @stmt_constexpr_if ref, + int then_id: @stmt ref +); + +constexpr_if_else( + unique int constexpr_if_stmt: @stmt_constexpr_if ref, + int else_id: @stmt ref +); + +while_body( + unique int while_stmt: @stmt_while ref, + int body_id: @stmt ref +); + +do_body( + unique int do_stmt: @stmt_end_test_while ref, + int body_id: @stmt ref +); + +switch_initialization( + unique int switch_stmt: @stmt_switch ref, + int init_id: @stmt ref +); + +#keyset[switch_stmt, index] +switch_case( + int switch_stmt: @stmt_switch ref, + int index: int ref, + int case_id: @stmt_switch_case ref +); + +switch_body( + unique int switch_stmt: @stmt_switch ref, + int body_id: @stmt ref +); + +for_initialization( + unique int for_stmt: @stmt_for ref, + int init_id: @stmt ref +); + +for_condition( + unique int for_stmt: @stmt_for ref, + int condition_id: @expr ref +); + +for_update( + unique int for_stmt: @stmt_for ref, + int update_id: @expr ref +); + +for_body( + unique int for_stmt: @stmt_for ref, + int body_id: @stmt ref +); + +@stmtparent = @stmt | @expr_stmt ; +stmtparents( + unique int id: @stmt ref, + int index: int ref, + int parent: @stmtparent ref +); + +ishandler(unique int block: @stmt_block ref); + +@cfgnode = @stmt | @expr | @function | @initialiser ; + +stmt_decl_bind( + int stmt: @stmt_decl ref, + int num: int ref, + int decl: @declaration ref +); + +stmt_decl_entry_bind( + int stmt: @stmt_decl ref, + int num: int ref, + int decl_entry: @element ref +); + +@functionorblock = @function | @stmt_block; + +blockscope( + unique int block: @stmt_block ref, + int enclosing: @functionorblock ref +); + +@jump = @stmt_goto | @stmt_break | @stmt_continue; + +@jumporlabel = @jump | @stmt_label | @literal; + +jumpinfo( + unique int id: @jumporlabel ref, + string str: string ref, + int target: @stmt ref +); + +preprocdirects( + unique int id: @preprocdirect, + int kind: int ref, + int location: @location_default ref +); +case @preprocdirect.kind of + 0 = @ppd_if +| 1 = @ppd_ifdef +| 2 = @ppd_ifndef +| 3 = @ppd_elif +| 4 = @ppd_else +| 5 = @ppd_endif +| 6 = @ppd_plain_include +| 7 = @ppd_define +| 8 = @ppd_undef +| 9 = @ppd_line +| 10 = @ppd_error +| 11 = @ppd_pragma +| 12 = @ppd_objc_import +| 13 = @ppd_include_next +| 18 = @ppd_warning +; + +@ppd_include = @ppd_plain_include | @ppd_objc_import | @ppd_include_next; + +@ppd_branch = @ppd_if | @ppd_ifdef | @ppd_ifndef | @ppd_elif; + +preprocpair( + int begin : @ppd_branch ref, + int elseelifend : @preprocdirect ref +); + +preproctrue(int branch : @ppd_branch ref); +preprocfalse(int branch : @ppd_branch ref); + +preproctext( + unique int id: @preprocdirect ref, + string head: string ref, + string body: string ref +); + +includes( + unique int id: @ppd_include ref, + int included: @file ref +); + +link_targets( + unique int id: @link_target, + int binary: @file ref +); + +link_parent( + int element : @element ref, + int link_target : @link_target ref +); + +/* XML Files */ + +xmlEncoding(unique int id: @file ref, string encoding: string ref); + +xmlDTDs( + unique int id: @xmldtd, + string root: string ref, + string publicId: string ref, + string systemId: string ref, + int fileid: @file ref +); + +xmlElements( + unique int id: @xmlelement, + string name: string ref, + int parentid: @xmlparent ref, + int idx: int ref, + int fileid: @file ref +); + +xmlAttrs( + unique int id: @xmlattribute, + int elementid: @xmlelement ref, + string name: string ref, + string value: string ref, + int idx: int ref, + int fileid: @file ref +); + +xmlNs( + int id: @xmlnamespace, + string prefixName: string ref, + string 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, + string text: string ref, + int parentid: @xmlparent ref, + int fileid: @file ref +); + +xmlChars( + unique int id: @xmlcharacters, + string 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; diff --git a/cpp/downgrades/f79ce79e3b751aeeed59e594633ba5c07a27ef3e/upgrade.properties b/cpp/downgrades/f79ce79e3b751aeeed59e594633ba5c07a27ef3e/upgrade.properties new file mode 100644 index 000000000000..2e93d8c4306f --- /dev/null +++ b/cpp/downgrades/f79ce79e3b751aeeed59e594633ba5c07a27ef3e/upgrade.properties @@ -0,0 +1,3 @@ +description: Introduce extractor version numbers +compatibility: breaking +extractor_version.rel: delete diff --git a/cpp/ql/lib/change-notes/2023-10-24-remove-getlocation-from-folder.md b/cpp/ql/lib/change-notes/2023-10-24-remove-getlocation-from-folder.md new file mode 100644 index 000000000000..f2b168949a6a --- /dev/null +++ b/cpp/ql/lib/change-notes/2023-10-24-remove-getlocation-from-folder.md @@ -0,0 +1,4 @@ +--- +category: breaking +--- +* The `Container` and `Folder` classes now derive from `ElementBase` instead of `Locatable`, and no longer expose the `getLocation` predicate. Use `getURL` instead. diff --git a/cpp/ql/lib/qlpack.yml b/cpp/ql/lib/qlpack.yml index cb5488af594a..06ce6589b7b6 100644 --- a/cpp/ql/lib/qlpack.yml +++ b/cpp/ql/lib/qlpack.yml @@ -7,6 +7,7 @@ library: true upgrades: upgrades dependencies: codeql/dataflow: ${workspace} + codeql/rangeanalysis: ${workspace} codeql/ssa: ${workspace} codeql/tutorial: ${workspace} codeql/util: ${workspace} diff --git a/cpp/ql/lib/semmle/code/cpp/File.qll b/cpp/ql/lib/semmle/code/cpp/File.qll index 55ecd2b46e36..950368bf984a 100644 --- a/cpp/ql/lib/semmle/code/cpp/File.qll +++ b/cpp/ql/lib/semmle/code/cpp/File.qll @@ -32,7 +32,7 @@ private module Input implements InputSig { private module Impl = Make; /** A file or folder. */ -class Container extends Locatable, Impl::Container { +class Container extends ElementBase, Impl::Container { override string toString() { result = Impl::Container.super.toString() } } @@ -47,11 +47,6 @@ class Container extends Locatable, Impl::Container { * To get the full path, use `getAbsolutePath`. */ class Folder extends Container, Impl::Folder { - override Location getLocation() { - result.getContainer() = this and - result.hasLocationInfo(_, 0, 0, 0, 0) - } - override string getAPrimaryQlClass() { result = "Folder" } } @@ -67,7 +62,7 @@ class Folder extends Container, Impl::Folder { * The base name further decomposes into the _stem_ and _extension_ -- see * `getStem` and `getExtension`. To get the full path, use `getAbsolutePath`. */ -class File extends Container, Impl::File { +class File extends Container, Locatable, Impl::File { override string getAPrimaryQlClass() { result = "File" } override Location getLocation() { diff --git a/cpp/ql/lib/semmle/code/cpp/internal/ExtractorVersion.qll b/cpp/ql/lib/semmle/code/cpp/internal/ExtractorVersion.qll new file mode 100644 index 000000000000..859f0375b364 --- /dev/null +++ b/cpp/ql/lib/semmle/code/cpp/internal/ExtractorVersion.qll @@ -0,0 +1,15 @@ +/** + * INTERNAL: Do not use. Provides predicates for getting the CodeQL and frontend + * version used during database extraction. + */ + +/** Get the extractor CodeQL version */ +string getExtractorCodeQLVersion() { extractor_version(result, _) } + +/** Get the extractor frontend version */ +string getExtractorFrontendVersion() { extractor_version(_, result) } + +predicate isExtractorFrontendVersion65OrHigher() { + // Version numbers we not included in the database before 6.5. + exists(getExtractorCodeQLVersion()) +} diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/ModelUtil.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/ModelUtil.qll index cc2a0b01c4d4..055f48c80ec8 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/ModelUtil.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/ModelUtil.qll @@ -32,25 +32,34 @@ DataFlow::Node callInput(CallInstruction call, FunctionInput input) { } /** - * Gets the instruction that holds the `output` for `call`. + * Gets the node that represents the output of `call` with kind `output` at + * indirection index `indirectionIndex`. */ -Node callOutput(CallInstruction call, FunctionOutput output) { +private Node callOutputWithIndirectionIndex( + CallInstruction call, FunctionOutput output, int indirectionIndex +) { // The return value simpleOutNode(result, call) and - output.isReturnValue() + output.isReturnValue() and + indirectionIndex = 0 or // The side effect of a call on the value pointed to by an argument or qualifier - exists(int index, int indirectionIndex | + exists(int index | result.(IndirectArgumentOutNode).getArgumentIndex() = index and - result.(IndirectArgumentOutNode).getIndirectionIndex() = indirectionIndex and + result.(IndirectArgumentOutNode).getIndirectionIndex() = indirectionIndex - 1 and result.(IndirectArgumentOutNode).getCallInstruction() = call and - output.isParameterDerefOrQualifierObject(index, indirectionIndex) + output.isParameterDerefOrQualifierObject(index, indirectionIndex - 1) ) or - exists(int ind | - result = getIndirectReturnOutNode(call, ind) and - output.isReturnValueDeref(ind) - ) + result = getIndirectReturnOutNode(call, indirectionIndex) and + output.isReturnValueDeref(indirectionIndex) +} + +/** + * Gets the instruction that holds the `output` for `call`. + */ +Node callOutput(CallInstruction call, FunctionOutput output) { + result = callOutputWithIndirectionIndex(call, output, _) } DataFlow::Node callInput(CallInstruction call, FunctionInput input, int d) { @@ -76,19 +85,15 @@ private IndirectReturnOutNode getIndirectReturnOutNode(CallInstruction call, int */ bindingset[d] Node callOutput(CallInstruction call, FunctionOutput output, int d) { - exists(DataFlow::Node n | n = callOutput(call, output) and d > 0 | + exists(DataFlow::Node n, int indirectionIndex | + n = callOutputWithIndirectionIndex(call, output, indirectionIndex) and d > 0 + | // The return value - result = getIndirectReturnOutNode(n.asInstruction(), d) + result = callOutputWithIndirectionIndex(call, output, indirectionIndex + d) or // If there isn't an indirect out node for the call with indirection `d` then // we conflate this with the underlying `CallInstruction`. - not exists(getIndirectReturnOutNode(call, d)) and + not exists(getIndirectReturnOutNode(call, indirectionIndex + d)) and n = result - or - // The side effect of a call on the value pointed to by an argument or qualifier - exists(Operand operand, int indirectionIndex | - Ssa::outNodeHasAddressAndIndex(n, operand, indirectionIndex) and - Ssa::outNodeHasAddressAndIndex(result, operand, indirectionIndex + d) - ) ) } diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/SsaInternalsCommon.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/SsaInternalsCommon.qll index 8d9156502665..fc718693dbdf 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/SsaInternalsCommon.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/SsaInternalsCommon.qll @@ -228,7 +228,7 @@ private class PointerWrapperTypeIndirection extends Indirection instanceof Point override predicate isAdditionalDereference(Instruction deref, Operand address) { exists(CallInstruction call | operandForFullyConvertedCall(getAUse(deref), call) and - this = call.getStaticCallTarget().getClassAndName("operator*") and + this = call.getStaticCallTarget().getClassAndName(["operator*", "operator->", "get"]) and address = call.getThisArgumentOperand() ) } diff --git a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedElement.qll b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedElement.qll index 03ef716f4f06..a0967ed9a774 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedElement.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedElement.qll @@ -1,5 +1,6 @@ private import cpp import semmle.code.cpp.ir.implementation.raw.IR +private import semmle.code.cpp.internal.ExtractorVersion private import semmle.code.cpp.ir.IRConfiguration private import semmle.code.cpp.ir.implementation.Opcode private import semmle.code.cpp.ir.implementation.internal.OperandTag @@ -362,10 +363,10 @@ predicate ignoreLoad(Expr expr) { expr instanceof FunctionAccess or // The load is duplicated from the operand. - expr instanceof ParenthesisExpr + isExtractorFrontendVersion65OrHigher() and expr instanceof ParenthesisExpr or // The load is duplicated from the right operand. - expr instanceof CommaExpr + isExtractorFrontendVersion65OrHigher() and expr instanceof CommaExpr or expr.(PointerDereferenceExpr).getOperand().getFullyConverted().getType().getUnspecifiedType() instanceof FunctionPointerType diff --git a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedExpr.qll b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedExpr.qll index 2a62d4f1219d..f06579fc4368 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedExpr.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/implementation/raw/internal/TranslatedExpr.qll @@ -1,4 +1,5 @@ private import cpp +private import semmle.code.cpp.internal.ExtractorVersion private import semmle.code.cpp.ir.implementation.IRType private import semmle.code.cpp.ir.implementation.Opcode private import semmle.code.cpp.ir.implementation.internal.OperandTag @@ -648,7 +649,21 @@ abstract class TranslatedCrementOperation extends TranslatedNonConstantExpr { class TranslatedPrefixCrementOperation extends TranslatedCrementOperation { override PrefixCrementOperation expr; - override Instruction getResult() { result = this.getUnloadedOperand().getResult() } + override Instruction getResult() { + // The following distinction is needed to work around extractor limitations + // in old versions of the extractor. + if expr.isPRValueCategory() and not isExtractorFrontendVersion65OrHigher() + then + // If this is C, then the result of a prefix crement is a prvalue for the + // new value assigned to the operand. If this is C++, then the result is + // an lvalue, but that lvalue is being loaded as part of this expression. + // EDG doesn't mark this as a load. + result = this.getInstruction(CrementOpTag()) + else + // This is C++, where the result is an lvalue for the operand, and that + // lvalue is not being loaded as part of this expression. + result = this.getUnloadedOperand().getResult() + } } class TranslatedPostfixCrementOperation extends TranslatedCrementOperation { @@ -1491,7 +1506,21 @@ class TranslatedAssignExpr extends TranslatedNonConstantExpr { result = this.getRightOperand().getFirstInstruction() } - final override Instruction getResult() { result = this.getLeftOperand().getResult() } + final override Instruction getResult() { + // The following distinction is needed to work around extractor limitations + // in old versions of the extractor. + if expr.isPRValueCategory() and not isExtractorFrontendVersion65OrHigher() + then + // If this is C, then the result of an assignment is a prvalue for the new + // value assigned to the left operand. If this is C++, then the result is + // an lvalue, but that lvalue is being loaded as part of this expression. + // EDG doesn't mark this as a load. + result = this.getRightOperand().getResult() + else + // This is C++, where the result is an lvalue for the left operand, + // and that lvalue is not being loaded as part of this expression. + result = this.getLeftOperand().getResult() + } final TranslatedExpr getLeftOperand() { result = getTranslatedExpr(expr.getLValue().getFullyConverted()) @@ -1617,7 +1646,21 @@ class TranslatedAssignOperation extends TranslatedNonConstantExpr { result = this.getRightOperand().getFirstInstruction() } - final override Instruction getResult() { result = this.getUnloadedLeftOperand().getResult() } + final override Instruction getResult() { + // The following distinction is needed to work around extractor limitations + // in old versions of the extractor. + if expr.isPRValueCategory() and not isExtractorFrontendVersion65OrHigher() + then + // If this is C, then the result of an assignment is a prvalue for the new + // value assigned to the left operand. If this is C++, then the result is + // an lvalue, but that lvalue is being loaded as part of this expression. + // EDG doesn't mark this as a load. + result = this.getStoredValue() + else + // This is C++, where the result is an lvalue for the left operand, + // and that lvalue is not being loaded as part of this expression. + result = this.getUnloadedLeftOperand().getResult() + } final TranslatedExpr getUnloadedLeftOperand() { result = this.getLoadedLeftOperand().getOperand() @@ -2155,15 +2198,16 @@ abstract class TranslatedConditionalExpr extends TranslatedNonConstantExpr { not this.elseIsVoid() and tag = ConditionValueFalseStoreTag() ) and opcode instanceof Opcode::Store and - ( + if isExtractorFrontendVersion65OrHigher() + then not expr.hasLValueToRValueConversion() and resultType = this.getResultType() or expr.hasLValueToRValueConversion() and resultType = getTypeForPRValue(expr.getType()) - ) + else resultType = this.getResultType() or - not expr.hasLValueToRValueConversion() and + (not expr.hasLValueToRValueConversion() or not isExtractorFrontendVersion65OrHigher()) and tag = ConditionValueResultLoadTag() and opcode instanceof Opcode::Load and resultType = this.getResultType() @@ -2193,15 +2237,16 @@ abstract class TranslatedConditionalExpr extends TranslatedNonConstantExpr { ) or tag = ConditionValueResultTempAddressTag() and - ( + if isExtractorFrontendVersion65OrHigher() + then not expr.hasLValueToRValueConversion() and result = this.getInstruction(ConditionValueResultLoadTag()) or expr.hasLValueToRValueConversion() and result = this.getParent().getChildSuccessor(this) - ) + else result = this.getInstruction(ConditionValueResultLoadTag()) or - not expr.hasLValueToRValueConversion() and + (not expr.hasLValueToRValueConversion() or not isExtractorFrontendVersion65OrHigher()) and tag = ConditionValueResultLoadTag() and result = this.getParent().getChildSuccessor(this) ) @@ -2230,7 +2275,7 @@ abstract class TranslatedConditionalExpr extends TranslatedNonConstantExpr { result = this.getElse().getResult() ) or - not expr.hasLValueToRValueConversion() and + (not expr.hasLValueToRValueConversion() or not isExtractorFrontendVersion65OrHigher()) and tag = ConditionValueResultLoadTag() and operandTag instanceof AddressOperandTag and result = this.getInstruction(ConditionValueResultTempAddressTag()) @@ -2240,13 +2285,14 @@ abstract class TranslatedConditionalExpr extends TranslatedNonConstantExpr { final override predicate hasTempVariable(TempVariableTag tag, CppType type) { not this.resultIsVoid() and tag = ConditionValueTempVar() and - ( + if isExtractorFrontendVersion65OrHigher() + then not expr.hasLValueToRValueConversion() and type = this.getResultType() or expr.hasLValueToRValueConversion() and type = getTypeForPRValue(expr.getType()) - ) + else type = this.getResultType() } final override IRVariable getInstructionVariable(InstructionTag tag) { @@ -2261,13 +2307,14 @@ abstract class TranslatedConditionalExpr extends TranslatedNonConstantExpr { final override Instruction getResult() { not this.resultIsVoid() and - ( + if isExtractorFrontendVersion65OrHigher() + then expr.hasLValueToRValueConversion() and result = this.getInstruction(ConditionValueResultTempAddressTag()) or not expr.hasLValueToRValueConversion() and result = this.getInstruction(ConditionValueResultLoadTag()) - ) + else result = this.getInstruction(ConditionValueResultLoadTag()) } override Instruction getChildSuccessor(TranslatedElement child) { @@ -3226,9 +3273,19 @@ predicate exprNeedsCopyIfNotLoaded(Expr expr) { ( expr instanceof AssignExpr or - expr instanceof AssignOperation + expr instanceof AssignOperation and + ( + not expr.isPRValueCategory() // is C++ + or + isExtractorFrontendVersion65OrHigher() + ) or - expr instanceof PrefixCrementOperation + expr instanceof PrefixCrementOperation and + ( + not expr.isPRValueCategory() // is C++ + or + isExtractorFrontendVersion65OrHigher() + ) or // Because the load is on the `e` in `e++`. expr instanceof PostfixCrementOperation diff --git a/cpp/ql/lib/semmle/code/cpp/models/Models.qll b/cpp/ql/lib/semmle/code/cpp/models/Models.qll index 1318fd37b7fa..6a99a7e342b3 100644 --- a/cpp/ql/lib/semmle/code/cpp/models/Models.qll +++ b/cpp/ql/lib/semmle/code/cpp/models/Models.qll @@ -19,6 +19,7 @@ private import implementations.Strtok private import implementations.Strset private import implementations.Strcrement private import implementations.Strnextc +private import implementations.Strtol private import implementations.StdContainer private import implementations.StdPair private import implementations.StdMap diff --git a/cpp/ql/lib/semmle/code/cpp/models/implementations/Pure.qll b/cpp/ql/lib/semmle/code/cpp/models/implementations/Pure.qll index 41bd9ae0db7b..915bcbce6556 100644 --- a/cpp/ql/lib/semmle/code/cpp/models/implementations/Pure.qll +++ b/cpp/ql/lib/semmle/code/cpp/models/implementations/Pure.qll @@ -13,7 +13,7 @@ private class PureStrFunction extends AliasFunction, ArrayFunction, TaintFunctio PureStrFunction() { this.hasGlobalOrStdOrBslName([ atoi(), "strcasestr", "strchnul", "strchr", "strchrnul", "strstr", "strpbrk", "strrchr", - "strspn", strtol(), strrev(), strcmp(), strlwr(), strupr() + "strspn", strrev(), strcmp(), strlwr(), strupr() ]) } @@ -70,8 +70,6 @@ private class PureStrFunction extends AliasFunction, ArrayFunction, TaintFunctio private string atoi() { result = ["atof", "atoi", "atol", "atoll"] } -private string strtol() { result = ["strtod", "strtof", "strtol", "strtoll", "strtoq", "strtoul"] } - private string strlwr() { result = ["_strlwr", "_wcslwr", "_mbslwr", "_strlwr_l", "_wcslwr_l", "_mbslwr_l"] } diff --git a/cpp/ql/lib/semmle/code/cpp/models/implementations/Strtok.qll b/cpp/ql/lib/semmle/code/cpp/models/implementations/Strtok.qll index f2759e4a7378..6ccc4eb2fbe1 100644 --- a/cpp/ql/lib/semmle/code/cpp/models/implementations/Strtok.qll +++ b/cpp/ql/lib/semmle/code/cpp/models/implementations/Strtok.qll @@ -32,6 +32,8 @@ private class Strtok extends ArrayFunction, AliasFunction, TaintFunction, SideEf override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { input.isParameter(0) and output.isReturnValue() + or + input.isParameterDeref(0) and output.isReturnValueDeref() } override predicate hasOnlySpecificReadSideEffects() { none() } diff --git a/cpp/ql/lib/semmle/code/cpp/models/implementations/Strtol.qll b/cpp/ql/lib/semmle/code/cpp/models/implementations/Strtol.qll new file mode 100644 index 000000000000..30e95622924d --- /dev/null +++ b/cpp/ql/lib/semmle/code/cpp/models/implementations/Strtol.qll @@ -0,0 +1,54 @@ +import semmle.code.cpp.models.interfaces.ArrayFunction +import semmle.code.cpp.models.interfaces.Taint +import semmle.code.cpp.models.interfaces.Alias +import semmle.code.cpp.models.interfaces.SideEffect + +private string strtol() { result = ["strtod", "strtof", "strtol", "strtoll", "strtoq", "strtoul"] } + +/** + * The standard function `strtol` and its assorted variants + */ +private class Strtol extends AliasFunction, ArrayFunction, TaintFunction, SideEffectFunction { + Strtol() { this.hasGlobalOrStdOrBslName(strtol()) } + + override predicate hasArrayInput(int bufParam) { + // All the functions given by `strtol()` takes a `const char*` input as the first parameter + bufParam = 0 + } + + override predicate hasArrayWithNullTerminator(int bufParam) { bufParam = 0 } + + override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { + ( + input.isParameter(0) + or + input.isParameterDeref(0) + ) and + output.isReturnValue() + or + input.isParameter(0) and + output.isParameterDeref(1) + } + + override predicate parameterNeverEscapes(int i) { + // Parameter 0 does escape into parameter 1. + i = 1 + } + + override predicate parameterEscapesOnlyViaReturn(int i) { none() } + + override predicate parameterIsAlwaysReturned(int i) { none() } + + override predicate hasOnlySpecificReadSideEffects() { any() } + + override predicate hasOnlySpecificWriteSideEffects() { any() } + + override predicate hasSpecificReadSideEffect(ParameterIndex i, boolean buffer) { + i = 0 and + buffer = true + } + + override predicate hasSpecificWriteSideEffect(ParameterIndex i, boolean buffer, boolean mustWrite) { + i = 1 and buffer = false and mustWrite = false + } +} diff --git a/cpp/ql/lib/semmle/code/cpp/rangeanalysis/new/internal/semantic/SemanticLocation.qll b/cpp/ql/lib/semmle/code/cpp/rangeanalysis/new/internal/semantic/SemanticLocation.qll index 328f85151b58..0e801fb75c37 100644 --- a/cpp/ql/lib/semmle/code/cpp/rangeanalysis/new/internal/semantic/SemanticLocation.qll +++ b/cpp/ql/lib/semmle/code/cpp/rangeanalysis/new/internal/semantic/SemanticLocation.qll @@ -8,6 +8,18 @@ class SemLocation instanceof Location { */ string toString() { result = super.toString() } + /** Gets the 1-based line number (inclusive) where this location starts. */ + int getStartLine() { result = super.getStartLine() } + + /** Gets the 1-based column number (inclusive) where this location starts. */ + int getStartColumn() { result = super.getStartColumn() } + + /** Gets the 1-based line number (inclusive) where this location ends. */ + int getEndLine() { result = super.getEndLine() } + + /** Gets the 1-based column number (inclusive) where this location ends. */ + int getEndColumn() { result = super.getEndColumn() } + /** * Holds if this element is at the specified location. * The location spans column `startcolumn` of line `startline` to diff --git a/cpp/ql/lib/semmle/code/cpp/rangeanalysis/new/internal/semantic/analysis/FloatDelta.qll b/cpp/ql/lib/semmle/code/cpp/rangeanalysis/new/internal/semantic/analysis/FloatDelta.qll index 8767c53aa195..2cdeb9544ab7 100644 --- a/cpp/ql/lib/semmle/code/cpp/rangeanalysis/new/internal/semantic/analysis/FloatDelta.qll +++ b/cpp/ql/lib/semmle/code/cpp/rangeanalysis/new/internal/semantic/analysis/FloatDelta.qll @@ -1,5 +1,7 @@ -private import RangeAnalysisStage private import RangeAnalysisImpl +private import codeql.rangeanalysis.RangeAnalysis +private import semmle.code.cpp.rangeanalysis.new.internal.semantic.SemanticExpr +private import semmle.code.cpp.rangeanalysis.new.internal.semantic.SemanticType module FloatDelta implements DeltaSig { class Delta = float; @@ -20,7 +22,7 @@ module FloatDelta implements DeltaSig { Delta fromFloat(float f) { result = f } } -module FloatOverflow implements OverflowSig { +module FloatOverflow implements OverflowSig { predicate semExprDoesNotOverflow(boolean positively, SemExpr expr) { exists(float lb, float ub, float delta | typeBounds(expr.getSemType(), lb, ub) and diff --git a/cpp/ql/lib/semmle/code/cpp/rangeanalysis/new/internal/semantic/analysis/IntDelta.qll b/cpp/ql/lib/semmle/code/cpp/rangeanalysis/new/internal/semantic/analysis/IntDelta.qll deleted file mode 100644 index 83698b56229c..000000000000 --- a/cpp/ql/lib/semmle/code/cpp/rangeanalysis/new/internal/semantic/analysis/IntDelta.qll +++ /dev/null @@ -1,29 +0,0 @@ -private import RangeAnalysisStage - -module IntDelta implements DeltaSig { - class Delta = int; - - bindingset[d] - bindingset[result] - float toFloat(Delta d) { result = d } - - bindingset[d] - bindingset[result] - int toInt(Delta d) { result = d } - - bindingset[n] - bindingset[result] - Delta fromInt(int n) { result = n } - - bindingset[f] - Delta fromFloat(float f) { - result = - min(float diff, float res | - diff = (res - f) and res = f.ceil() - or - diff = (f - res) and res = f.floor() - | - res order by diff - ) - } -} diff --git a/cpp/ql/lib/semmle/code/cpp/rangeanalysis/new/internal/semantic/analysis/ModulusAnalysis.qll b/cpp/ql/lib/semmle/code/cpp/rangeanalysis/new/internal/semantic/analysis/ModulusAnalysis.qll index 9b00aca362f1..c53b0b85eb2a 100644 --- a/cpp/ql/lib/semmle/code/cpp/rangeanalysis/new/internal/semantic/analysis/ModulusAnalysis.qll +++ b/cpp/ql/lib/semmle/code/cpp/rangeanalysis/new/internal/semantic/analysis/ModulusAnalysis.qll @@ -12,11 +12,13 @@ private import ModulusAnalysisSpecific::Private private import semmle.code.cpp.rangeanalysis.new.internal.semantic.Semantic +private import semmle.code.cpp.rangeanalysis.new.internal.semantic.SemanticLocation private import ConstantAnalysis private import RangeUtils -private import RangeAnalysisStage +private import codeql.rangeanalysis.RangeAnalysis +private import RangeAnalysisImpl -module ModulusAnalysis Bounds, UtilSig U> { +module ModulusAnalysis Bounds, UtilSig U> { pragma[nomagic] private predicate valueFlowStepSsaEqFlowCond( SemSsaReadPosition pos, SemSsaVariable v, SemExpr e, int delta diff --git a/cpp/ql/lib/semmle/code/cpp/rangeanalysis/new/internal/semantic/analysis/RangeAnalysisConstantSpecific.qll b/cpp/ql/lib/semmle/code/cpp/rangeanalysis/new/internal/semantic/analysis/RangeAnalysisConstantSpecific.qll index 42edb904c3f4..fc729766d2da 100644 --- a/cpp/ql/lib/semmle/code/cpp/rangeanalysis/new/internal/semantic/analysis/RangeAnalysisConstantSpecific.qll +++ b/cpp/ql/lib/semmle/code/cpp/rangeanalysis/new/internal/semantic/analysis/RangeAnalysisConstantSpecific.qll @@ -3,10 +3,11 @@ */ private import semmle.code.cpp.rangeanalysis.new.internal.semantic.Semantic -private import RangeAnalysisStage private import semmle.code.cpp.rangeanalysis.new.internal.semantic.analysis.FloatDelta +private import RangeAnalysisImpl +private import codeql.rangeanalysis.RangeAnalysis -module CppLangImplConstant implements LangSig { +module CppLangImplConstant implements LangSig { /** * Holds if the specified expression should be excluded from the result of `ssaRead()`. * diff --git a/cpp/ql/lib/semmle/code/cpp/rangeanalysis/new/internal/semantic/analysis/RangeAnalysisImpl.qll b/cpp/ql/lib/semmle/code/cpp/rangeanalysis/new/internal/semantic/analysis/RangeAnalysisImpl.qll index 938857c0c2de..cbbd5d092bbb 100644 --- a/cpp/ql/lib/semmle/code/cpp/rangeanalysis/new/internal/semantic/analysis/RangeAnalysisImpl.qll +++ b/cpp/ql/lib/semmle/code/cpp/rangeanalysis/new/internal/semantic/analysis/RangeAnalysisImpl.qll @@ -1,13 +1,104 @@ -private import RangeAnalysisStage private import RangeAnalysisConstantSpecific private import RangeAnalysisRelativeSpecific private import semmle.code.cpp.rangeanalysis.new.internal.semantic.analysis.FloatDelta private import RangeUtils +private import semmle.code.cpp.rangeanalysis.new.internal.semantic.SemanticExpr +private import semmle.code.cpp.rangeanalysis.new.internal.semantic.SemanticCFG +private import semmle.code.cpp.rangeanalysis.new.internal.semantic.SemanticGuard private import semmle.code.cpp.rangeanalysis.new.internal.semantic.SemanticBound as SemanticBound private import semmle.code.cpp.rangeanalysis.new.internal.semantic.SemanticLocation private import semmle.code.cpp.rangeanalysis.new.internal.semantic.SemanticSSA +private import semmle.code.cpp.rangeanalysis.new.internal.semantic.SemanticType as SemanticType +private import SemanticType +private import codeql.rangeanalysis.RangeAnalysis +private import ConstantAnalysis as ConstantAnalysis -module ConstantBounds implements BoundSig { +module Sem implements Semantic { + class Expr = SemExpr; + + class ConstantIntegerExpr = ConstantAnalysis::SemConstantIntegerExpr; + + class BinaryExpr = SemBinaryExpr; + + class AddExpr = SemAddExpr; + + class SubExpr = SemSubExpr; + + class MulExpr = SemMulExpr; + + class DivExpr = SemDivExpr; + + class RemExpr = SemRemExpr; + + class BitAndExpr = SemBitAndExpr; + + class BitOrExpr = SemBitOrExpr; + + class ShiftLeftExpr = SemShiftLeftExpr; + + class ShiftRightExpr = SemShiftRightExpr; + + class ShiftRightUnsignedExpr = SemShiftRightUnsignedExpr; + + class RelationalExpr = SemRelationalExpr; + + class UnaryExpr = SemUnaryExpr; + + class ConvertExpr = SemConvertExpr; + + class BoxExpr = SemBoxExpr; + + class UnboxExpr = SemUnboxExpr; + + class NegateExpr = SemNegateExpr; + + class AddOneExpr = SemAddOneExpr; + + class SubOneExpr = SemSubOneExpr; + + class ConditionalExpr = SemConditionalExpr; + + class BasicBlock = SemBasicBlock; + + class Guard = SemGuard; + + predicate implies_v2 = semImplies_v2/4; + + predicate guardDirectlyControlsSsaRead = semGuardDirectlyControlsSsaRead/3; + + class Type = SemType; + + class IntegerType = SemIntegerType; + + class FloatingPointType = SemFloatingPointType; + + class AddressType = SemAddressType; + + class SsaVariable = SemSsaVariable; + + class SsaPhiNode = SemSsaPhiNode; + + class SsaExplicitUpdate = SemSsaExplicitUpdate; + + class SsaReadPosition = SemSsaReadPosition; + + class SsaReadPositionPhiInputEdge = SemSsaReadPositionPhiInputEdge; + + class SsaReadPositionBlock = SemSsaReadPositionBlock; + + predicate backEdge = semBackEdge/3; + + predicate conversionCannotOverflow(Type fromType, Type toType) { + SemanticType::conversionCannotOverflow(fromType, toType) + } +} + +module SignAnalysis implements SignAnalysisSig { + private import SignAnalysisCommon as SA + import SA::SignAnalysis +} + +module ConstantBounds implements BoundSig { class SemBound instanceof SemanticBound::SemBound { SemBound() { this instanceof SemanticBound::SemZeroBound @@ -29,7 +120,7 @@ module ConstantBounds implements BoundSig { } } -module RelativeBounds implements BoundSig { +module RelativeBounds implements BoundSig { class SemBound instanceof SemanticBound::SemBound { SemBound() { not this instanceof SemanticBound::SemZeroBound } @@ -47,13 +138,38 @@ module RelativeBounds implements BoundSig { } } +module AllBounds implements BoundSig { + class SemBound instanceof SemanticBound::SemBound { + string toString() { result = super.toString() } + + SemLocation getLocation() { result = super.getLocation() } + + SemExpr getExpr(float delta) { result = super.getExpr(delta) } + } + + class SemZeroBound extends SemBound instanceof SemanticBound::SemZeroBound { } + + class SemSsaBound extends SemBound instanceof SemanticBound::SemSsaBound { + SemSsaVariable getAVariable() { result = this.(SemanticBound::SemSsaBound).getAVariable() } + } +} + +private module ModulusAnalysisInstantiated implements ModulusAnalysisSig { + class ModBound = AllBounds::SemBound; + + private import semmle.code.cpp.rangeanalysis.new.internal.semantic.analysis.ModulusAnalysis as MA + import MA::ModulusAnalysis +} + +module Util = RangeUtil; + module ConstantStage = - RangeStage>; + RangeStage; module RelativeStage = - RangeStage>; + RangeStage; private newtype TSemReason = TSemNoReason() or diff --git a/cpp/ql/lib/semmle/code/cpp/rangeanalysis/new/internal/semantic/analysis/RangeAnalysisRelativeSpecific.qll b/cpp/ql/lib/semmle/code/cpp/rangeanalysis/new/internal/semantic/analysis/RangeAnalysisRelativeSpecific.qll index 7643c4aadb94..114219783860 100644 --- a/cpp/ql/lib/semmle/code/cpp/rangeanalysis/new/internal/semantic/analysis/RangeAnalysisRelativeSpecific.qll +++ b/cpp/ql/lib/semmle/code/cpp/rangeanalysis/new/internal/semantic/analysis/RangeAnalysisRelativeSpecific.qll @@ -3,13 +3,12 @@ */ private import semmle.code.cpp.rangeanalysis.new.internal.semantic.Semantic -private import RangeAnalysisStage private import semmle.code.cpp.rangeanalysis.new.internal.semantic.analysis.FloatDelta -private import semmle.code.cpp.rangeanalysis.new.internal.semantic.analysis.IntDelta private import RangeAnalysisImpl private import semmle.code.cpp.rangeanalysis.RangeAnalysisUtils +private import codeql.rangeanalysis.RangeAnalysis -module CppLangImplRelative implements LangSig { +module CppLangImplRelative implements LangSig { /** * Holds if the specified expression should be excluded from the result of `ssaRead()`. * diff --git a/cpp/ql/lib/semmle/code/cpp/rangeanalysis/new/internal/semantic/analysis/RangeUtils.qll b/cpp/ql/lib/semmle/code/cpp/rangeanalysis/new/internal/semantic/analysis/RangeUtils.qll index 1b5da03feecf..e3798600f85d 100644 --- a/cpp/ql/lib/semmle/code/cpp/rangeanalysis/new/internal/semantic/analysis/RangeUtils.qll +++ b/cpp/ql/lib/semmle/code/cpp/rangeanalysis/new/internal/semantic/analysis/RangeUtils.qll @@ -4,10 +4,11 @@ private import semmle.code.cpp.rangeanalysis.new.internal.semantic.Semantic private import RangeAnalysisRelativeSpecific -private import RangeAnalysisStage as Range +private import codeql.rangeanalysis.RangeAnalysis +private import RangeAnalysisImpl private import ConstantAnalysis -module RangeUtil Lang> implements Range::UtilSig { +module RangeUtil Lang> implements UtilSig { /** * Gets an expression that equals `v - d`. */ @@ -138,27 +139,33 @@ module RangeUtil Lang> implements Range::Ut or not exists(Lang::getAlternateTypeForSsaVariable(var)) and result = var.getType() } -} -/** - * Holds if `rix` is the number of input edges to `phi`. - */ -predicate maxPhiInputRank(SemSsaPhiNode phi, int rix) { - rix = max(int r | rankedPhiInput(phi, _, _, r)) + import Ranking } -/** - * Holds if `inp` is an input to `phi` along `edge` and this input has index `r` - * in an arbitrary 1-based numbering of the input edges to `phi`. - */ -predicate rankedPhiInput( - SemSsaPhiNode phi, SemSsaVariable inp, SemSsaReadPositionPhiInputEdge edge, int r -) { - edge.phiInput(phi, inp) and - edge = - rank[r](SemSsaReadPositionPhiInputEdge e | - e.phiInput(phi, _) - | - e order by e.getOrigBlock().getUniqueId() - ) +import Ranking + +module Ranking { + /** + * Holds if `rix` is the number of input edges to `phi`. + */ + predicate maxPhiInputRank(SemSsaPhiNode phi, int rix) { + rix = max(int r | rankedPhiInput(phi, _, _, r)) + } + + /** + * Holds if `inp` is an input to `phi` along `edge` and this input has index `r` + * in an arbitrary 1-based numbering of the input edges to `phi`. + */ + predicate rankedPhiInput( + SemSsaPhiNode phi, SemSsaVariable inp, SemSsaReadPositionPhiInputEdge edge, int r + ) { + edge.phiInput(phi, inp) and + edge = + rank[r](SemSsaReadPositionPhiInputEdge e | + e.phiInput(phi, _) + | + e order by e.getOrigBlock().getUniqueId() + ) + } } diff --git a/cpp/ql/lib/semmle/code/cpp/rangeanalysis/new/internal/semantic/analysis/SignAnalysisCommon.qll b/cpp/ql/lib/semmle/code/cpp/rangeanalysis/new/internal/semantic/analysis/SignAnalysisCommon.qll index 9abcdc842abb..20ada012c2a4 100644 --- a/cpp/ql/lib/semmle/code/cpp/rangeanalysis/new/internal/semantic/analysis/SignAnalysisCommon.qll +++ b/cpp/ql/lib/semmle/code/cpp/rangeanalysis/new/internal/semantic/analysis/SignAnalysisCommon.qll @@ -6,14 +6,15 @@ * three-valued domain `{negative, zero, positive}`. */ -private import RangeAnalysisStage +private import codeql.rangeanalysis.RangeAnalysis +private import RangeAnalysisImpl private import SignAnalysisSpecific as Specific private import semmle.code.cpp.rangeanalysis.new.internal.semantic.Semantic private import ConstantAnalysis private import RangeUtils private import Sign -module SignAnalysis Utils> { +module SignAnalysis Utils> { /** * An SSA definition for which the analysis can compute the sign. * @@ -507,4 +508,16 @@ module SignAnalysis Utils> { not semExprSign(e) = TPos() and not semExprSign(e) = TZero() } + + /** + * Holds if `e` may have positive values. This does not rule out the + * possibility for negative values. + */ + predicate semMayBePositive(SemExpr e) { semExprSign(e) = TPos() } + + /** + * Holds if `e` may have negative values. This does not rule out the + * possibility for positive values. + */ + predicate semMayBeNegative(SemExpr e) { semExprSign(e) = TNeg() } } diff --git a/cpp/ql/lib/semmlecode.cpp.dbscheme b/cpp/ql/lib/semmlecode.cpp.dbscheme index 5b388693c66d..f79ce79e3b75 100644 --- a/cpp/ql/lib/semmlecode.cpp.dbscheme +++ b/cpp/ql/lib/semmlecode.cpp.dbscheme @@ -197,6 +197,11 @@ svnchurn( * C++ dbscheme */ +extractor_version( + string codeql_version: string ref, + string frontend_version: string ref +) + @location = @location_stmt | @location_expr | @location_default ; /** diff --git a/cpp/ql/lib/semmlecode.cpp.dbscheme.stats b/cpp/ql/lib/semmlecode.cpp.dbscheme.stats index 66cbfef08e6b..bd755b1cba10 100644 --- a/cpp/ql/lib/semmlecode.cpp.dbscheme.stats +++ b/cpp/ql/lib/semmlecode.cpp.dbscheme.stats @@ -18,20 +18,20 @@ @location_default - 29768422 + 29753047 @location_stmt 3814079 - - @location_expr - 13167909 - @diagnostic 5200 + + @location_expr + 13167909 + @file 122996 @@ -66,7 +66,7 @@ @namespace_decl - 308610 + 308602 @using @@ -74,7 +74,7 @@ @static_assert - 133393 + 133390 @parameter @@ -82,7 +82,7 @@ @membervariable - 1053094 + 1077872 @globalvariable @@ -90,11 +90,11 @@ @localvariable - 581163 + 581158 @enumconstant - 241303 + 248647 @errortype @@ -370,7 +370,7 @@ @type_mention - 4023013 + 4060812 @routinetype @@ -394,7 +394,7 @@ @declspec - 243334 + 244509 @msattribute @@ -454,7 +454,7 @@ @initialiser - 1698635 + 1698613 @lambdacapture @@ -582,7 +582,7 @@ @geexpr - 59159 + 59287 @leexpr @@ -654,7 +654,7 @@ @subscriptexpr - 367576 + 367573 @callexpr @@ -794,7 +794,7 @@ @thisaccess - 1126162 + 1126135 @new_expr @@ -1302,7 +1302,7 @@ @stmt_empty - 193309 + 193308 @stmt_continue @@ -1310,7 +1310,7 @@ @stmt_break - 102247 + 102257 @stmt_try_block @@ -2036,7 +2036,7 @@ seconds - 9972 + 12884 @@ -2114,55 +2114,55 @@ 12 - - 2 - 3 - 39 - 3 4 - 797 + 398 4 5 - 159 + 598 - 5 + 6 8 159 - 8 + 9 10 - 159 + 79 10 + 11 + 119 + + + 11 12 - 159 + 119 - 12 - 18 + 13 + 17 159 - 18 - 22 - 159 + 17 + 18 + 79 - 22 - 55 + 20 + 27 159 - 83 - 84 - 39 + 44 + 118 + 119 @@ -2230,17 +2230,17 @@ 3 4 - 1515 + 718 4 5 - 239 + 1037 5 6 - 279 + 159 6 @@ -2250,23 +2250,28 @@ 7 8 - 79 + 159 8 9 - 239 + 159 9 - 24 + 12 279 - 24 - 91 + 13 + 42 279 + + 44 + 96 + 119 + @@ -2316,18 +2321,18 @@ 39 - 4 - 5 + 5 + 6 39 - 123 - 124 + 160 + 161 39 - 130 - 131 + 165 + 166 39 @@ -2344,12 +2349,12 @@ 1 2 - 5465 + 8018 2 3 - 2273 + 3071 3 @@ -2358,13 +2363,8 @@ 4 - 6 - 877 - - - 6 - 43 - 239 + 46 + 678 @@ -2380,32 +2380,22 @@ 1 2 - 4627 + 6901 2 3 - 2114 + 3390 3 4 - 1276 + 1755 4 - 5 - 797 - - - 5 - 7 - 917 - - - 7 - 66 - 239 + 75 + 837 @@ -2421,12 +2411,12 @@ 1 2 - 9573 + 12525 2 - 3 - 398 + 4 + 359 @@ -2770,11 +2760,11 @@ cpu_seconds - 7343 + 6938 elapsed_seconds - 146 + 134 @@ -2820,17 +2810,22 @@ 1 2 - 5982 + 5465 2 3 - 899 + 933 3 - 18 - 461 + 10 + 528 + + + 16 + 17 + 11 @@ -2846,12 +2841,12 @@ 1 2 - 6758 + 6286 2 3 - 584 + 652 @@ -2867,16 +2862,16 @@ 1 2 - 33 + 22 - 3 - 4 - 22 + 2 + 3 + 11 - 6 - 7 + 3 + 4 11 @@ -2885,33 +2880,38 @@ 11 - 14 - 15 + 9 + 10 11 - 35 - 36 + 10 + 11 11 - 144 - 145 + 33 + 34 11 - 174 - 175 + 101 + 102 11 - 225 - 226 + 185 + 186 11 - 248 - 249 + 249 + 250 + 11 + + + 261 + 262 11 @@ -2928,16 +2928,16 @@ 1 2 - 33 + 22 - 3 - 4 - 22 + 2 + 3 + 11 - 6 - 7 + 3 + 4 11 @@ -2946,33 +2946,38 @@ 11 - 14 - 15 + 9 + 10 11 - 34 - 35 + 10 + 11 11 - 124 - 125 + 32 + 33 11 - 128 - 129 + 92 + 93 11 - 159 - 160 + 135 + 136 11 - 223 - 224 + 160 + 161 + 11 + + + 222 + 223 11 @@ -4695,17 +4700,65 @@ + + extractor_version + 465 + + + codeql_version + 465 + + + frontend_version + 465 + + + + + codeql_version + frontend_version + + + 12 + + + 1 + 2 + 465 + + + + + + + frontend_version + codeql_version + + + 12 + + + 1 + 2 + 465 + + + + + + + locations_default - 29768422 + 29753047 id - 29768422 + 29753047 container - 138371 + 122996 startLine @@ -4735,7 +4788,7 @@ 1 2 - 29768422 + 29753047 @@ -4751,7 +4804,7 @@ 1 2 - 29768422 + 29753047 @@ -4767,7 +4820,7 @@ 1 2 - 29768422 + 29753047 @@ -4783,7 +4836,7 @@ 1 2 - 29768422 + 29753047 @@ -4799,7 +4852,7 @@ 1 2 - 29768422 + 29753047 @@ -4814,68 +4867,68 @@ 1 - 2 - 15840 + 11 + 9783 - 2 - 12 - 10715 + 11 + 18 + 10249 - 13 - 20 - 11647 + 18 + 30 + 9317 - 21 - 36 - 11181 + 30 + 42 + 9783 - 36 - 55 - 11181 + 43 + 61 + 9783 - 55 - 77 - 10715 + 61 + 79 + 9317 - 77 - 102 - 10715 + 80 + 106 + 9783 - 102 + 109 149 - 10715 + 9317 149 - 227 - 11181 + 199 + 9317 - 228 - 350 - 10715 + 206 + 292 + 9317 - 352 - 604 - 10715 + 305 + 469 + 9317 - 630 - 1494 - 10715 + 482 + 850 + 9317 - 1829 + 939 2380 - 2329 + 8386 @@ -4890,68 +4943,73 @@ 1 - 2 - 15840 + 8 + 9317 - 2 - 9 - 10715 + 8 + 13 + 9317 - 9 - 16 - 11647 + 13 + 20 + 9783 - 16 - 25 - 11181 + 20 + 32 + 9317 - 25 - 40 - 10715 + 32 + 43 + 9783 - 40 - 57 - 10715 + 44 + 61 + 9317 - 58 + 62 72 - 10715 + 9317 73 - 103 - 11181 + 93 + 9317 - 106 - 141 - 11647 + 97 + 128 + 9317 - 148 - 225 - 10715 + 128 + 180 + 9317 - 225 - 360 - 10715 + 180 + 267 + 9317 - 372 - 1255 - 10715 + 277 + 414 + 9317 - 1455 + 439 + 1465 + 9317 + + + 1557 1569 - 1863 + 931 @@ -4966,13 +5024,8 @@ 1 - 2 - 15840 - - - 2 4 - 8386 + 8852 4 @@ -4991,43 +5044,48 @@ 8 - 13 - 12113 + 10 + 9317 - 13 - 17 - 11181 + 10 + 15 + 10715 - 17 - 25 + 15 + 23 + 9783 + + + 23 + 28 11181 - 25 - 31 - 12113 + 28 + 34 + 9783 - 31 - 39 - 11181 + 34 + 44 + 9317 - 39 - 54 - 11181 + 44 + 55 + 9317 - 54 - 67 - 10715 + 55 + 66 + 9783 - 67 + 66 77 - 7920 + 8386 @@ -5042,68 +5100,73 @@ 1 - 2 - 15840 + 8 + 9317 - 2 - 9 - 10715 + 8 + 13 + 9317 - 9 - 16 - 11647 + 13 + 20 + 9783 - 16 - 25 - 11181 + 20 + 32 + 9317 - 25 - 40 - 10715 + 32 + 43 + 9783 - 40 - 57 - 10715 + 43 + 60 + 9317 - 58 + 61 71 - 10715 + 9317 72 - 98 - 10715 + 93 + 9317 - 101 - 140 - 11647 + 94 + 127 + 9317 - 140 - 222 - 10715 + 128 + 179 + 9317 - 223 - 360 - 11181 + 180 + 268 + 9317 - 372 - 1255 - 10715 + 278 + 413 + 9317 - 1452 + 437 + 1465 + 9317 + + + 1554 1566 - 1863 + 931 @@ -5118,58 +5181,63 @@ 1 - 2 - 15840 + 9 + 9783 - 2 - 10 - 11181 + 9 + 13 + 9317 - 10 - 14 - 10715 + 13 + 18 + 9317 - 14 - 21 - 11181 + 18 + 26 + 10249 - 22 - 31 - 11181 + 27 + 33 + 9317 - 31 + 33 39 - 12579 + 9317 39 - 48 - 12113 + 47 + 10249 - 48 - 56 - 11647 + 47 + 54 + 9317 - 56 - 64 - 12113 + 54 + 60 + 10249 - 64 - 73 - 12113 + 60 + 66 + 9317 - 73 + 66 + 74 + 9783 + + + 74 78 - 10715 + 9783 78 @@ -5234,7 +5302,7 @@ 160 - 298 + 265 11647 @@ -5285,7 +5353,7 @@ 51 - 298 + 265 74077 @@ -5464,11 +5532,11 @@ 247 - 292 + 286 2795 - 293 + 291 360 2795 @@ -5585,7 +5653,7 @@ 195 - 298 + 265 1397 @@ -5884,7 +5952,7 @@ 160 - 298 + 265 11181 @@ -5940,7 +6008,7 @@ 121 - 298 + 265 11647 @@ -6119,11 +6187,11 @@ 193 - 295 + 288 3727 - 297 + 294 495 3727 @@ -6240,7 +6308,7 @@ 207 - 298 + 265 1397 @@ -12259,7 +12327,7 @@ 2 3 - 543313 + 543317 3 @@ -12294,7 +12362,7 @@ 11 337 - 224533 + 224529 339 @@ -14030,11 +14098,11 @@ purefunctions - 99971 + 99968 id - 99971 + 99968 @@ -16166,11 +16234,11 @@ namespace_decls - 308610 + 308602 id - 308610 + 308602 namespace_id @@ -16178,11 +16246,11 @@ location - 308610 + 308602 bodylocation - 308610 + 308602 @@ -16196,7 +16264,7 @@ 1 2 - 308610 + 308602 @@ -16212,7 +16280,7 @@ 1 2 - 308610 + 308602 @@ -16228,7 +16296,7 @@ 1 2 - 308610 + 308602 @@ -16442,7 +16510,7 @@ 1 2 - 308610 + 308602 @@ -16458,7 +16526,7 @@ 1 2 - 308610 + 308602 @@ -16474,7 +16542,7 @@ 1 2 - 308610 + 308602 @@ -16490,7 +16558,7 @@ 1 2 - 308610 + 308602 @@ -16506,7 +16574,7 @@ 1 2 - 308610 + 308602 @@ -16522,7 +16590,7 @@ 1 2 - 308610 + 308602 @@ -16801,19 +16869,19 @@ static_asserts - 133393 + 133390 id - 133393 + 133390 condition - 133393 + 133390 message - 29938 + 29937 location @@ -16821,7 +16889,7 @@ enclosing - 4603 + 4602 @@ -16835,7 +16903,7 @@ 1 2 - 133393 + 133390 @@ -16851,7 +16919,7 @@ 1 2 - 133393 + 133390 @@ -16867,7 +16935,7 @@ 1 2 - 133393 + 133390 @@ -16883,7 +16951,7 @@ 1 2 - 133393 + 133390 @@ -16899,7 +16967,7 @@ 1 2 - 133393 + 133390 @@ -16915,7 +16983,7 @@ 1 2 - 133393 + 133390 @@ -16931,7 +16999,7 @@ 1 2 - 133393 + 133390 @@ -16947,7 +17015,7 @@ 1 2 - 133393 + 133390 @@ -17081,7 +17149,7 @@ 4 12 - 1440 + 1439 12 @@ -17255,12 +17323,12 @@ 1 2 - 3861 + 3860 2 3 - 6219 + 6218 3 @@ -17368,7 +17436,7 @@ 2 3 - 371 + 370 3 @@ -17905,15 +17973,15 @@ overrides - 159848 + 159844 new - 125042 + 125039 old - 15098 + 15097 @@ -17927,12 +17995,12 @@ 1 2 - 90243 + 90240 2 3 - 34793 + 34792 3 @@ -17993,19 +18061,19 @@ membervariables - 1054889 + 1079662 id - 1053094 + 1077872 type_id - 327229 + 331092 name - 450932 + 462559 @@ -18019,12 +18087,12 @@ 1 2 - 1051379 + 1076161 2 4 - 1715 + 1710 @@ -18040,7 +18108,7 @@ 1 2 - 1053094 + 1077872 @@ -18056,22 +18124,22 @@ 1 2 - 242659 + 245663 2 3 - 51818 + 52443 3 10 - 25490 + 25664 10 - 4152 - 7260 + 4335 + 7321 @@ -18087,22 +18155,22 @@ 1 2 - 254866 + 258157 2 3 - 46393 + 46832 3 - 40 - 24573 + 46 + 24908 - 41 - 2031 - 1396 + 48 + 2128 + 1193 @@ -18118,22 +18186,22 @@ 1 2 - 294877 + 303956 2 3 - 86404 + 87657 3 5 - 41128 + 41739 5 - 646 - 28522 + 653 + 29205 @@ -18149,17 +18217,17 @@ 1 2 - 367280 + 377607 2 3 - 51659 + 52483 3 - 650 - 31992 + 657 + 32468 @@ -18340,11 +18408,11 @@ localvariables - 581163 + 581158 id - 581163 + 581158 type_id @@ -18366,7 +18434,7 @@ 1 2 - 581163 + 581158 @@ -18382,7 +18450,7 @@ 1 2 - 581163 + 581158 @@ -18403,7 +18471,7 @@ 2 3 - 5412 + 5408 3 @@ -18413,7 +18481,7 @@ 4 7 - 3405 + 3409 7 @@ -18423,7 +18491,7 @@ 18 15847 - 2511 + 2510 @@ -18439,7 +18507,7 @@ 1 2 - 26974 + 26970 2 @@ -18449,7 +18517,7 @@ 3 5 - 2939 + 2943 5 @@ -18511,7 +18579,7 @@ 1 2 - 77144 + 77143 2 @@ -18652,19 +18720,19 @@ enumconstants - 241303 + 248647 id - 241303 + 248647 parent - 28482 + 29683 index - 10212 + 10186 type_id @@ -18672,11 +18740,11 @@ name - 241024 + 248369 location - 221237 + 228633 @@ -18690,7 +18758,7 @@ 1 2 - 241303 + 248647 @@ -18706,7 +18774,7 @@ 1 2 - 241303 + 248647 @@ -18722,7 +18790,7 @@ 1 2 - 241303 + 248647 @@ -18738,7 +18806,7 @@ 1 2 - 241303 + 248647 @@ -18754,7 +18822,7 @@ 1 2 - 241303 + 248647 @@ -18770,57 +18838,57 @@ 1 2 - 997 + 1114 2 3 - 4029 + 4177 3 4 - 5784 + 6087 4 5 - 3909 + 4058 5 6 - 3071 + 3262 6 7 - 1835 + 1870 7 8 - 1475 + 1432 8 - 11 - 2592 + 10 + 2148 - 11 - 17 - 2353 + 10 + 15 + 2387 - 17 - 84 - 2154 + 15 + 34 + 2307 - 94 + 35 257 - 279 + 835 @@ -18836,57 +18904,57 @@ 1 2 - 997 + 1114 2 3 - 4029 + 4177 3 4 - 5784 + 6087 4 5 - 3909 + 4058 5 6 - 3071 + 3262 6 7 - 1835 + 1870 7 8 - 1475 + 1432 8 - 11 - 2592 + 10 + 2148 - 11 - 17 - 2353 + 10 + 15 + 2387 - 17 - 84 - 2154 + 15 + 34 + 2307 - 94 + 35 257 - 279 + 835 @@ -18902,7 +18970,7 @@ 1 2 - 28482 + 29683 @@ -18918,57 +18986,57 @@ 1 2 - 997 + 1114 2 3 - 4029 + 4177 3 4 - 5784 + 6087 4 5 - 3909 + 4058 5 6 - 3071 + 3262 6 7 - 1835 + 1870 7 8 - 1475 + 1432 8 - 11 - 2592 + 10 + 2148 - 11 - 17 - 2353 + 10 + 15 + 2387 - 17 - 84 - 2154 + 15 + 34 + 2307 - 94 + 35 257 - 279 + 835 @@ -18984,52 +19052,52 @@ 1 2 - 1436 + 1551 2 3 - 4188 + 4337 3 4 - 5824 + 6127 4 5 - 3869 + 4018 5 6 - 3071 + 3262 6 7 - 1795 + 1830 7 8 - 1396 + 1352 8 11 - 2513 + 2705 11 - 17 - 2233 + 18 + 2268 - 17 + 18 257 - 2154 + 2228 @@ -19045,47 +19113,47 @@ 1 2 - 2034 + 2029 2 3 - 1635 + 1631 3 4 - 1755 + 1750 4 5 - 877 + 835 5 9 - 797 + 795 9 12 - 837 + 875 12 20 - 877 + 835 20 - 69 - 797 + 66 + 795 - 77 - 715 - 598 + 70 + 747 + 636 @@ -19101,47 +19169,47 @@ 1 2 - 2034 + 2029 2 3 - 1635 + 1631 3 4 - 1755 + 1750 4 5 - 877 + 835 5 9 - 797 + 795 9 12 - 837 + 875 12 20 - 877 + 835 20 - 69 - 797 + 66 + 795 - 77 - 715 - 598 + 70 + 747 + 636 @@ -19157,7 +19225,7 @@ 1 2 - 10212 + 10186 @@ -19173,47 +19241,47 @@ 1 2 - 2034 + 2029 2 3 - 1635 + 1631 3 4 - 1755 + 1750 4 5 - 877 + 835 5 9 - 797 + 795 9 12 - 837 + 875 12 20 - 877 + 835 20 - 69 - 797 + 66 + 795 - 77 - 712 - 598 + 70 + 744 + 636 @@ -19229,47 +19297,47 @@ 1 2 - 2034 + 2029 2 3 - 1635 + 1631 3 4 - 1755 + 1750 4 5 - 877 + 835 5 9 - 797 + 795 9 12 - 837 + 875 12 20 - 877 + 835 20 - 69 - 797 + 66 + 795 - 77 - 715 - 598 + 70 + 747 + 636 @@ -19283,8 +19351,8 @@ 12 - 6049 - 6050 + 6249 + 6250 39 @@ -19299,8 +19367,8 @@ 12 - 714 - 715 + 746 + 747 39 @@ -19331,8 +19399,8 @@ 12 - 6042 - 6043 + 6242 + 6243 39 @@ -19347,8 +19415,8 @@ 12 - 5546 - 5547 + 5746 + 5747 39 @@ -19365,12 +19433,12 @@ 1 2 - 240744 + 248090 2 3 - 279 + 278 @@ -19386,12 +19454,12 @@ 1 2 - 240744 + 248090 2 3 - 279 + 278 @@ -19407,7 +19475,7 @@ 1 2 - 241024 + 248369 @@ -19423,7 +19491,7 @@ 1 2 - 241024 + 248369 @@ -19439,12 +19507,12 @@ 1 2 - 240744 + 248090 2 3 - 279 + 278 @@ -19460,12 +19528,12 @@ 1 2 - 220480 + 227877 2 205 - 757 + 756 @@ -19481,7 +19549,7 @@ 1 2 - 221237 + 228633 @@ -19497,12 +19565,12 @@ 1 2 - 220480 + 227877 2 205 - 757 + 756 @@ -19518,7 +19586,7 @@ 1 2 - 221237 + 228633 @@ -19534,12 +19602,12 @@ 1 2 - 220480 + 227877 2 205 - 757 + 756 @@ -21924,7 +21992,7 @@ 2 3 - 371 + 370 @@ -22579,19 +22647,19 @@ type_mentions - 4023013 + 4060812 id - 4023013 + 4060812 type_id - 197901 + 200223 location - 3989544 + 4027428 kind @@ -22609,7 +22677,7 @@ 1 2 - 4023013 + 4060812 @@ -22625,7 +22693,7 @@ 1 2 - 4023013 + 4060812 @@ -22641,7 +22709,7 @@ 1 2 - 4023013 + 4060812 @@ -22657,42 +22725,42 @@ 1 2 - 97454 + 98918 2 3 - 21700 + 22322 3 4 - 8217 + 8196 4 5 - 10770 + 10663 5 7 - 14360 + 14642 7 12 - 15836 + 15876 12 27 - 15158 + 15160 27 - 8555 - 14400 + 8808 + 14443 @@ -22708,42 +22776,42 @@ 1 2 - 97454 + 98918 2 3 - 21700 + 22322 3 4 - 8217 + 8196 4 5 - 10770 + 10663 5 7 - 14360 + 14642 7 12 - 15836 + 15876 12 27 - 15158 + 15160 27 - 8555 - 14400 + 8808 + 14443 @@ -22759,7 +22827,7 @@ 1 2 - 197901 + 200223 @@ -22775,12 +22843,12 @@ 1 2 - 3956075 + 3994044 2 3 - 33468 + 33383 @@ -22796,12 +22864,12 @@ 1 2 - 3956075 + 3994044 2 3 - 33468 + 33383 @@ -22817,7 +22885,7 @@ 1 2 - 3989544 + 4027428 @@ -22831,8 +22899,8 @@ 12 - 100849 - 100850 + 102056 + 102057 39 @@ -22847,8 +22915,8 @@ 12 - 4961 - 4962 + 5032 + 5033 39 @@ -22863,8 +22931,8 @@ 12 - 100010 - 100011 + 101217 + 101218 39 @@ -24603,11 +24671,11 @@ funspecifiers - 12754043 + 12754079 func_id - 3899573 + 3899608 spec_id @@ -24625,7 +24693,7 @@ 1 2 - 314396 + 314431 2 @@ -24739,8 +24807,8 @@ 35 - 77764 - 77765 + 77765 + 77766 35 @@ -28309,11 +28377,11 @@ compgenerated - 8403048 + 9138729 id - 8403048 + 9138729 @@ -29654,7 +29722,7 @@ fun - 533151 + 533132 @@ -29689,12 +29757,12 @@ 1 2 - 329366 + 329327 2 3 - 82059 + 82079 3 @@ -30325,19 +30393,19 @@ fieldoffsets - 1053094 + 1077872 id - 1053094 + 1077872 byteoffset - 22658 + 22879 bitoffset - 319 + 318 @@ -30351,7 +30419,7 @@ 1 2 - 1053094 + 1077872 @@ -30367,7 +30435,7 @@ 1 2 - 1053094 + 1077872 @@ -30383,37 +30451,37 @@ 1 2 - 13004 + 12891 2 3 - 1715 + 1790 3 5 - 1795 + 1949 5 12 - 1914 + 1949 12 35 - 1715 + 1750 35 - 205 - 1715 + 209 + 1750 - 244 - 5638 - 797 + 248 + 5836 + 795 @@ -30429,12 +30497,12 @@ 1 2 - 21980 + 22202 2 9 - 678 + 676 @@ -30448,43 +30516,43 @@ 12 - 29 - 30 + 31 + 32 39 - 30 - 31 + 32 + 33 39 - 33 - 34 + 37 + 38 39 - 36 - 37 + 43 + 44 39 - 42 - 43 + 46 + 47 39 - 43 - 44 + 53 + 54 39 - 55 - 56 + 68 + 69 39 - 26131 - 26132 + 26779 + 26780 39 @@ -30501,7 +30569,7 @@ 11 12 - 159 + 119 12 @@ -30511,11 +30579,11 @@ 13 14 - 39 + 79 - 568 - 569 + 575 + 576 39 @@ -30712,23 +30780,23 @@ initialisers - 1698635 + 1698613 init - 1698635 + 1698613 var - 722109 + 722110 expr - 1698635 + 1698613 location - 390823 + 390813 @@ -30742,7 +30810,7 @@ 1 2 - 1698635 + 1698613 @@ -30758,7 +30826,7 @@ 1 2 - 1698635 + 1698613 @@ -30774,7 +30842,7 @@ 1 2 - 1698635 + 1698613 @@ -30790,17 +30858,17 @@ 1 2 - 633984 + 633988 2 16 - 31466 + 31465 16 25 - 56657 + 56656 @@ -30816,17 +30884,17 @@ 1 2 - 633984 + 633988 2 16 - 31466 + 31465 16 25 - 56657 + 56656 @@ -30842,7 +30910,7 @@ 1 2 - 722102 + 722104 2 @@ -30863,7 +30931,7 @@ 1 2 - 1698635 + 1698613 @@ -30879,7 +30947,7 @@ 1 2 - 1698635 + 1698613 @@ -30895,7 +30963,7 @@ 1 2 - 1698635 + 1698613 @@ -30911,17 +30979,17 @@ 1 2 - 318451 + 318443 2 3 - 23851 + 23850 3 15 - 30680 + 30679 15 @@ -30942,12 +31010,12 @@ 1 2 - 341120 + 341112 2 4 - 35642 + 35641 4 @@ -30968,17 +31036,17 @@ 1 2 - 318451 + 318443 2 3 - 23851 + 23850 3 15 - 30680 + 30679 15 @@ -31346,7 +31414,7 @@ typeid - 1244631 + 1244642 value_category @@ -31411,32 +31479,32 @@ 3 4 - 103287 + 103298 4 5 - 84777 + 84788 5 8 - 111125 + 111102 8 14 - 99171 + 99182 14 42 - 94099 + 94111 42 125383 - 43226 + 43215 @@ -31452,7 +31520,7 @@ 1 2 - 1075930 + 1075941 2 @@ -31512,8 +31580,8 @@ 11 - 93013 - 93014 + 93014 + 93015 11 @@ -32806,7 +32874,7 @@ 1 2 - 19745 + 19744 2 @@ -35297,11 +35365,11 @@ stmtparents - 4053171 + 4053248 id - 4053171 + 4053248 index @@ -35309,7 +35377,7 @@ parent - 1719896 + 1719942 @@ -35323,7 +35391,7 @@ 1 2 - 4053171 + 4053248 @@ -35339,7 +35407,7 @@ 1 2 - 4053171 + 4053248 @@ -35399,7 +35467,7 @@ 77 - 196965 + 196973 697 @@ -35460,7 +35528,7 @@ 77 - 196965 + 196973 697 @@ -35477,27 +35545,27 @@ 1 2 - 987613 + 987639 2 3 - 373033 + 373043 3 4 - 105762 + 105766 4 6 - 111258 + 111262 6 17 - 129865 + 129868 17 @@ -35518,27 +35586,27 @@ 1 2 - 987613 + 987639 2 3 - 373033 + 373043 3 4 - 105762 + 105766 4 6 - 111258 + 111262 6 17 - 129865 + 129868 17 @@ -35564,11 +35632,11 @@ stmt_decl_bind - 585093 + 585089 stmt - 544980 + 544976 num @@ -35576,7 +35644,7 @@ decl - 584988 + 584984 @@ -35590,7 +35658,7 @@ 1 2 - 524119 + 524115 2 @@ -35611,7 +35679,7 @@ 1 2 - 524119 + 524115 2 @@ -35814,7 +35882,7 @@ 1 2 - 584950 + 584946 2 @@ -35835,7 +35903,7 @@ 1 2 - 584988 + 584984 @@ -35845,11 +35913,11 @@ stmt_decl_entry_bind - 527554 + 527550 stmt - 487743 + 487740 num @@ -35857,7 +35925,7 @@ decl_entry - 527495 + 527491 @@ -35871,12 +35939,12 @@ 1 2 - 467147 + 467144 2 19 - 20596 + 20595 @@ -35892,12 +35960,12 @@ 1 2 - 467147 + 467144 2 19 - 20596 + 20595 @@ -36095,7 +36163,7 @@ 1 2 - 527474 + 527470 3 @@ -36116,7 +36184,7 @@ 1 2 - 527495 + 527491 @@ -36923,11 +36991,11 @@ link_parent - 39330305 + 39330622 element - 4985174 + 4985209 link_target @@ -36955,7 +37023,7 @@ 9 10 - 4286883 + 4286918 @@ -36974,48 +37042,48 @@ 35 - 121945 - 121946 + 121946 + 121947 35 - 122057 - 122058 + 122058 + 122059 35 - 122156 - 122157 + 122157 + 122158 35 - 122187 - 122188 + 122188 + 122189 35 - 122199 - 122200 + 122200 + 122201 35 - 122216 - 122217 + 122217 + 122218 35 - 124216 - 124217 + 124217 + 124218 35 - 128870 - 128871 + 128871 + 128872 35 - 131274 - 131275 + 131275 + 131276 35 diff --git a/cpp/ql/lib/upgrades/5b388693c66db1e7dc2e76a90aa67a2b6eb74f0f/old.dbscheme b/cpp/ql/lib/upgrades/5b388693c66db1e7dc2e76a90aa67a2b6eb74f0f/old.dbscheme new file mode 100644 index 000000000000..5b388693c66d --- /dev/null +++ b/cpp/ql/lib/upgrades/5b388693c66db1e7dc2e76a90aa67a2b6eb74f0f/old.dbscheme @@ -0,0 +1,2221 @@ + +/** + * An invocation of the compiler. Note that more than one file may be + * compiled per invocation. For example, this command compiles three + * source files: + * + * gcc -c f1.c f2.c f3.c + * + * The `id` simply identifies the invocation, while `cwd` is the working + * directory from which the compiler was invoked. + */ +compilations( + /** + * An invocation of the compiler. Note that more than one file may + * be compiled per invocation. For example, this command compiles + * three source files: + * + * gcc -c f1.c f2.c f3.c + */ + unique int id : @compilation, + string cwd : string ref +); + +/** + * The arguments that were passed to the extractor for a compiler + * invocation. If `id` is for the compiler invocation + * + * gcc -c f1.c f2.c f3.c + * + * then typically there will be rows for + * + * num | arg + * --- | --- + * 0 | *path to extractor* + * 1 | `--mimic` + * 2 | `/usr/bin/gcc` + * 3 | `-c` + * 4 | f1.c + * 5 | f2.c + * 6 | f3.c + */ +#keyset[id, num] +compilation_args( + int id : @compilation ref, + int num : int ref, + string arg : string ref +); + +/** + * The source files that are compiled by a compiler invocation. + * If `id` is for the compiler invocation + * + * gcc -c f1.c f2.c f3.c + * + * then there will be rows for + * + * num | arg + * --- | --- + * 0 | f1.c + * 1 | f2.c + * 2 | f3.c + * + * Note that even if those files `#include` headers, those headers + * do not appear as rows. + */ +#keyset[id, num] +compilation_compiling_files( + int id : @compilation ref, + int num : int ref, + int file : @file ref +); + +/** + * The time taken by the extractor for a compiler invocation. + * + * For each file `num`, there will be rows for + * + * kind | seconds + * ---- | --- + * 1 | CPU seconds used by the extractor frontend + * 2 | Elapsed seconds during the extractor frontend + * 3 | CPU seconds used by the extractor backend + * 4 | Elapsed seconds during the extractor backend + */ +#keyset[id, num, kind] +compilation_time( + int id : @compilation ref, + int num : int ref, + /* kind: + 1 = frontend_cpu_seconds + 2 = frontend_elapsed_seconds + 3 = extractor_cpu_seconds + 4 = extractor_elapsed_seconds + */ + int kind : int ref, + float seconds : float ref +); + +/** + * An error or warning generated by the extractor. + * The diagnostic message `diagnostic` was generated during compiler + * invocation `compilation`, and is the `file_number_diagnostic_number`th + * message generated while extracting the `file_number`th file of that + * invocation. + */ +#keyset[compilation, file_number, file_number_diagnostic_number] +diagnostic_for( + int diagnostic : @diagnostic ref, + int compilation : @compilation ref, + int file_number : int ref, + int file_number_diagnostic_number : int ref +); + +/** + * If extraction was successful, then `cpu_seconds` and + * `elapsed_seconds` are the CPU time and elapsed time (respectively) + * that extraction took for compiler invocation `id`. + */ +compilation_finished( + unique int id : @compilation ref, + float cpu_seconds : float ref, + float elapsed_seconds : float ref +); + + +/** + * External data, loaded from CSV files during snapshot creation. See + * [Tutorial: Incorporating external data](https://help.semmle.com/wiki/display/SD/Tutorial%3A+Incorporating+external+data) + * for more information. + */ +externalData( + int id : @externalDataElement, + string path : string ref, + int column: int ref, + string value : string ref +); + +/** + * The source location of the snapshot. + */ +sourceLocationPrefix(string prefix : string ref); + +/** + * Information about packages that provide code used during compilation. + * The `id` is just a unique identifier. + * The `namespace` is typically the name of the package manager that + * provided the package (e.g. "dpkg" or "yum"). + * The `package_name` is the name of the package, and `version` is its + * version (as a string). + */ +external_packages( + unique int id: @external_package, + string namespace : string ref, + string package_name : string ref, + string version : string ref +); + +/** + * Holds if File `fileid` was provided by package `package`. + */ +header_to_external_package( + int fileid : @file ref, + int package : @external_package ref +); + +/* + * Version history + */ + +svnentries( + unique int id : @svnentry, + string revision : string ref, + string author : string ref, + date revisionDate : date ref, + int changeSize : int ref +) + +svnaffectedfiles( + int id : @svnentry ref, + int file : @file ref, + string action : string ref +) + +svnentrymsg( + unique int id : @svnentry ref, + string message : string ref +) + +svnchurn( + int commit : @svnentry ref, + int file : @file ref, + int addedLines : int ref, + int deletedLines : int ref +) + +/* + * C++ dbscheme + */ + +@location = @location_stmt | @location_expr | @location_default ; + +/** + * The location of an element that is not an expression or a statement. + * The location spans column `startcolumn` of line `startline` to + * column `endcolumn` of line `endline` in file `file`. + * For more information, see + * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). + */ +locations_default( + /** The location of an element that is not an expression or a statement. */ + unique int id: @location_default, + int container: @container ref, + int startLine: int ref, + int startColumn: int ref, + int endLine: int ref, + int endColumn: int ref +); + +/** + * The location of a statement. + * The location spans column `startcolumn` of line `startline` to + * column `endcolumn` of line `endline` in file `file`. + * For more information, see + * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). + */ +locations_stmt( + /** The location of a statement. */ + unique int id: @location_stmt, + int container: @container ref, + int startLine: int ref, + int startColumn: int ref, + int endLine: int ref, + int endColumn: int ref +); + +/** + * The location of an expression. + * The location spans column `startcolumn` of line `startline` to + * column `endcolumn` of line `endline` in file `file`. + * For more information, see + * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). + */ +locations_expr( + /** The location of an expression. */ + unique int id: @location_expr, + int container: @container ref, + int startLine: int ref, + int startColumn: int ref, + int endLine: int ref, + int endColumn: int ref +); + +/** An element for which line-count information is available. */ +@sourceline = @file | @function | @variable | @enumconstant | @xmllocatable; + +numlines( + int element_id: @sourceline ref, + int num_lines: int ref, + int num_code: int ref, + int num_comment: int ref +); + +diagnostics( + unique int id: @diagnostic, + int severity: int ref, + string error_tag: string ref, + string error_message: string ref, + string full_error_message: string ref, + int location: @location_default ref +); + +files( + unique int id: @file, + string name: string ref +); + +folders( + unique int id: @folder, + string name: string ref +); + +@container = @folder | @file + +containerparent( + int parent: @container ref, + unique int child: @container ref +); + +fileannotations( + int id: @file ref, + int kind: int ref, + string name: string ref, + string value: string ref +); + +inmacroexpansion( + int id: @element ref, + int inv: @macroinvocation ref +); + +affectedbymacroexpansion( + int id: @element ref, + int inv: @macroinvocation ref +); + +case @macroinvocation.kind of + 1 = @macro_expansion +| 2 = @other_macro_reference +; + +macroinvocations( + unique int id: @macroinvocation, + int macro_id: @ppd_define ref, + int location: @location_default ref, + int kind: int ref +); + +macroparent( + unique int id: @macroinvocation ref, + int parent_id: @macroinvocation ref +); + +// a macroinvocation may be part of another location +// the way to find a constant expression that uses a macro +// is thus to find a constant expression that has a location +// to which a macro invocation is bound +macrolocationbind( + int id: @macroinvocation ref, + int location: @location ref +); + +#keyset[invocation, argument_index] +macro_argument_unexpanded( + int invocation: @macroinvocation ref, + int argument_index: int ref, + string text: string ref +); + +#keyset[invocation, argument_index] +macro_argument_expanded( + int invocation: @macroinvocation ref, + int argument_index: int ref, + string text: string ref +); + +/* +case @function.kind of + 1 = @normal_function +| 2 = @constructor +| 3 = @destructor +| 4 = @conversion_function +| 5 = @operator +| 6 = @builtin_function // GCC built-in functions, e.g. __builtin___memcpy_chk +; +*/ + +functions( + unique int id: @function, + string name: string ref, + int kind: int ref +); + +function_entry_point( + int id: @function ref, + unique int entry_point: @stmt ref +); + +function_return_type( + int id: @function ref, + int return_type: @type ref +); + +/** + * If `function` is a coroutine, then this gives the `std::experimental::resumable_traits` + * instance associated with it, and the variables representing the `handle` and `promise` + * for it. + */ +coroutine( + unique int function: @function ref, + int traits: @type ref, + int handle: @variable ref, + int promise: @variable ref +); + +/** The `new` function used for allocating the coroutine state, if any. */ +coroutine_new( + unique int function: @function ref, + int new: @function ref +); + +/** The `delete` function used for deallocating the coroutine state, if any. */ +coroutine_delete( + unique int function: @function ref, + int delete: @function ref +); + +purefunctions(unique int id: @function ref); + +function_deleted(unique int id: @function ref); + +function_defaulted(unique int id: @function ref); + +member_function_this_type( + unique int id: @function ref, + int this_type: @type ref +); + +#keyset[id, type_id] +fun_decls( + int id: @fun_decl, + int function: @function ref, + int type_id: @type ref, + string name: string ref, + int location: @location_default ref +); +fun_def(unique int id: @fun_decl ref); +fun_specialized(unique int id: @fun_decl ref); +fun_implicit(unique int id: @fun_decl ref); +fun_decl_specifiers( + int id: @fun_decl ref, + string name: string ref +) +#keyset[fun_decl, index] +fun_decl_throws( + int fun_decl: @fun_decl ref, + int index: int ref, + int type_id: @type ref +); +/* an empty throw specification is different from none */ +fun_decl_empty_throws(unique int fun_decl: @fun_decl ref); +fun_decl_noexcept( + int fun_decl: @fun_decl ref, + int constant: @expr ref +); +fun_decl_empty_noexcept(int fun_decl: @fun_decl ref); +fun_decl_typedef_type( + unique int fun_decl: @fun_decl ref, + int typedeftype_id: @usertype ref +); + +param_decl_bind( + unique int id: @var_decl ref, + int index: int ref, + int fun_decl: @fun_decl ref +); + +#keyset[id, type_id] +var_decls( + int id: @var_decl, + int variable: @variable ref, + int type_id: @type ref, + string name: string ref, + int location: @location_default ref +); +var_def(unique int id: @var_decl ref); +var_decl_specifiers( + int id: @var_decl ref, + string name: string ref +) +is_structured_binding(unique int id: @variable ref); + +type_decls( + unique int id: @type_decl, + int type_id: @type ref, + int location: @location_default ref +); +type_def(unique int id: @type_decl ref); +type_decl_top( + unique int type_decl: @type_decl ref +); + +namespace_decls( + unique int id: @namespace_decl, + int namespace_id: @namespace ref, + int location: @location_default ref, + int bodylocation: @location_default ref +); + +usings( + unique int id: @using, + int element_id: @element ref, + int location: @location_default ref +); + +/** The element which contains the `using` declaration. */ +using_container( + int parent: @element ref, + int child: @using ref +); + +static_asserts( + unique int id: @static_assert, + int condition : @expr ref, + string message : string ref, + int location: @location_default ref, + int enclosing : @element ref +); + +// each function has an ordered list of parameters +#keyset[id, type_id] +#keyset[function, index, type_id] +params( + int id: @parameter, + int function: @functionorblock ref, + int index: int ref, + int type_id: @type ref +); + +overrides( + int new: @function ref, + int old: @function ref +); + +#keyset[id, type_id] +membervariables( + int id: @membervariable, + int type_id: @type ref, + string name: string ref +); + +#keyset[id, type_id] +globalvariables( + int id: @globalvariable, + int type_id: @type ref, + string name: string ref +); + +#keyset[id, type_id] +localvariables( + int id: @localvariable, + int type_id: @type ref, + string name: string ref +); + +autoderivation( + unique int var: @variable ref, + int derivation_type: @type ref +); + +orphaned_variables( + int var: @localvariable ref, + int function: @function ref +) + +enumconstants( + unique int id: @enumconstant, + int parent: @usertype ref, + int index: int ref, + int type_id: @type ref, + string name: string ref, + int location: @location_default ref +); + +@variable = @localscopevariable | @globalvariable | @membervariable; + +@localscopevariable = @localvariable | @parameter; + +/** + * Built-in types are the fundamental types, e.g., integral, floating, and void. + */ +case @builtintype.kind of + 1 = @errortype +| 2 = @unknowntype +| 3 = @void +| 4 = @boolean +| 5 = @char +| 6 = @unsigned_char +| 7 = @signed_char +| 8 = @short +| 9 = @unsigned_short +| 10 = @signed_short +| 11 = @int +| 12 = @unsigned_int +| 13 = @signed_int +| 14 = @long +| 15 = @unsigned_long +| 16 = @signed_long +| 17 = @long_long +| 18 = @unsigned_long_long +| 19 = @signed_long_long +// ... 20 Microsoft-specific __int8 +// ... 21 Microsoft-specific __int16 +// ... 22 Microsoft-specific __int32 +// ... 23 Microsoft-specific __int64 +| 24 = @float +| 25 = @double +| 26 = @long_double +| 27 = @complex_float // C99-specific _Complex float +| 28 = @complex_double // C99-specific _Complex double +| 29 = @complex_long_double // C99-specific _Complex long double +| 30 = @imaginary_float // C99-specific _Imaginary float +| 31 = @imaginary_double // C99-specific _Imaginary double +| 32 = @imaginary_long_double // C99-specific _Imaginary long double +| 33 = @wchar_t // Microsoft-specific +| 34 = @decltype_nullptr // C++11 +| 35 = @int128 // __int128 +| 36 = @unsigned_int128 // unsigned __int128 +| 37 = @signed_int128 // signed __int128 +| 38 = @float128 // __float128 +| 39 = @complex_float128 // _Complex __float128 +| 40 = @decimal32 // _Decimal32 +| 41 = @decimal64 // _Decimal64 +| 42 = @decimal128 // _Decimal128 +| 43 = @char16_t +| 44 = @char32_t +| 45 = @std_float32 // _Float32 +| 46 = @float32x // _Float32x +| 47 = @std_float64 // _Float64 +| 48 = @float64x // _Float64x +| 49 = @std_float128 // _Float128 +// ... 50 _Float128x +| 51 = @char8_t +| 52 = @float16 // _Float16 +| 53 = @complex_float16 // _Complex _Float16 +| 54 = @fp16 // __fp16 +| 55 = @std_bfloat16 // __bf16 +| 56 = @std_float16 // std::float16_t +| 57 = @complex_std_float32 // _Complex _Float32 +| 58 = @complex_float32x // _Complex _Float32x +| 59 = @complex_std_float64 // _Complex _Float64 +| 60 = @complex_float64x // _Complex _Float64x +| 61 = @complex_std_float128 // _Complex _Float128 +; + +builtintypes( + unique int id: @builtintype, + string name: string ref, + int kind: int ref, + int size: int ref, + int sign: int ref, + int alignment: int ref +); + +/** + * Derived types are types that are directly derived from existing types and + * point to, refer to, transform type data to return a new type. + */ +case @derivedtype.kind of + 1 = @pointer +| 2 = @reference +| 3 = @type_with_specifiers +| 4 = @array +| 5 = @gnu_vector +| 6 = @routineptr +| 7 = @routinereference +| 8 = @rvalue_reference // C++11 +// ... 9 type_conforming_to_protocols deprecated +| 10 = @block +; + +derivedtypes( + unique int id: @derivedtype, + string name: string ref, + int kind: int ref, + int type_id: @type ref +); + +pointerishsize(unique int id: @derivedtype ref, + int size: int ref, + int alignment: int ref); + +arraysizes( + unique int id: @derivedtype ref, + int num_elements: int ref, + int bytesize: int ref, + int alignment: int ref +); + +typedefbase( + unique int id: @usertype ref, + int type_id: @type ref +); + +/** + * An instance of the C++11 `decltype` operator. For example: + * ``` + * int a; + * decltype(1+a) b; + * ``` + * Here `expr` is `1+a`. + * + * Sometimes an additional pair of parentheses around the expression + * would change the semantics of this decltype, e.g. + * ``` + * struct A { double x; }; + * const A* a = new A(); + * decltype( a->x ); // type is double + * decltype((a->x)); // type is const double& + * ``` + * (Please consult the C++11 standard for more details). + * `parentheses_would_change_meaning` is `true` iff that is the case. + */ +#keyset[id, expr] +decltypes( + int id: @decltype, + int expr: @expr ref, + int base_type: @type ref, + boolean parentheses_would_change_meaning: boolean ref +); + +/* +case @usertype.kind of + 1 = @struct +| 2 = @class +| 3 = @union +| 4 = @enum +| 5 = @typedef // classic C: typedef typedef type name +| 6 = @template +| 7 = @template_parameter +| 8 = @template_template_parameter +| 9 = @proxy_class // a proxy class associated with a template parameter +// ... 10 objc_class deprecated +// ... 11 objc_protocol deprecated +// ... 12 objc_category deprecated +| 13 = @scoped_enum +| 14 = @using_alias // a using name = type style typedef +; +*/ + +usertypes( + unique int id: @usertype, + string name: string ref, + int kind: int ref +); + +usertypesize( + unique int id: @usertype ref, + int size: int ref, + int alignment: int ref +); + +usertype_final(unique int id: @usertype ref); + +usertype_uuid( + unique int id: @usertype ref, + string uuid: string ref +); + +mangled_name( + unique int id: @declaration ref, + int mangled_name : @mangledname +); + +is_pod_class(unique int id: @usertype ref); +is_standard_layout_class(unique int id: @usertype ref); + +is_complete(unique int id: @usertype ref); + +is_class_template(unique int id: @usertype ref); +class_instantiation( + int to: @usertype ref, + int from: @usertype ref +); +class_template_argument( + int type_id: @usertype ref, + int index: int ref, + int arg_type: @type ref +); +class_template_argument_value( + int type_id: @usertype ref, + int index: int ref, + int arg_value: @expr ref +); + +is_proxy_class_for( + unique int id: @usertype ref, + unique int templ_param_id: @usertype ref +); + +type_mentions( + unique int id: @type_mention, + int type_id: @type ref, + int location: @location ref, + // a_symbol_reference_kind from the frontend. + int kind: int ref +); + +is_function_template(unique int id: @function ref); +function_instantiation( + unique int to: @function ref, + int from: @function ref +); +function_template_argument( + int function_id: @function ref, + int index: int ref, + int arg_type: @type ref +); +function_template_argument_value( + int function_id: @function ref, + int index: int ref, + int arg_value: @expr ref +); + +is_variable_template(unique int id: @variable ref); +variable_instantiation( + unique int to: @variable ref, + int from: @variable ref +); +variable_template_argument( + int variable_id: @variable ref, + int index: int ref, + int arg_type: @type ref +); +variable_template_argument_value( + int variable_id: @variable ref, + int index: int ref, + int arg_value: @expr ref +); + +/* + Fixed point types + precision(1) = short, precision(2) = default, precision(3) = long + is_unsigned(1) = unsigned is_unsigned(2) = signed + is_fract_type(1) = declared with _Fract + saturating(1) = declared with _Sat +*/ +/* TODO +fixedpointtypes( + unique int id: @fixedpointtype, + int precision: int ref, + int is_unsigned: int ref, + int is_fract_type: int ref, + int saturating: int ref); +*/ + +routinetypes( + unique int id: @routinetype, + int return_type: @type ref +); + +routinetypeargs( + int routine: @routinetype ref, + int index: int ref, + int type_id: @type ref +); + +ptrtomembers( + unique int id: @ptrtomember, + int type_id: @type ref, + int class_id: @type ref +); + +/* + specifiers for types, functions, and variables + + "public", + "protected", + "private", + + "const", + "volatile", + "static", + + "pure", + "virtual", + "sealed", // Microsoft + "__interface", // Microsoft + "inline", + "explicit", + + "near", // near far extension + "far", // near far extension + "__ptr32", // Microsoft + "__ptr64", // Microsoft + "__sptr", // Microsoft + "__uptr", // Microsoft + "dllimport", // Microsoft + "dllexport", // Microsoft + "thread", // Microsoft + "naked", // Microsoft + "microsoft_inline", // Microsoft + "forceinline", // Microsoft + "selectany", // Microsoft + "nothrow", // Microsoft + "novtable", // Microsoft + "noreturn", // Microsoft + "noinline", // Microsoft + "noalias", // Microsoft + "restrict", // Microsoft +*/ + +specifiers( + unique int id: @specifier, + unique string str: string ref +); + +typespecifiers( + int type_id: @type ref, + int spec_id: @specifier ref +); + +funspecifiers( + int func_id: @function ref, + int spec_id: @specifier ref +); + +varspecifiers( + int var_id: @accessible ref, + int spec_id: @specifier ref +); + +attributes( + unique int id: @attribute, + int kind: int ref, + string name: string ref, + string name_space: string ref, + int location: @location_default ref +); + +case @attribute.kind of + 0 = @gnuattribute +| 1 = @stdattribute +| 2 = @declspec +| 3 = @msattribute +| 4 = @alignas +// ... 5 @objc_propertyattribute deprecated +; + +attribute_args( + unique int id: @attribute_arg, + int kind: int ref, + int attribute: @attribute ref, + int index: int ref, + int location: @location_default ref +); + +case @attribute_arg.kind of + 0 = @attribute_arg_empty +| 1 = @attribute_arg_token +| 2 = @attribute_arg_constant +| 3 = @attribute_arg_type +| 4 = @attribute_arg_constant_expr +; + +attribute_arg_value( + unique int arg: @attribute_arg ref, + string value: string ref +); +attribute_arg_type( + unique int arg: @attribute_arg ref, + int type_id: @type ref +); +attribute_arg_constant( + unique int arg: @attribute_arg ref, + int constant: @expr ref +) +attribute_arg_name( + unique int arg: @attribute_arg ref, + string name: string ref +); + +typeattributes( + int type_id: @type ref, + int spec_id: @attribute ref +); + +funcattributes( + int func_id: @function ref, + int spec_id: @attribute ref +); + +varattributes( + int var_id: @accessible ref, + int spec_id: @attribute ref +); + +stmtattributes( + int stmt_id: @stmt ref, + int spec_id: @attribute ref +); + +@type = @builtintype + | @derivedtype + | @usertype + /* TODO | @fixedpointtype */ + | @routinetype + | @ptrtomember + | @decltype; + +unspecifiedtype( + unique int type_id: @type ref, + int unspecified_type_id: @type ref +); + +member( + int parent: @type ref, + int index: int ref, + int child: @member ref +); + +@enclosingfunction_child = @usertype | @variable | @namespace + +enclosingfunction( + unique int child: @enclosingfunction_child ref, + int parent: @function ref +); + +derivations( + unique int derivation: @derivation, + int sub: @type ref, + int index: int ref, + int super: @type ref, + int location: @location_default ref +); + +derspecifiers( + int der_id: @derivation ref, + int spec_id: @specifier ref +); + +/** + * Contains the byte offset of the base class subobject within the derived + * class. Only holds for non-virtual base classes, but see table + * `virtual_base_offsets` for offsets of virtual base class subobjects. + */ +direct_base_offsets( + unique int der_id: @derivation ref, + int offset: int ref +); + +/** + * Contains the byte offset of the virtual base class subobject for class + * `super` within a most-derived object of class `sub`. `super` can be either a + * direct or indirect base class. + */ +#keyset[sub, super] +virtual_base_offsets( + int sub: @usertype ref, + int super: @usertype ref, + int offset: int ref +); + +frienddecls( + unique int id: @frienddecl, + int type_id: @type ref, + int decl_id: @declaration ref, + int location: @location_default ref +); + +@declaredtype = @usertype ; + +@declaration = @function + | @declaredtype + | @variable + | @enumconstant + | @frienddecl; + +@member = @membervariable + | @function + | @declaredtype + | @enumconstant; + +@locatable = @diagnostic + | @declaration + | @ppd_include + | @ppd_define + | @macroinvocation + /*| @funcall*/ + | @xmllocatable + | @attribute + | @attribute_arg; + +@namedscope = @namespace | @usertype; + +@element = @locatable + | @file + | @folder + | @specifier + | @type + | @expr + | @namespace + | @initialiser + | @stmt + | @derivation + | @comment + | @preprocdirect + | @fun_decl + | @var_decl + | @type_decl + | @namespace_decl + | @using + | @namequalifier + | @specialnamequalifyingelement + | @static_assert + | @type_mention + | @lambdacapture; + +@exprparent = @element; + +comments( + unique int id: @comment, + string contents: string ref, + int location: @location_default ref +); + +commentbinding( + int id: @comment ref, + int element: @element ref +); + +exprconv( + int converted: @expr ref, + unique int conversion: @expr ref +); + +compgenerated(unique int id: @element ref); + +/** + * `destructor_call` destructs the `i`'th entity that should be + * destructed following `element`. Note that entities should be + * destructed in reverse construction order, so for a given `element` + * these should be called from highest to lowest `i`. + */ +#keyset[element, destructor_call] +#keyset[element, i] +synthetic_destructor_call( + int element: @element ref, + int i: int ref, + int destructor_call: @routineexpr ref +); + +namespaces( + unique int id: @namespace, + string name: string ref +); + +namespace_inline( + unique int id: @namespace ref +); + +namespacembrs( + int parentid: @namespace ref, + unique int memberid: @namespacembr ref +); + +@namespacembr = @declaration | @namespace; + +exprparents( + int expr_id: @expr ref, + int child_index: int ref, + int parent_id: @exprparent ref +); + +expr_isload(unique int expr_id: @expr ref); + +@cast = @c_style_cast + | @const_cast + | @dynamic_cast + | @reinterpret_cast + | @static_cast + ; + +/* +case @conversion.kind of + 0 = @simple_conversion // a numeric conversion, qualification conversion, or a reinterpret_cast +| 1 = @bool_conversion // conversion to 'bool' +| 2 = @base_class_conversion // a derived-to-base conversion +| 3 = @derived_class_conversion // a base-to-derived conversion +| 4 = @pm_base_class_conversion // a derived-to-base conversion of a pointer to member +| 5 = @pm_derived_class_conversion // a base-to-derived conversion of a pointer to member +| 6 = @glvalue_adjust // an adjustment of the type of a glvalue +| 7 = @prvalue_adjust // an adjustment of the type of a prvalue +; +*/ +/** + * Describes the semantics represented by a cast expression. This is largely + * independent of the source syntax of the cast, so it is separate from the + * regular expression kind. + */ +conversionkinds( + unique int expr_id: @cast ref, + int kind: int ref +); + +@conversion = @cast + | @array_to_pointer + | @parexpr + | @reference_to + | @ref_indirect + | @temp_init + ; + +/* +case @funbindexpr.kind of + 0 = @normal_call // a normal call +| 1 = @virtual_call // a virtual call +| 2 = @adl_call // a call whose target is only found by ADL +; +*/ +iscall( + unique int caller: @funbindexpr ref, + int kind: int ref +); + +numtemplatearguments( + unique int expr_id: @expr ref, + int num: int ref +); + +specialnamequalifyingelements( + unique int id: @specialnamequalifyingelement, + unique string name: string ref +); + +@namequalifiableelement = @expr | @namequalifier; +@namequalifyingelement = @namespace + | @specialnamequalifyingelement + | @usertype; + +namequalifiers( + unique int id: @namequalifier, + unique int qualifiableelement: @namequalifiableelement ref, + int qualifyingelement: @namequalifyingelement ref, + int location: @location_default ref +); + +varbind( + int expr: @varbindexpr ref, + int var: @accessible ref +); + +funbind( + int expr: @funbindexpr ref, + int fun: @function ref +); + +@any_new_expr = @new_expr + | @new_array_expr; + +@new_or_delete_expr = @any_new_expr + | @delete_expr + | @delete_array_expr; + +@prefix_crement_expr = @preincrexpr | @predecrexpr; + +@postfix_crement_expr = @postincrexpr | @postdecrexpr; + +@increment_expr = @preincrexpr | @postincrexpr; + +@decrement_expr = @predecrexpr | @postdecrexpr; + +@crement_expr = @increment_expr | @decrement_expr; + +@un_arith_op_expr = @arithnegexpr + | @unaryplusexpr + | @conjugation + | @realpartexpr + | @imagpartexpr + | @crement_expr + ; + +@un_bitwise_op_expr = @complementexpr; + +@un_log_op_expr = @notexpr; + +@un_op_expr = @address_of + | @indirect + | @un_arith_op_expr + | @un_bitwise_op_expr + | @builtinaddressof + | @vec_fill + | @un_log_op_expr + | @co_await + | @co_yield + ; + +@bin_log_op_expr = @andlogicalexpr | @orlogicalexpr; + +@cmp_op_expr = @eq_op_expr | @rel_op_expr; + +@eq_op_expr = @eqexpr | @neexpr; + +@rel_op_expr = @gtexpr + | @ltexpr + | @geexpr + | @leexpr + | @spaceshipexpr + ; + +@bin_bitwise_op_expr = @lshiftexpr + | @rshiftexpr + | @andexpr + | @orexpr + | @xorexpr + ; + +@p_arith_op_expr = @paddexpr + | @psubexpr + | @pdiffexpr + ; + +@bin_arith_op_expr = @addexpr + | @subexpr + | @mulexpr + | @divexpr + | @remexpr + | @jmulexpr + | @jdivexpr + | @fjaddexpr + | @jfaddexpr + | @fjsubexpr + | @jfsubexpr + | @minexpr + | @maxexpr + | @p_arith_op_expr + ; + +@bin_op_expr = @bin_arith_op_expr + | @bin_bitwise_op_expr + | @cmp_op_expr + | @bin_log_op_expr + ; + +@op_expr = @un_op_expr + | @bin_op_expr + | @assign_expr + | @conditionalexpr + ; + +@assign_arith_expr = @assignaddexpr + | @assignsubexpr + | @assignmulexpr + | @assigndivexpr + | @assignremexpr + ; + +@assign_bitwise_expr = @assignandexpr + | @assignorexpr + | @assignxorexpr + | @assignlshiftexpr + | @assignrshiftexpr + | @assignpaddexpr + | @assignpsubexpr + ; + +@assign_op_expr = @assign_arith_expr | @assign_bitwise_expr + +@assign_expr = @assignexpr | @assign_op_expr | @blockassignexpr + +/* + case @allocator.form of + 0 = plain + | 1 = alignment + ; +*/ + +/** + * The allocator function associated with a `new` or `new[]` expression. + * The `form` column specified whether the allocation call contains an alignment + * argument. + */ +expr_allocator( + unique int expr: @any_new_expr ref, + int func: @function ref, + int form: int ref +); + +/* + case @deallocator.form of + 0 = plain + | 1 = size + | 2 = alignment + | 3 = size_and_alignment + ; +*/ + +/** + * The deallocator function associated with a `delete`, `delete[]`, `new`, or + * `new[]` expression. For a `new` or `new[]` expression, the deallocator is the + * one used to free memory if the initialization throws an exception. + * The `form` column specifies whether the deallocation call contains a size + * argument, and alignment argument, or both. + */ +expr_deallocator( + unique int expr: @new_or_delete_expr ref, + int func: @function ref, + int form: int ref +); + +/** + * Holds if the `@conditionalexpr` is of the two operand form + * `guard ? : false`. + */ +expr_cond_two_operand( + unique int cond: @conditionalexpr ref +); + +/** + * The guard of `@conditionalexpr` `guard ? true : false` + */ +expr_cond_guard( + unique int cond: @conditionalexpr ref, + int guard: @expr ref +); + +/** + * The expression used when the guard of `@conditionalexpr` + * `guard ? true : false` holds. For the two operand form + * `guard ?: false` consider using `expr_cond_guard` instead. + */ +expr_cond_true( + unique int cond: @conditionalexpr ref, + int true: @expr ref +); + +/** + * The expression used when the guard of `@conditionalexpr` + * `guard ? true : false` does not hold. + */ +expr_cond_false( + unique int cond: @conditionalexpr ref, + int false: @expr ref +); + +/** A string representation of the value. */ +values( + unique int id: @value, + string str: string ref +); + +/** The actual text in the source code for the value, if any. */ +valuetext( + unique int id: @value ref, + string text: string ref +); + +valuebind( + int val: @value ref, + unique int expr: @expr ref +); + +fieldoffsets( + unique int id: @variable ref, + int byteoffset: int ref, + int bitoffset: int ref +); + +bitfield( + unique int id: @variable ref, + int bits: int ref, + int declared_bits: int ref +); + +/* TODO +memberprefix( + int member: @expr ref, + int prefix: @expr ref +); +*/ + +/* + kind(1) = mbrcallexpr + kind(2) = mbrptrcallexpr + kind(3) = mbrptrmbrcallexpr + kind(4) = ptrmbrptrmbrcallexpr + kind(5) = mbrreadexpr // x.y + kind(6) = mbrptrreadexpr // p->y + kind(7) = mbrptrmbrreadexpr // x.*pm + kind(8) = mbrptrmbrptrreadexpr // x->*pm + kind(9) = staticmbrreadexpr // static x.y + kind(10) = staticmbrptrreadexpr // static p->y +*/ +/* TODO +memberaccess( + int member: @expr ref, + int kind: int ref +); +*/ + +initialisers( + unique int init: @initialiser, + int var: @accessible ref, + unique int expr: @expr ref, + int location: @location_expr ref +); + +braced_initialisers( + int init: @initialiser ref +); + +/** + * An ancestor for the expression, for cases in which we cannot + * otherwise find the expression's parent. + */ +expr_ancestor( + int exp: @expr ref, + int ancestor: @element ref +); + +exprs( + unique int id: @expr, + int kind: int ref, + int location: @location_expr ref +); + +/* + case @value.category of + 1 = prval + | 2 = xval + | 3 = lval + ; +*/ +expr_types( + int id: @expr ref, + int typeid: @type ref, + int value_category: int ref +); + +case @expr.kind of + 1 = @errorexpr +| 2 = @address_of // & AddressOfExpr +| 3 = @reference_to // ReferenceToExpr (implicit?) +| 4 = @indirect // * PointerDereferenceExpr +| 5 = @ref_indirect // ReferenceDereferenceExpr (implicit?) +// ... +| 8 = @array_to_pointer // (???) +| 9 = @vacuous_destructor_call // VacuousDestructorCall +// ... +| 11 = @assume // Microsoft +| 12 = @parexpr +| 13 = @arithnegexpr +| 14 = @unaryplusexpr +| 15 = @complementexpr +| 16 = @notexpr +| 17 = @conjugation // GNU ~ operator +| 18 = @realpartexpr // GNU __real +| 19 = @imagpartexpr // GNU __imag +| 20 = @postincrexpr +| 21 = @postdecrexpr +| 22 = @preincrexpr +| 23 = @predecrexpr +| 24 = @conditionalexpr +| 25 = @addexpr +| 26 = @subexpr +| 27 = @mulexpr +| 28 = @divexpr +| 29 = @remexpr +| 30 = @jmulexpr // C99 mul imaginary +| 31 = @jdivexpr // C99 div imaginary +| 32 = @fjaddexpr // C99 add real + imaginary +| 33 = @jfaddexpr // C99 add imaginary + real +| 34 = @fjsubexpr // C99 sub real - imaginary +| 35 = @jfsubexpr // C99 sub imaginary - real +| 36 = @paddexpr // pointer add (pointer + int or int + pointer) +| 37 = @psubexpr // pointer sub (pointer - integer) +| 38 = @pdiffexpr // difference between two pointers +| 39 = @lshiftexpr +| 40 = @rshiftexpr +| 41 = @andexpr +| 42 = @orexpr +| 43 = @xorexpr +| 44 = @eqexpr +| 45 = @neexpr +| 46 = @gtexpr +| 47 = @ltexpr +| 48 = @geexpr +| 49 = @leexpr +| 50 = @minexpr // GNU minimum +| 51 = @maxexpr // GNU maximum +| 52 = @assignexpr +| 53 = @assignaddexpr +| 54 = @assignsubexpr +| 55 = @assignmulexpr +| 56 = @assigndivexpr +| 57 = @assignremexpr +| 58 = @assignlshiftexpr +| 59 = @assignrshiftexpr +| 60 = @assignandexpr +| 61 = @assignorexpr +| 62 = @assignxorexpr +| 63 = @assignpaddexpr // assign pointer add +| 64 = @assignpsubexpr // assign pointer sub +| 65 = @andlogicalexpr +| 66 = @orlogicalexpr +| 67 = @commaexpr +| 68 = @subscriptexpr // access to member of an array, e.g., a[5] +// ... 69 @objc_subscriptexpr deprecated +// ... 70 @cmdaccess deprecated +// ... +| 73 = @virtfunptrexpr +| 74 = @callexpr +// ... 75 @msgexpr_normal deprecated +// ... 76 @msgexpr_super deprecated +// ... 77 @atselectorexpr deprecated +// ... 78 @atprotocolexpr deprecated +| 79 = @vastartexpr +| 80 = @vaargexpr +| 81 = @vaendexpr +| 82 = @vacopyexpr +// ... 83 @atencodeexpr deprecated +| 84 = @varaccess +| 85 = @thisaccess +// ... 86 @objc_box_expr deprecated +| 87 = @new_expr +| 88 = @delete_expr +| 89 = @throw_expr +| 90 = @condition_decl // a variable declared in a condition, e.g., if(int x = y > 2) +| 91 = @braced_init_list +| 92 = @type_id +| 93 = @runtime_sizeof +| 94 = @runtime_alignof +| 95 = @sizeof_pack +| 96 = @expr_stmt // GNU extension +| 97 = @routineexpr +| 98 = @type_operand // used to access a type in certain contexts (haven't found any examples yet....) +| 99 = @offsetofexpr // offsetof ::= type and field +| 100 = @hasassignexpr // __has_assign ::= type +| 101 = @hascopyexpr // __has_copy ::= type +| 102 = @hasnothrowassign // __has_nothrow_assign ::= type +| 103 = @hasnothrowconstr // __has_nothrow_constructor ::= type +| 104 = @hasnothrowcopy // __has_nothrow_copy ::= type +| 105 = @hastrivialassign // __has_trivial_assign ::= type +| 106 = @hastrivialconstr // __has_trivial_constructor ::= type +| 107 = @hastrivialcopy // __has_trivial_copy ::= type +| 108 = @hasuserdestr // __has_user_destructor ::= type +| 109 = @hasvirtualdestr // __has_virtual_destructor ::= type +| 110 = @isabstractexpr // __is_abstract ::= type +| 111 = @isbaseofexpr // __is_base_of ::= type type +| 112 = @isclassexpr // __is_class ::= type +| 113 = @isconvtoexpr // __is_convertible_to ::= type type +| 114 = @isemptyexpr // __is_empty ::= type +| 115 = @isenumexpr // __is_enum ::= type +| 116 = @ispodexpr // __is_pod ::= type +| 117 = @ispolyexpr // __is_polymorphic ::= type +| 118 = @isunionexpr // __is_union ::= type +| 119 = @typescompexpr // GNU __builtin_types_compatible ::= type type +| 120 = @intaddrexpr // frontend internal builtin, used to implement offsetof +// ... +| 122 = @hastrivialdestructor // __has_trivial_destructor ::= type +| 123 = @literal +| 124 = @uuidof +| 127 = @aggregateliteral +| 128 = @delete_array_expr +| 129 = @new_array_expr +// ... 130 @objc_array_literal deprecated +// ... 131 @objc_dictionary_literal deprecated +| 132 = @foldexpr +// ... +| 200 = @ctordirectinit +| 201 = @ctorvirtualinit +| 202 = @ctorfieldinit +| 203 = @ctordelegatinginit +| 204 = @dtordirectdestruct +| 205 = @dtorvirtualdestruct +| 206 = @dtorfielddestruct +// ... +| 210 = @static_cast +| 211 = @reinterpret_cast +| 212 = @const_cast +| 213 = @dynamic_cast +| 214 = @c_style_cast +| 215 = @lambdaexpr +| 216 = @param_ref +| 217 = @noopexpr +// ... +| 294 = @istriviallyconstructibleexpr +| 295 = @isdestructibleexpr +| 296 = @isnothrowdestructibleexpr +| 297 = @istriviallydestructibleexpr +| 298 = @istriviallyassignableexpr +| 299 = @isnothrowassignableexpr +| 300 = @istrivialexpr +| 301 = @isstandardlayoutexpr +| 302 = @istriviallycopyableexpr +| 303 = @isliteraltypeexpr +| 304 = @hastrivialmoveconstructorexpr +| 305 = @hastrivialmoveassignexpr +| 306 = @hasnothrowmoveassignexpr +| 307 = @isconstructibleexpr +| 308 = @isnothrowconstructibleexpr +| 309 = @hasfinalizerexpr +| 310 = @isdelegateexpr +| 311 = @isinterfaceclassexpr +| 312 = @isrefarrayexpr +| 313 = @isrefclassexpr +| 314 = @issealedexpr +| 315 = @issimplevalueclassexpr +| 316 = @isvalueclassexpr +| 317 = @isfinalexpr +| 319 = @noexceptexpr +| 320 = @builtinshufflevector +| 321 = @builtinchooseexpr +| 322 = @builtinaddressof +| 323 = @vec_fill +| 324 = @builtinconvertvector +| 325 = @builtincomplex +| 326 = @spaceshipexpr +| 327 = @co_await +| 328 = @co_yield +| 329 = @temp_init +| 330 = @isassignable +| 331 = @isaggregate +| 332 = @hasuniqueobjectrepresentations +| 333 = @builtinbitcast +| 334 = @builtinshuffle +| 335 = @blockassignexpr +| 336 = @issame +| 337 = @isfunction +| 338 = @islayoutcompatible +| 339 = @ispointerinterconvertiblebaseof +| 340 = @isarray +| 341 = @arrayrank +| 342 = @arrayextent +| 343 = @isarithmetic +| 344 = @iscompletetype +| 345 = @iscompound +| 346 = @isconst +| 347 = @isfloatingpoint +| 348 = @isfundamental +| 349 = @isintegral +| 350 = @islvaluereference +| 351 = @ismemberfunctionpointer +| 352 = @ismemberobjectpointer +| 353 = @ismemberpointer +| 354 = @isobject +| 355 = @ispointer +| 356 = @isreference +| 357 = @isrvaluereference +| 358 = @isscalar +| 359 = @issigned +| 360 = @isunsigned +| 361 = @isvoid +| 362 = @isvolatile +; + +@var_args_expr = @vastartexpr + | @vaendexpr + | @vaargexpr + | @vacopyexpr + ; + +@builtin_op = @var_args_expr + | @noopexpr + | @offsetofexpr + | @intaddrexpr + | @hasassignexpr + | @hascopyexpr + | @hasnothrowassign + | @hasnothrowconstr + | @hasnothrowcopy + | @hastrivialassign + | @hastrivialconstr + | @hastrivialcopy + | @hastrivialdestructor + | @hasuserdestr + | @hasvirtualdestr + | @isabstractexpr + | @isbaseofexpr + | @isclassexpr + | @isconvtoexpr + | @isemptyexpr + | @isenumexpr + | @ispodexpr + | @ispolyexpr + | @isunionexpr + | @typescompexpr + | @builtinshufflevector + | @builtinconvertvector + | @builtinaddressof + | @istriviallyconstructibleexpr + | @isdestructibleexpr + | @isnothrowdestructibleexpr + | @istriviallydestructibleexpr + | @istriviallyassignableexpr + | @isnothrowassignableexpr + | @istrivialexpr + | @isstandardlayoutexpr + | @istriviallycopyableexpr + | @isliteraltypeexpr + | @hastrivialmoveconstructorexpr + | @hastrivialmoveassignexpr + | @hasnothrowmoveassignexpr + | @isconstructibleexpr + | @isnothrowconstructibleexpr + | @hasfinalizerexpr + | @isdelegateexpr + | @isinterfaceclassexpr + | @isrefarrayexpr + | @isrefclassexpr + | @issealedexpr + | @issimplevalueclassexpr + | @isvalueclassexpr + | @isfinalexpr + | @builtinchooseexpr + | @builtincomplex + | @isassignable + | @isaggregate + | @hasuniqueobjectrepresentations + | @builtinbitcast + | @builtinshuffle + | @issame + | @isfunction + | @islayoutcompatible + | @ispointerinterconvertiblebaseof + | @isarray + | @arrayrank + | @arrayextent + | @isarithmetic + | @iscompletetype + | @iscompound + | @isconst + | @isfloatingpoint + | @isfundamental + | @isintegral + | @islvaluereference + | @ismemberfunctionpointer + | @ismemberobjectpointer + | @ismemberpointer + | @isobject + | @ispointer + | @isreference + | @isrvaluereference + | @isscalar + | @issigned + | @isunsigned + | @isvoid + | @isvolatile + ; + +new_allocated_type( + unique int expr: @new_expr ref, + int type_id: @type ref +); + +new_array_allocated_type( + unique int expr: @new_array_expr ref, + int type_id: @type ref +); + +/** + * The field being initialized by an initializer expression within an aggregate + * initializer for a class/struct/union. Position is used to sort repeated initializers. + */ +#keyset[aggregate, position] +aggregate_field_init( + int aggregate: @aggregateliteral ref, + int initializer: @expr ref, + int field: @membervariable ref, + int position: int ref +); + +/** + * The index of the element being initialized by an initializer expression + * within an aggregate initializer for an array. Position is used to sort repeated initializers. + */ +#keyset[aggregate, position] +aggregate_array_init( + int aggregate: @aggregateliteral ref, + int initializer: @expr ref, + int element_index: int ref, + int position: int ref +); + +@ctorinit = @ctordirectinit + | @ctorvirtualinit + | @ctorfieldinit + | @ctordelegatinginit; +@dtordestruct = @dtordirectdestruct + | @dtorvirtualdestruct + | @dtorfielddestruct; + + +condition_decl_bind( + unique int expr: @condition_decl ref, + unique int decl: @declaration ref +); + +typeid_bind( + unique int expr: @type_id ref, + int type_id: @type ref +); + +uuidof_bind( + unique int expr: @uuidof ref, + int type_id: @type ref +); + +@runtime_sizeof_or_alignof = @runtime_sizeof | @runtime_alignof; + +sizeof_bind( + unique int expr: @runtime_sizeof_or_alignof ref, + int type_id: @type ref +); + +code_block( + unique int block: @literal ref, + unique int routine: @function ref +); + +lambdas( + unique int expr: @lambdaexpr ref, + string default_capture: string ref, + boolean has_explicit_return_type: boolean ref +); + +lambda_capture( + unique int id: @lambdacapture, + int lambda: @lambdaexpr ref, + int index: int ref, + int field: @membervariable ref, + boolean captured_by_reference: boolean ref, + boolean is_implicit: boolean ref, + int location: @location_default ref +); + +@funbindexpr = @routineexpr + | @new_expr + | @delete_expr + | @delete_array_expr + | @ctordirectinit + | @ctorvirtualinit + | @ctordelegatinginit + | @dtordirectdestruct + | @dtorvirtualdestruct; + +@varbindexpr = @varaccess | @ctorfieldinit | @dtorfielddestruct; +@addressable = @function | @variable ; +@accessible = @addressable | @enumconstant ; + +@access = @varaccess | @routineexpr ; + +fold( + int expr: @foldexpr ref, + string operator: string ref, + boolean is_left_fold: boolean ref +); + +stmts( + unique int id: @stmt, + int kind: int ref, + int location: @location_stmt ref +); + +case @stmt.kind of + 1 = @stmt_expr +| 2 = @stmt_if +| 3 = @stmt_while +| 4 = @stmt_goto +| 5 = @stmt_label +| 6 = @stmt_return +| 7 = @stmt_block +| 8 = @stmt_end_test_while // do { ... } while ( ... ) +| 9 = @stmt_for +| 10 = @stmt_switch_case +| 11 = @stmt_switch +| 13 = @stmt_asm // "asm" statement or the body of an asm function +| 15 = @stmt_try_block +| 16 = @stmt_microsoft_try // Microsoft +| 17 = @stmt_decl +| 18 = @stmt_set_vla_size // C99 +| 19 = @stmt_vla_decl // C99 +| 25 = @stmt_assigned_goto // GNU +| 26 = @stmt_empty +| 27 = @stmt_continue +| 28 = @stmt_break +| 29 = @stmt_range_based_for // C++11 +// ... 30 @stmt_at_autoreleasepool_block deprecated +// ... 31 @stmt_objc_for_in deprecated +// ... 32 @stmt_at_synchronized deprecated +| 33 = @stmt_handler +// ... 34 @stmt_finally_end deprecated +| 35 = @stmt_constexpr_if +| 37 = @stmt_co_return +; + +type_vla( + int type_id: @type ref, + int decl: @stmt_vla_decl ref +); + +variable_vla( + int var: @variable ref, + int decl: @stmt_vla_decl ref +); + +if_initialization( + unique int if_stmt: @stmt_if ref, + int init_id: @stmt ref +); + +if_then( + unique int if_stmt: @stmt_if ref, + int then_id: @stmt ref +); + +if_else( + unique int if_stmt: @stmt_if ref, + int else_id: @stmt ref +); + +constexpr_if_initialization( + unique int constexpr_if_stmt: @stmt_constexpr_if ref, + int init_id: @stmt ref +); + +constexpr_if_then( + unique int constexpr_if_stmt: @stmt_constexpr_if ref, + int then_id: @stmt ref +); + +constexpr_if_else( + unique int constexpr_if_stmt: @stmt_constexpr_if ref, + int else_id: @stmt ref +); + +while_body( + unique int while_stmt: @stmt_while ref, + int body_id: @stmt ref +); + +do_body( + unique int do_stmt: @stmt_end_test_while ref, + int body_id: @stmt ref +); + +switch_initialization( + unique int switch_stmt: @stmt_switch ref, + int init_id: @stmt ref +); + +#keyset[switch_stmt, index] +switch_case( + int switch_stmt: @stmt_switch ref, + int index: int ref, + int case_id: @stmt_switch_case ref +); + +switch_body( + unique int switch_stmt: @stmt_switch ref, + int body_id: @stmt ref +); + +for_initialization( + unique int for_stmt: @stmt_for ref, + int init_id: @stmt ref +); + +for_condition( + unique int for_stmt: @stmt_for ref, + int condition_id: @expr ref +); + +for_update( + unique int for_stmt: @stmt_for ref, + int update_id: @expr ref +); + +for_body( + unique int for_stmt: @stmt_for ref, + int body_id: @stmt ref +); + +@stmtparent = @stmt | @expr_stmt ; +stmtparents( + unique int id: @stmt ref, + int index: int ref, + int parent: @stmtparent ref +); + +ishandler(unique int block: @stmt_block ref); + +@cfgnode = @stmt | @expr | @function | @initialiser ; + +stmt_decl_bind( + int stmt: @stmt_decl ref, + int num: int ref, + int decl: @declaration ref +); + +stmt_decl_entry_bind( + int stmt: @stmt_decl ref, + int num: int ref, + int decl_entry: @element ref +); + +@functionorblock = @function | @stmt_block; + +blockscope( + unique int block: @stmt_block ref, + int enclosing: @functionorblock ref +); + +@jump = @stmt_goto | @stmt_break | @stmt_continue; + +@jumporlabel = @jump | @stmt_label | @literal; + +jumpinfo( + unique int id: @jumporlabel ref, + string str: string ref, + int target: @stmt ref +); + +preprocdirects( + unique int id: @preprocdirect, + int kind: int ref, + int location: @location_default ref +); +case @preprocdirect.kind of + 0 = @ppd_if +| 1 = @ppd_ifdef +| 2 = @ppd_ifndef +| 3 = @ppd_elif +| 4 = @ppd_else +| 5 = @ppd_endif +| 6 = @ppd_plain_include +| 7 = @ppd_define +| 8 = @ppd_undef +| 9 = @ppd_line +| 10 = @ppd_error +| 11 = @ppd_pragma +| 12 = @ppd_objc_import +| 13 = @ppd_include_next +| 18 = @ppd_warning +; + +@ppd_include = @ppd_plain_include | @ppd_objc_import | @ppd_include_next; + +@ppd_branch = @ppd_if | @ppd_ifdef | @ppd_ifndef | @ppd_elif; + +preprocpair( + int begin : @ppd_branch ref, + int elseelifend : @preprocdirect ref +); + +preproctrue(int branch : @ppd_branch ref); +preprocfalse(int branch : @ppd_branch ref); + +preproctext( + unique int id: @preprocdirect ref, + string head: string ref, + string body: string ref +); + +includes( + unique int id: @ppd_include ref, + int included: @file ref +); + +link_targets( + unique int id: @link_target, + int binary: @file ref +); + +link_parent( + int element : @element ref, + int link_target : @link_target ref +); + +/* XML Files */ + +xmlEncoding(unique int id: @file ref, string encoding: string ref); + +xmlDTDs( + unique int id: @xmldtd, + string root: string ref, + string publicId: string ref, + string systemId: string ref, + int fileid: @file ref +); + +xmlElements( + unique int id: @xmlelement, + string name: string ref, + int parentid: @xmlparent ref, + int idx: int ref, + int fileid: @file ref +); + +xmlAttrs( + unique int id: @xmlattribute, + int elementid: @xmlelement ref, + string name: string ref, + string value: string ref, + int idx: int ref, + int fileid: @file ref +); + +xmlNs( + int id: @xmlnamespace, + string prefixName: string ref, + string 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, + string text: string ref, + int parentid: @xmlparent ref, + int fileid: @file ref +); + +xmlChars( + unique int id: @xmlcharacters, + string 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; diff --git a/cpp/ql/lib/upgrades/5b388693c66db1e7dc2e76a90aa67a2b6eb74f0f/semmlecode.cpp.dbscheme b/cpp/ql/lib/upgrades/5b388693c66db1e7dc2e76a90aa67a2b6eb74f0f/semmlecode.cpp.dbscheme new file mode 100644 index 000000000000..f79ce79e3b75 --- /dev/null +++ b/cpp/ql/lib/upgrades/5b388693c66db1e7dc2e76a90aa67a2b6eb74f0f/semmlecode.cpp.dbscheme @@ -0,0 +1,2226 @@ + +/** + * An invocation of the compiler. Note that more than one file may be + * compiled per invocation. For example, this command compiles three + * source files: + * + * gcc -c f1.c f2.c f3.c + * + * The `id` simply identifies the invocation, while `cwd` is the working + * directory from which the compiler was invoked. + */ +compilations( + /** + * An invocation of the compiler. Note that more than one file may + * be compiled per invocation. For example, this command compiles + * three source files: + * + * gcc -c f1.c f2.c f3.c + */ + unique int id : @compilation, + string cwd : string ref +); + +/** + * The arguments that were passed to the extractor for a compiler + * invocation. If `id` is for the compiler invocation + * + * gcc -c f1.c f2.c f3.c + * + * then typically there will be rows for + * + * num | arg + * --- | --- + * 0 | *path to extractor* + * 1 | `--mimic` + * 2 | `/usr/bin/gcc` + * 3 | `-c` + * 4 | f1.c + * 5 | f2.c + * 6 | f3.c + */ +#keyset[id, num] +compilation_args( + int id : @compilation ref, + int num : int ref, + string arg : string ref +); + +/** + * The source files that are compiled by a compiler invocation. + * If `id` is for the compiler invocation + * + * gcc -c f1.c f2.c f3.c + * + * then there will be rows for + * + * num | arg + * --- | --- + * 0 | f1.c + * 1 | f2.c + * 2 | f3.c + * + * Note that even if those files `#include` headers, those headers + * do not appear as rows. + */ +#keyset[id, num] +compilation_compiling_files( + int id : @compilation ref, + int num : int ref, + int file : @file ref +); + +/** + * The time taken by the extractor for a compiler invocation. + * + * For each file `num`, there will be rows for + * + * kind | seconds + * ---- | --- + * 1 | CPU seconds used by the extractor frontend + * 2 | Elapsed seconds during the extractor frontend + * 3 | CPU seconds used by the extractor backend + * 4 | Elapsed seconds during the extractor backend + */ +#keyset[id, num, kind] +compilation_time( + int id : @compilation ref, + int num : int ref, + /* kind: + 1 = frontend_cpu_seconds + 2 = frontend_elapsed_seconds + 3 = extractor_cpu_seconds + 4 = extractor_elapsed_seconds + */ + int kind : int ref, + float seconds : float ref +); + +/** + * An error or warning generated by the extractor. + * The diagnostic message `diagnostic` was generated during compiler + * invocation `compilation`, and is the `file_number_diagnostic_number`th + * message generated while extracting the `file_number`th file of that + * invocation. + */ +#keyset[compilation, file_number, file_number_diagnostic_number] +diagnostic_for( + int diagnostic : @diagnostic ref, + int compilation : @compilation ref, + int file_number : int ref, + int file_number_diagnostic_number : int ref +); + +/** + * If extraction was successful, then `cpu_seconds` and + * `elapsed_seconds` are the CPU time and elapsed time (respectively) + * that extraction took for compiler invocation `id`. + */ +compilation_finished( + unique int id : @compilation ref, + float cpu_seconds : float ref, + float elapsed_seconds : float ref +); + + +/** + * External data, loaded from CSV files during snapshot creation. See + * [Tutorial: Incorporating external data](https://help.semmle.com/wiki/display/SD/Tutorial%3A+Incorporating+external+data) + * for more information. + */ +externalData( + int id : @externalDataElement, + string path : string ref, + int column: int ref, + string value : string ref +); + +/** + * The source location of the snapshot. + */ +sourceLocationPrefix(string prefix : string ref); + +/** + * Information about packages that provide code used during compilation. + * The `id` is just a unique identifier. + * The `namespace` is typically the name of the package manager that + * provided the package (e.g. "dpkg" or "yum"). + * The `package_name` is the name of the package, and `version` is its + * version (as a string). + */ +external_packages( + unique int id: @external_package, + string namespace : string ref, + string package_name : string ref, + string version : string ref +); + +/** + * Holds if File `fileid` was provided by package `package`. + */ +header_to_external_package( + int fileid : @file ref, + int package : @external_package ref +); + +/* + * Version history + */ + +svnentries( + unique int id : @svnentry, + string revision : string ref, + string author : string ref, + date revisionDate : date ref, + int changeSize : int ref +) + +svnaffectedfiles( + int id : @svnentry ref, + int file : @file ref, + string action : string ref +) + +svnentrymsg( + unique int id : @svnentry ref, + string message : string ref +) + +svnchurn( + int commit : @svnentry ref, + int file : @file ref, + int addedLines : int ref, + int deletedLines : int ref +) + +/* + * C++ dbscheme + */ + +extractor_version( + string codeql_version: string ref, + string frontend_version: string ref +) + +@location = @location_stmt | @location_expr | @location_default ; + +/** + * The location of an element that is not an expression or a statement. + * The location spans column `startcolumn` of line `startline` to + * column `endcolumn` of line `endline` in file `file`. + * For more information, see + * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). + */ +locations_default( + /** The location of an element that is not an expression or a statement. */ + unique int id: @location_default, + int container: @container ref, + int startLine: int ref, + int startColumn: int ref, + int endLine: int ref, + int endColumn: int ref +); + +/** + * The location of a statement. + * The location spans column `startcolumn` of line `startline` to + * column `endcolumn` of line `endline` in file `file`. + * For more information, see + * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). + */ +locations_stmt( + /** The location of a statement. */ + unique int id: @location_stmt, + int container: @container ref, + int startLine: int ref, + int startColumn: int ref, + int endLine: int ref, + int endColumn: int ref +); + +/** + * The location of an expression. + * The location spans column `startcolumn` of line `startline` to + * column `endcolumn` of line `endline` in file `file`. + * For more information, see + * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). + */ +locations_expr( + /** The location of an expression. */ + unique int id: @location_expr, + int container: @container ref, + int startLine: int ref, + int startColumn: int ref, + int endLine: int ref, + int endColumn: int ref +); + +/** An element for which line-count information is available. */ +@sourceline = @file | @function | @variable | @enumconstant | @xmllocatable; + +numlines( + int element_id: @sourceline ref, + int num_lines: int ref, + int num_code: int ref, + int num_comment: int ref +); + +diagnostics( + unique int id: @diagnostic, + int severity: int ref, + string error_tag: string ref, + string error_message: string ref, + string full_error_message: string ref, + int location: @location_default ref +); + +files( + unique int id: @file, + string name: string ref +); + +folders( + unique int id: @folder, + string name: string ref +); + +@container = @folder | @file + +containerparent( + int parent: @container ref, + unique int child: @container ref +); + +fileannotations( + int id: @file ref, + int kind: int ref, + string name: string ref, + string value: string ref +); + +inmacroexpansion( + int id: @element ref, + int inv: @macroinvocation ref +); + +affectedbymacroexpansion( + int id: @element ref, + int inv: @macroinvocation ref +); + +case @macroinvocation.kind of + 1 = @macro_expansion +| 2 = @other_macro_reference +; + +macroinvocations( + unique int id: @macroinvocation, + int macro_id: @ppd_define ref, + int location: @location_default ref, + int kind: int ref +); + +macroparent( + unique int id: @macroinvocation ref, + int parent_id: @macroinvocation ref +); + +// a macroinvocation may be part of another location +// the way to find a constant expression that uses a macro +// is thus to find a constant expression that has a location +// to which a macro invocation is bound +macrolocationbind( + int id: @macroinvocation ref, + int location: @location ref +); + +#keyset[invocation, argument_index] +macro_argument_unexpanded( + int invocation: @macroinvocation ref, + int argument_index: int ref, + string text: string ref +); + +#keyset[invocation, argument_index] +macro_argument_expanded( + int invocation: @macroinvocation ref, + int argument_index: int ref, + string text: string ref +); + +/* +case @function.kind of + 1 = @normal_function +| 2 = @constructor +| 3 = @destructor +| 4 = @conversion_function +| 5 = @operator +| 6 = @builtin_function // GCC built-in functions, e.g. __builtin___memcpy_chk +; +*/ + +functions( + unique int id: @function, + string name: string ref, + int kind: int ref +); + +function_entry_point( + int id: @function ref, + unique int entry_point: @stmt ref +); + +function_return_type( + int id: @function ref, + int return_type: @type ref +); + +/** + * If `function` is a coroutine, then this gives the `std::experimental::resumable_traits` + * instance associated with it, and the variables representing the `handle` and `promise` + * for it. + */ +coroutine( + unique int function: @function ref, + int traits: @type ref, + int handle: @variable ref, + int promise: @variable ref +); + +/** The `new` function used for allocating the coroutine state, if any. */ +coroutine_new( + unique int function: @function ref, + int new: @function ref +); + +/** The `delete` function used for deallocating the coroutine state, if any. */ +coroutine_delete( + unique int function: @function ref, + int delete: @function ref +); + +purefunctions(unique int id: @function ref); + +function_deleted(unique int id: @function ref); + +function_defaulted(unique int id: @function ref); + +member_function_this_type( + unique int id: @function ref, + int this_type: @type ref +); + +#keyset[id, type_id] +fun_decls( + int id: @fun_decl, + int function: @function ref, + int type_id: @type ref, + string name: string ref, + int location: @location_default ref +); +fun_def(unique int id: @fun_decl ref); +fun_specialized(unique int id: @fun_decl ref); +fun_implicit(unique int id: @fun_decl ref); +fun_decl_specifiers( + int id: @fun_decl ref, + string name: string ref +) +#keyset[fun_decl, index] +fun_decl_throws( + int fun_decl: @fun_decl ref, + int index: int ref, + int type_id: @type ref +); +/* an empty throw specification is different from none */ +fun_decl_empty_throws(unique int fun_decl: @fun_decl ref); +fun_decl_noexcept( + int fun_decl: @fun_decl ref, + int constant: @expr ref +); +fun_decl_empty_noexcept(int fun_decl: @fun_decl ref); +fun_decl_typedef_type( + unique int fun_decl: @fun_decl ref, + int typedeftype_id: @usertype ref +); + +param_decl_bind( + unique int id: @var_decl ref, + int index: int ref, + int fun_decl: @fun_decl ref +); + +#keyset[id, type_id] +var_decls( + int id: @var_decl, + int variable: @variable ref, + int type_id: @type ref, + string name: string ref, + int location: @location_default ref +); +var_def(unique int id: @var_decl ref); +var_decl_specifiers( + int id: @var_decl ref, + string name: string ref +) +is_structured_binding(unique int id: @variable ref); + +type_decls( + unique int id: @type_decl, + int type_id: @type ref, + int location: @location_default ref +); +type_def(unique int id: @type_decl ref); +type_decl_top( + unique int type_decl: @type_decl ref +); + +namespace_decls( + unique int id: @namespace_decl, + int namespace_id: @namespace ref, + int location: @location_default ref, + int bodylocation: @location_default ref +); + +usings( + unique int id: @using, + int element_id: @element ref, + int location: @location_default ref +); + +/** The element which contains the `using` declaration. */ +using_container( + int parent: @element ref, + int child: @using ref +); + +static_asserts( + unique int id: @static_assert, + int condition : @expr ref, + string message : string ref, + int location: @location_default ref, + int enclosing : @element ref +); + +// each function has an ordered list of parameters +#keyset[id, type_id] +#keyset[function, index, type_id] +params( + int id: @parameter, + int function: @functionorblock ref, + int index: int ref, + int type_id: @type ref +); + +overrides( + int new: @function ref, + int old: @function ref +); + +#keyset[id, type_id] +membervariables( + int id: @membervariable, + int type_id: @type ref, + string name: string ref +); + +#keyset[id, type_id] +globalvariables( + int id: @globalvariable, + int type_id: @type ref, + string name: string ref +); + +#keyset[id, type_id] +localvariables( + int id: @localvariable, + int type_id: @type ref, + string name: string ref +); + +autoderivation( + unique int var: @variable ref, + int derivation_type: @type ref +); + +orphaned_variables( + int var: @localvariable ref, + int function: @function ref +) + +enumconstants( + unique int id: @enumconstant, + int parent: @usertype ref, + int index: int ref, + int type_id: @type ref, + string name: string ref, + int location: @location_default ref +); + +@variable = @localscopevariable | @globalvariable | @membervariable; + +@localscopevariable = @localvariable | @parameter; + +/** + * Built-in types are the fundamental types, e.g., integral, floating, and void. + */ +case @builtintype.kind of + 1 = @errortype +| 2 = @unknowntype +| 3 = @void +| 4 = @boolean +| 5 = @char +| 6 = @unsigned_char +| 7 = @signed_char +| 8 = @short +| 9 = @unsigned_short +| 10 = @signed_short +| 11 = @int +| 12 = @unsigned_int +| 13 = @signed_int +| 14 = @long +| 15 = @unsigned_long +| 16 = @signed_long +| 17 = @long_long +| 18 = @unsigned_long_long +| 19 = @signed_long_long +// ... 20 Microsoft-specific __int8 +// ... 21 Microsoft-specific __int16 +// ... 22 Microsoft-specific __int32 +// ... 23 Microsoft-specific __int64 +| 24 = @float +| 25 = @double +| 26 = @long_double +| 27 = @complex_float // C99-specific _Complex float +| 28 = @complex_double // C99-specific _Complex double +| 29 = @complex_long_double // C99-specific _Complex long double +| 30 = @imaginary_float // C99-specific _Imaginary float +| 31 = @imaginary_double // C99-specific _Imaginary double +| 32 = @imaginary_long_double // C99-specific _Imaginary long double +| 33 = @wchar_t // Microsoft-specific +| 34 = @decltype_nullptr // C++11 +| 35 = @int128 // __int128 +| 36 = @unsigned_int128 // unsigned __int128 +| 37 = @signed_int128 // signed __int128 +| 38 = @float128 // __float128 +| 39 = @complex_float128 // _Complex __float128 +| 40 = @decimal32 // _Decimal32 +| 41 = @decimal64 // _Decimal64 +| 42 = @decimal128 // _Decimal128 +| 43 = @char16_t +| 44 = @char32_t +| 45 = @std_float32 // _Float32 +| 46 = @float32x // _Float32x +| 47 = @std_float64 // _Float64 +| 48 = @float64x // _Float64x +| 49 = @std_float128 // _Float128 +// ... 50 _Float128x +| 51 = @char8_t +| 52 = @float16 // _Float16 +| 53 = @complex_float16 // _Complex _Float16 +| 54 = @fp16 // __fp16 +| 55 = @std_bfloat16 // __bf16 +| 56 = @std_float16 // std::float16_t +| 57 = @complex_std_float32 // _Complex _Float32 +| 58 = @complex_float32x // _Complex _Float32x +| 59 = @complex_std_float64 // _Complex _Float64 +| 60 = @complex_float64x // _Complex _Float64x +| 61 = @complex_std_float128 // _Complex _Float128 +; + +builtintypes( + unique int id: @builtintype, + string name: string ref, + int kind: int ref, + int size: int ref, + int sign: int ref, + int alignment: int ref +); + +/** + * Derived types are types that are directly derived from existing types and + * point to, refer to, transform type data to return a new type. + */ +case @derivedtype.kind of + 1 = @pointer +| 2 = @reference +| 3 = @type_with_specifiers +| 4 = @array +| 5 = @gnu_vector +| 6 = @routineptr +| 7 = @routinereference +| 8 = @rvalue_reference // C++11 +// ... 9 type_conforming_to_protocols deprecated +| 10 = @block +; + +derivedtypes( + unique int id: @derivedtype, + string name: string ref, + int kind: int ref, + int type_id: @type ref +); + +pointerishsize(unique int id: @derivedtype ref, + int size: int ref, + int alignment: int ref); + +arraysizes( + unique int id: @derivedtype ref, + int num_elements: int ref, + int bytesize: int ref, + int alignment: int ref +); + +typedefbase( + unique int id: @usertype ref, + int type_id: @type ref +); + +/** + * An instance of the C++11 `decltype` operator. For example: + * ``` + * int a; + * decltype(1+a) b; + * ``` + * Here `expr` is `1+a`. + * + * Sometimes an additional pair of parentheses around the expression + * would change the semantics of this decltype, e.g. + * ``` + * struct A { double x; }; + * const A* a = new A(); + * decltype( a->x ); // type is double + * decltype((a->x)); // type is const double& + * ``` + * (Please consult the C++11 standard for more details). + * `parentheses_would_change_meaning` is `true` iff that is the case. + */ +#keyset[id, expr] +decltypes( + int id: @decltype, + int expr: @expr ref, + int base_type: @type ref, + boolean parentheses_would_change_meaning: boolean ref +); + +/* +case @usertype.kind of + 1 = @struct +| 2 = @class +| 3 = @union +| 4 = @enum +| 5 = @typedef // classic C: typedef typedef type name +| 6 = @template +| 7 = @template_parameter +| 8 = @template_template_parameter +| 9 = @proxy_class // a proxy class associated with a template parameter +// ... 10 objc_class deprecated +// ... 11 objc_protocol deprecated +// ... 12 objc_category deprecated +| 13 = @scoped_enum +| 14 = @using_alias // a using name = type style typedef +; +*/ + +usertypes( + unique int id: @usertype, + string name: string ref, + int kind: int ref +); + +usertypesize( + unique int id: @usertype ref, + int size: int ref, + int alignment: int ref +); + +usertype_final(unique int id: @usertype ref); + +usertype_uuid( + unique int id: @usertype ref, + string uuid: string ref +); + +mangled_name( + unique int id: @declaration ref, + int mangled_name : @mangledname +); + +is_pod_class(unique int id: @usertype ref); +is_standard_layout_class(unique int id: @usertype ref); + +is_complete(unique int id: @usertype ref); + +is_class_template(unique int id: @usertype ref); +class_instantiation( + int to: @usertype ref, + int from: @usertype ref +); +class_template_argument( + int type_id: @usertype ref, + int index: int ref, + int arg_type: @type ref +); +class_template_argument_value( + int type_id: @usertype ref, + int index: int ref, + int arg_value: @expr ref +); + +is_proxy_class_for( + unique int id: @usertype ref, + unique int templ_param_id: @usertype ref +); + +type_mentions( + unique int id: @type_mention, + int type_id: @type ref, + int location: @location ref, + // a_symbol_reference_kind from the frontend. + int kind: int ref +); + +is_function_template(unique int id: @function ref); +function_instantiation( + unique int to: @function ref, + int from: @function ref +); +function_template_argument( + int function_id: @function ref, + int index: int ref, + int arg_type: @type ref +); +function_template_argument_value( + int function_id: @function ref, + int index: int ref, + int arg_value: @expr ref +); + +is_variable_template(unique int id: @variable ref); +variable_instantiation( + unique int to: @variable ref, + int from: @variable ref +); +variable_template_argument( + int variable_id: @variable ref, + int index: int ref, + int arg_type: @type ref +); +variable_template_argument_value( + int variable_id: @variable ref, + int index: int ref, + int arg_value: @expr ref +); + +/* + Fixed point types + precision(1) = short, precision(2) = default, precision(3) = long + is_unsigned(1) = unsigned is_unsigned(2) = signed + is_fract_type(1) = declared with _Fract + saturating(1) = declared with _Sat +*/ +/* TODO +fixedpointtypes( + unique int id: @fixedpointtype, + int precision: int ref, + int is_unsigned: int ref, + int is_fract_type: int ref, + int saturating: int ref); +*/ + +routinetypes( + unique int id: @routinetype, + int return_type: @type ref +); + +routinetypeargs( + int routine: @routinetype ref, + int index: int ref, + int type_id: @type ref +); + +ptrtomembers( + unique int id: @ptrtomember, + int type_id: @type ref, + int class_id: @type ref +); + +/* + specifiers for types, functions, and variables + + "public", + "protected", + "private", + + "const", + "volatile", + "static", + + "pure", + "virtual", + "sealed", // Microsoft + "__interface", // Microsoft + "inline", + "explicit", + + "near", // near far extension + "far", // near far extension + "__ptr32", // Microsoft + "__ptr64", // Microsoft + "__sptr", // Microsoft + "__uptr", // Microsoft + "dllimport", // Microsoft + "dllexport", // Microsoft + "thread", // Microsoft + "naked", // Microsoft + "microsoft_inline", // Microsoft + "forceinline", // Microsoft + "selectany", // Microsoft + "nothrow", // Microsoft + "novtable", // Microsoft + "noreturn", // Microsoft + "noinline", // Microsoft + "noalias", // Microsoft + "restrict", // Microsoft +*/ + +specifiers( + unique int id: @specifier, + unique string str: string ref +); + +typespecifiers( + int type_id: @type ref, + int spec_id: @specifier ref +); + +funspecifiers( + int func_id: @function ref, + int spec_id: @specifier ref +); + +varspecifiers( + int var_id: @accessible ref, + int spec_id: @specifier ref +); + +attributes( + unique int id: @attribute, + int kind: int ref, + string name: string ref, + string name_space: string ref, + int location: @location_default ref +); + +case @attribute.kind of + 0 = @gnuattribute +| 1 = @stdattribute +| 2 = @declspec +| 3 = @msattribute +| 4 = @alignas +// ... 5 @objc_propertyattribute deprecated +; + +attribute_args( + unique int id: @attribute_arg, + int kind: int ref, + int attribute: @attribute ref, + int index: int ref, + int location: @location_default ref +); + +case @attribute_arg.kind of + 0 = @attribute_arg_empty +| 1 = @attribute_arg_token +| 2 = @attribute_arg_constant +| 3 = @attribute_arg_type +| 4 = @attribute_arg_constant_expr +; + +attribute_arg_value( + unique int arg: @attribute_arg ref, + string value: string ref +); +attribute_arg_type( + unique int arg: @attribute_arg ref, + int type_id: @type ref +); +attribute_arg_constant( + unique int arg: @attribute_arg ref, + int constant: @expr ref +) +attribute_arg_name( + unique int arg: @attribute_arg ref, + string name: string ref +); + +typeattributes( + int type_id: @type ref, + int spec_id: @attribute ref +); + +funcattributes( + int func_id: @function ref, + int spec_id: @attribute ref +); + +varattributes( + int var_id: @accessible ref, + int spec_id: @attribute ref +); + +stmtattributes( + int stmt_id: @stmt ref, + int spec_id: @attribute ref +); + +@type = @builtintype + | @derivedtype + | @usertype + /* TODO | @fixedpointtype */ + | @routinetype + | @ptrtomember + | @decltype; + +unspecifiedtype( + unique int type_id: @type ref, + int unspecified_type_id: @type ref +); + +member( + int parent: @type ref, + int index: int ref, + int child: @member ref +); + +@enclosingfunction_child = @usertype | @variable | @namespace + +enclosingfunction( + unique int child: @enclosingfunction_child ref, + int parent: @function ref +); + +derivations( + unique int derivation: @derivation, + int sub: @type ref, + int index: int ref, + int super: @type ref, + int location: @location_default ref +); + +derspecifiers( + int der_id: @derivation ref, + int spec_id: @specifier ref +); + +/** + * Contains the byte offset of the base class subobject within the derived + * class. Only holds for non-virtual base classes, but see table + * `virtual_base_offsets` for offsets of virtual base class subobjects. + */ +direct_base_offsets( + unique int der_id: @derivation ref, + int offset: int ref +); + +/** + * Contains the byte offset of the virtual base class subobject for class + * `super` within a most-derived object of class `sub`. `super` can be either a + * direct or indirect base class. + */ +#keyset[sub, super] +virtual_base_offsets( + int sub: @usertype ref, + int super: @usertype ref, + int offset: int ref +); + +frienddecls( + unique int id: @frienddecl, + int type_id: @type ref, + int decl_id: @declaration ref, + int location: @location_default ref +); + +@declaredtype = @usertype ; + +@declaration = @function + | @declaredtype + | @variable + | @enumconstant + | @frienddecl; + +@member = @membervariable + | @function + | @declaredtype + | @enumconstant; + +@locatable = @diagnostic + | @declaration + | @ppd_include + | @ppd_define + | @macroinvocation + /*| @funcall*/ + | @xmllocatable + | @attribute + | @attribute_arg; + +@namedscope = @namespace | @usertype; + +@element = @locatable + | @file + | @folder + | @specifier + | @type + | @expr + | @namespace + | @initialiser + | @stmt + | @derivation + | @comment + | @preprocdirect + | @fun_decl + | @var_decl + | @type_decl + | @namespace_decl + | @using + | @namequalifier + | @specialnamequalifyingelement + | @static_assert + | @type_mention + | @lambdacapture; + +@exprparent = @element; + +comments( + unique int id: @comment, + string contents: string ref, + int location: @location_default ref +); + +commentbinding( + int id: @comment ref, + int element: @element ref +); + +exprconv( + int converted: @expr ref, + unique int conversion: @expr ref +); + +compgenerated(unique int id: @element ref); + +/** + * `destructor_call` destructs the `i`'th entity that should be + * destructed following `element`. Note that entities should be + * destructed in reverse construction order, so for a given `element` + * these should be called from highest to lowest `i`. + */ +#keyset[element, destructor_call] +#keyset[element, i] +synthetic_destructor_call( + int element: @element ref, + int i: int ref, + int destructor_call: @routineexpr ref +); + +namespaces( + unique int id: @namespace, + string name: string ref +); + +namespace_inline( + unique int id: @namespace ref +); + +namespacembrs( + int parentid: @namespace ref, + unique int memberid: @namespacembr ref +); + +@namespacembr = @declaration | @namespace; + +exprparents( + int expr_id: @expr ref, + int child_index: int ref, + int parent_id: @exprparent ref +); + +expr_isload(unique int expr_id: @expr ref); + +@cast = @c_style_cast + | @const_cast + | @dynamic_cast + | @reinterpret_cast + | @static_cast + ; + +/* +case @conversion.kind of + 0 = @simple_conversion // a numeric conversion, qualification conversion, or a reinterpret_cast +| 1 = @bool_conversion // conversion to 'bool' +| 2 = @base_class_conversion // a derived-to-base conversion +| 3 = @derived_class_conversion // a base-to-derived conversion +| 4 = @pm_base_class_conversion // a derived-to-base conversion of a pointer to member +| 5 = @pm_derived_class_conversion // a base-to-derived conversion of a pointer to member +| 6 = @glvalue_adjust // an adjustment of the type of a glvalue +| 7 = @prvalue_adjust // an adjustment of the type of a prvalue +; +*/ +/** + * Describes the semantics represented by a cast expression. This is largely + * independent of the source syntax of the cast, so it is separate from the + * regular expression kind. + */ +conversionkinds( + unique int expr_id: @cast ref, + int kind: int ref +); + +@conversion = @cast + | @array_to_pointer + | @parexpr + | @reference_to + | @ref_indirect + | @temp_init + ; + +/* +case @funbindexpr.kind of + 0 = @normal_call // a normal call +| 1 = @virtual_call // a virtual call +| 2 = @adl_call // a call whose target is only found by ADL +; +*/ +iscall( + unique int caller: @funbindexpr ref, + int kind: int ref +); + +numtemplatearguments( + unique int expr_id: @expr ref, + int num: int ref +); + +specialnamequalifyingelements( + unique int id: @specialnamequalifyingelement, + unique string name: string ref +); + +@namequalifiableelement = @expr | @namequalifier; +@namequalifyingelement = @namespace + | @specialnamequalifyingelement + | @usertype; + +namequalifiers( + unique int id: @namequalifier, + unique int qualifiableelement: @namequalifiableelement ref, + int qualifyingelement: @namequalifyingelement ref, + int location: @location_default ref +); + +varbind( + int expr: @varbindexpr ref, + int var: @accessible ref +); + +funbind( + int expr: @funbindexpr ref, + int fun: @function ref +); + +@any_new_expr = @new_expr + | @new_array_expr; + +@new_or_delete_expr = @any_new_expr + | @delete_expr + | @delete_array_expr; + +@prefix_crement_expr = @preincrexpr | @predecrexpr; + +@postfix_crement_expr = @postincrexpr | @postdecrexpr; + +@increment_expr = @preincrexpr | @postincrexpr; + +@decrement_expr = @predecrexpr | @postdecrexpr; + +@crement_expr = @increment_expr | @decrement_expr; + +@un_arith_op_expr = @arithnegexpr + | @unaryplusexpr + | @conjugation + | @realpartexpr + | @imagpartexpr + | @crement_expr + ; + +@un_bitwise_op_expr = @complementexpr; + +@un_log_op_expr = @notexpr; + +@un_op_expr = @address_of + | @indirect + | @un_arith_op_expr + | @un_bitwise_op_expr + | @builtinaddressof + | @vec_fill + | @un_log_op_expr + | @co_await + | @co_yield + ; + +@bin_log_op_expr = @andlogicalexpr | @orlogicalexpr; + +@cmp_op_expr = @eq_op_expr | @rel_op_expr; + +@eq_op_expr = @eqexpr | @neexpr; + +@rel_op_expr = @gtexpr + | @ltexpr + | @geexpr + | @leexpr + | @spaceshipexpr + ; + +@bin_bitwise_op_expr = @lshiftexpr + | @rshiftexpr + | @andexpr + | @orexpr + | @xorexpr + ; + +@p_arith_op_expr = @paddexpr + | @psubexpr + | @pdiffexpr + ; + +@bin_arith_op_expr = @addexpr + | @subexpr + | @mulexpr + | @divexpr + | @remexpr + | @jmulexpr + | @jdivexpr + | @fjaddexpr + | @jfaddexpr + | @fjsubexpr + | @jfsubexpr + | @minexpr + | @maxexpr + | @p_arith_op_expr + ; + +@bin_op_expr = @bin_arith_op_expr + | @bin_bitwise_op_expr + | @cmp_op_expr + | @bin_log_op_expr + ; + +@op_expr = @un_op_expr + | @bin_op_expr + | @assign_expr + | @conditionalexpr + ; + +@assign_arith_expr = @assignaddexpr + | @assignsubexpr + | @assignmulexpr + | @assigndivexpr + | @assignremexpr + ; + +@assign_bitwise_expr = @assignandexpr + | @assignorexpr + | @assignxorexpr + | @assignlshiftexpr + | @assignrshiftexpr + | @assignpaddexpr + | @assignpsubexpr + ; + +@assign_op_expr = @assign_arith_expr | @assign_bitwise_expr + +@assign_expr = @assignexpr | @assign_op_expr | @blockassignexpr + +/* + case @allocator.form of + 0 = plain + | 1 = alignment + ; +*/ + +/** + * The allocator function associated with a `new` or `new[]` expression. + * The `form` column specified whether the allocation call contains an alignment + * argument. + */ +expr_allocator( + unique int expr: @any_new_expr ref, + int func: @function ref, + int form: int ref +); + +/* + case @deallocator.form of + 0 = plain + | 1 = size + | 2 = alignment + | 3 = size_and_alignment + ; +*/ + +/** + * The deallocator function associated with a `delete`, `delete[]`, `new`, or + * `new[]` expression. For a `new` or `new[]` expression, the deallocator is the + * one used to free memory if the initialization throws an exception. + * The `form` column specifies whether the deallocation call contains a size + * argument, and alignment argument, or both. + */ +expr_deallocator( + unique int expr: @new_or_delete_expr ref, + int func: @function ref, + int form: int ref +); + +/** + * Holds if the `@conditionalexpr` is of the two operand form + * `guard ? : false`. + */ +expr_cond_two_operand( + unique int cond: @conditionalexpr ref +); + +/** + * The guard of `@conditionalexpr` `guard ? true : false` + */ +expr_cond_guard( + unique int cond: @conditionalexpr ref, + int guard: @expr ref +); + +/** + * The expression used when the guard of `@conditionalexpr` + * `guard ? true : false` holds. For the two operand form + * `guard ?: false` consider using `expr_cond_guard` instead. + */ +expr_cond_true( + unique int cond: @conditionalexpr ref, + int true: @expr ref +); + +/** + * The expression used when the guard of `@conditionalexpr` + * `guard ? true : false` does not hold. + */ +expr_cond_false( + unique int cond: @conditionalexpr ref, + int false: @expr ref +); + +/** A string representation of the value. */ +values( + unique int id: @value, + string str: string ref +); + +/** The actual text in the source code for the value, if any. */ +valuetext( + unique int id: @value ref, + string text: string ref +); + +valuebind( + int val: @value ref, + unique int expr: @expr ref +); + +fieldoffsets( + unique int id: @variable ref, + int byteoffset: int ref, + int bitoffset: int ref +); + +bitfield( + unique int id: @variable ref, + int bits: int ref, + int declared_bits: int ref +); + +/* TODO +memberprefix( + int member: @expr ref, + int prefix: @expr ref +); +*/ + +/* + kind(1) = mbrcallexpr + kind(2) = mbrptrcallexpr + kind(3) = mbrptrmbrcallexpr + kind(4) = ptrmbrptrmbrcallexpr + kind(5) = mbrreadexpr // x.y + kind(6) = mbrptrreadexpr // p->y + kind(7) = mbrptrmbrreadexpr // x.*pm + kind(8) = mbrptrmbrptrreadexpr // x->*pm + kind(9) = staticmbrreadexpr // static x.y + kind(10) = staticmbrptrreadexpr // static p->y +*/ +/* TODO +memberaccess( + int member: @expr ref, + int kind: int ref +); +*/ + +initialisers( + unique int init: @initialiser, + int var: @accessible ref, + unique int expr: @expr ref, + int location: @location_expr ref +); + +braced_initialisers( + int init: @initialiser ref +); + +/** + * An ancestor for the expression, for cases in which we cannot + * otherwise find the expression's parent. + */ +expr_ancestor( + int exp: @expr ref, + int ancestor: @element ref +); + +exprs( + unique int id: @expr, + int kind: int ref, + int location: @location_expr ref +); + +/* + case @value.category of + 1 = prval + | 2 = xval + | 3 = lval + ; +*/ +expr_types( + int id: @expr ref, + int typeid: @type ref, + int value_category: int ref +); + +case @expr.kind of + 1 = @errorexpr +| 2 = @address_of // & AddressOfExpr +| 3 = @reference_to // ReferenceToExpr (implicit?) +| 4 = @indirect // * PointerDereferenceExpr +| 5 = @ref_indirect // ReferenceDereferenceExpr (implicit?) +// ... +| 8 = @array_to_pointer // (???) +| 9 = @vacuous_destructor_call // VacuousDestructorCall +// ... +| 11 = @assume // Microsoft +| 12 = @parexpr +| 13 = @arithnegexpr +| 14 = @unaryplusexpr +| 15 = @complementexpr +| 16 = @notexpr +| 17 = @conjugation // GNU ~ operator +| 18 = @realpartexpr // GNU __real +| 19 = @imagpartexpr // GNU __imag +| 20 = @postincrexpr +| 21 = @postdecrexpr +| 22 = @preincrexpr +| 23 = @predecrexpr +| 24 = @conditionalexpr +| 25 = @addexpr +| 26 = @subexpr +| 27 = @mulexpr +| 28 = @divexpr +| 29 = @remexpr +| 30 = @jmulexpr // C99 mul imaginary +| 31 = @jdivexpr // C99 div imaginary +| 32 = @fjaddexpr // C99 add real + imaginary +| 33 = @jfaddexpr // C99 add imaginary + real +| 34 = @fjsubexpr // C99 sub real - imaginary +| 35 = @jfsubexpr // C99 sub imaginary - real +| 36 = @paddexpr // pointer add (pointer + int or int + pointer) +| 37 = @psubexpr // pointer sub (pointer - integer) +| 38 = @pdiffexpr // difference between two pointers +| 39 = @lshiftexpr +| 40 = @rshiftexpr +| 41 = @andexpr +| 42 = @orexpr +| 43 = @xorexpr +| 44 = @eqexpr +| 45 = @neexpr +| 46 = @gtexpr +| 47 = @ltexpr +| 48 = @geexpr +| 49 = @leexpr +| 50 = @minexpr // GNU minimum +| 51 = @maxexpr // GNU maximum +| 52 = @assignexpr +| 53 = @assignaddexpr +| 54 = @assignsubexpr +| 55 = @assignmulexpr +| 56 = @assigndivexpr +| 57 = @assignremexpr +| 58 = @assignlshiftexpr +| 59 = @assignrshiftexpr +| 60 = @assignandexpr +| 61 = @assignorexpr +| 62 = @assignxorexpr +| 63 = @assignpaddexpr // assign pointer add +| 64 = @assignpsubexpr // assign pointer sub +| 65 = @andlogicalexpr +| 66 = @orlogicalexpr +| 67 = @commaexpr +| 68 = @subscriptexpr // access to member of an array, e.g., a[5] +// ... 69 @objc_subscriptexpr deprecated +// ... 70 @cmdaccess deprecated +// ... +| 73 = @virtfunptrexpr +| 74 = @callexpr +// ... 75 @msgexpr_normal deprecated +// ... 76 @msgexpr_super deprecated +// ... 77 @atselectorexpr deprecated +// ... 78 @atprotocolexpr deprecated +| 79 = @vastartexpr +| 80 = @vaargexpr +| 81 = @vaendexpr +| 82 = @vacopyexpr +// ... 83 @atencodeexpr deprecated +| 84 = @varaccess +| 85 = @thisaccess +// ... 86 @objc_box_expr deprecated +| 87 = @new_expr +| 88 = @delete_expr +| 89 = @throw_expr +| 90 = @condition_decl // a variable declared in a condition, e.g., if(int x = y > 2) +| 91 = @braced_init_list +| 92 = @type_id +| 93 = @runtime_sizeof +| 94 = @runtime_alignof +| 95 = @sizeof_pack +| 96 = @expr_stmt // GNU extension +| 97 = @routineexpr +| 98 = @type_operand // used to access a type in certain contexts (haven't found any examples yet....) +| 99 = @offsetofexpr // offsetof ::= type and field +| 100 = @hasassignexpr // __has_assign ::= type +| 101 = @hascopyexpr // __has_copy ::= type +| 102 = @hasnothrowassign // __has_nothrow_assign ::= type +| 103 = @hasnothrowconstr // __has_nothrow_constructor ::= type +| 104 = @hasnothrowcopy // __has_nothrow_copy ::= type +| 105 = @hastrivialassign // __has_trivial_assign ::= type +| 106 = @hastrivialconstr // __has_trivial_constructor ::= type +| 107 = @hastrivialcopy // __has_trivial_copy ::= type +| 108 = @hasuserdestr // __has_user_destructor ::= type +| 109 = @hasvirtualdestr // __has_virtual_destructor ::= type +| 110 = @isabstractexpr // __is_abstract ::= type +| 111 = @isbaseofexpr // __is_base_of ::= type type +| 112 = @isclassexpr // __is_class ::= type +| 113 = @isconvtoexpr // __is_convertible_to ::= type type +| 114 = @isemptyexpr // __is_empty ::= type +| 115 = @isenumexpr // __is_enum ::= type +| 116 = @ispodexpr // __is_pod ::= type +| 117 = @ispolyexpr // __is_polymorphic ::= type +| 118 = @isunionexpr // __is_union ::= type +| 119 = @typescompexpr // GNU __builtin_types_compatible ::= type type +| 120 = @intaddrexpr // frontend internal builtin, used to implement offsetof +// ... +| 122 = @hastrivialdestructor // __has_trivial_destructor ::= type +| 123 = @literal +| 124 = @uuidof +| 127 = @aggregateliteral +| 128 = @delete_array_expr +| 129 = @new_array_expr +// ... 130 @objc_array_literal deprecated +// ... 131 @objc_dictionary_literal deprecated +| 132 = @foldexpr +// ... +| 200 = @ctordirectinit +| 201 = @ctorvirtualinit +| 202 = @ctorfieldinit +| 203 = @ctordelegatinginit +| 204 = @dtordirectdestruct +| 205 = @dtorvirtualdestruct +| 206 = @dtorfielddestruct +// ... +| 210 = @static_cast +| 211 = @reinterpret_cast +| 212 = @const_cast +| 213 = @dynamic_cast +| 214 = @c_style_cast +| 215 = @lambdaexpr +| 216 = @param_ref +| 217 = @noopexpr +// ... +| 294 = @istriviallyconstructibleexpr +| 295 = @isdestructibleexpr +| 296 = @isnothrowdestructibleexpr +| 297 = @istriviallydestructibleexpr +| 298 = @istriviallyassignableexpr +| 299 = @isnothrowassignableexpr +| 300 = @istrivialexpr +| 301 = @isstandardlayoutexpr +| 302 = @istriviallycopyableexpr +| 303 = @isliteraltypeexpr +| 304 = @hastrivialmoveconstructorexpr +| 305 = @hastrivialmoveassignexpr +| 306 = @hasnothrowmoveassignexpr +| 307 = @isconstructibleexpr +| 308 = @isnothrowconstructibleexpr +| 309 = @hasfinalizerexpr +| 310 = @isdelegateexpr +| 311 = @isinterfaceclassexpr +| 312 = @isrefarrayexpr +| 313 = @isrefclassexpr +| 314 = @issealedexpr +| 315 = @issimplevalueclassexpr +| 316 = @isvalueclassexpr +| 317 = @isfinalexpr +| 319 = @noexceptexpr +| 320 = @builtinshufflevector +| 321 = @builtinchooseexpr +| 322 = @builtinaddressof +| 323 = @vec_fill +| 324 = @builtinconvertvector +| 325 = @builtincomplex +| 326 = @spaceshipexpr +| 327 = @co_await +| 328 = @co_yield +| 329 = @temp_init +| 330 = @isassignable +| 331 = @isaggregate +| 332 = @hasuniqueobjectrepresentations +| 333 = @builtinbitcast +| 334 = @builtinshuffle +| 335 = @blockassignexpr +| 336 = @issame +| 337 = @isfunction +| 338 = @islayoutcompatible +| 339 = @ispointerinterconvertiblebaseof +| 340 = @isarray +| 341 = @arrayrank +| 342 = @arrayextent +| 343 = @isarithmetic +| 344 = @iscompletetype +| 345 = @iscompound +| 346 = @isconst +| 347 = @isfloatingpoint +| 348 = @isfundamental +| 349 = @isintegral +| 350 = @islvaluereference +| 351 = @ismemberfunctionpointer +| 352 = @ismemberobjectpointer +| 353 = @ismemberpointer +| 354 = @isobject +| 355 = @ispointer +| 356 = @isreference +| 357 = @isrvaluereference +| 358 = @isscalar +| 359 = @issigned +| 360 = @isunsigned +| 361 = @isvoid +| 362 = @isvolatile +; + +@var_args_expr = @vastartexpr + | @vaendexpr + | @vaargexpr + | @vacopyexpr + ; + +@builtin_op = @var_args_expr + | @noopexpr + | @offsetofexpr + | @intaddrexpr + | @hasassignexpr + | @hascopyexpr + | @hasnothrowassign + | @hasnothrowconstr + | @hasnothrowcopy + | @hastrivialassign + | @hastrivialconstr + | @hastrivialcopy + | @hastrivialdestructor + | @hasuserdestr + | @hasvirtualdestr + | @isabstractexpr + | @isbaseofexpr + | @isclassexpr + | @isconvtoexpr + | @isemptyexpr + | @isenumexpr + | @ispodexpr + | @ispolyexpr + | @isunionexpr + | @typescompexpr + | @builtinshufflevector + | @builtinconvertvector + | @builtinaddressof + | @istriviallyconstructibleexpr + | @isdestructibleexpr + | @isnothrowdestructibleexpr + | @istriviallydestructibleexpr + | @istriviallyassignableexpr + | @isnothrowassignableexpr + | @istrivialexpr + | @isstandardlayoutexpr + | @istriviallycopyableexpr + | @isliteraltypeexpr + | @hastrivialmoveconstructorexpr + | @hastrivialmoveassignexpr + | @hasnothrowmoveassignexpr + | @isconstructibleexpr + | @isnothrowconstructibleexpr + | @hasfinalizerexpr + | @isdelegateexpr + | @isinterfaceclassexpr + | @isrefarrayexpr + | @isrefclassexpr + | @issealedexpr + | @issimplevalueclassexpr + | @isvalueclassexpr + | @isfinalexpr + | @builtinchooseexpr + | @builtincomplex + | @isassignable + | @isaggregate + | @hasuniqueobjectrepresentations + | @builtinbitcast + | @builtinshuffle + | @issame + | @isfunction + | @islayoutcompatible + | @ispointerinterconvertiblebaseof + | @isarray + | @arrayrank + | @arrayextent + | @isarithmetic + | @iscompletetype + | @iscompound + | @isconst + | @isfloatingpoint + | @isfundamental + | @isintegral + | @islvaluereference + | @ismemberfunctionpointer + | @ismemberobjectpointer + | @ismemberpointer + | @isobject + | @ispointer + | @isreference + | @isrvaluereference + | @isscalar + | @issigned + | @isunsigned + | @isvoid + | @isvolatile + ; + +new_allocated_type( + unique int expr: @new_expr ref, + int type_id: @type ref +); + +new_array_allocated_type( + unique int expr: @new_array_expr ref, + int type_id: @type ref +); + +/** + * The field being initialized by an initializer expression within an aggregate + * initializer for a class/struct/union. Position is used to sort repeated initializers. + */ +#keyset[aggregate, position] +aggregate_field_init( + int aggregate: @aggregateliteral ref, + int initializer: @expr ref, + int field: @membervariable ref, + int position: int ref +); + +/** + * The index of the element being initialized by an initializer expression + * within an aggregate initializer for an array. Position is used to sort repeated initializers. + */ +#keyset[aggregate, position] +aggregate_array_init( + int aggregate: @aggregateliteral ref, + int initializer: @expr ref, + int element_index: int ref, + int position: int ref +); + +@ctorinit = @ctordirectinit + | @ctorvirtualinit + | @ctorfieldinit + | @ctordelegatinginit; +@dtordestruct = @dtordirectdestruct + | @dtorvirtualdestruct + | @dtorfielddestruct; + + +condition_decl_bind( + unique int expr: @condition_decl ref, + unique int decl: @declaration ref +); + +typeid_bind( + unique int expr: @type_id ref, + int type_id: @type ref +); + +uuidof_bind( + unique int expr: @uuidof ref, + int type_id: @type ref +); + +@runtime_sizeof_or_alignof = @runtime_sizeof | @runtime_alignof; + +sizeof_bind( + unique int expr: @runtime_sizeof_or_alignof ref, + int type_id: @type ref +); + +code_block( + unique int block: @literal ref, + unique int routine: @function ref +); + +lambdas( + unique int expr: @lambdaexpr ref, + string default_capture: string ref, + boolean has_explicit_return_type: boolean ref +); + +lambda_capture( + unique int id: @lambdacapture, + int lambda: @lambdaexpr ref, + int index: int ref, + int field: @membervariable ref, + boolean captured_by_reference: boolean ref, + boolean is_implicit: boolean ref, + int location: @location_default ref +); + +@funbindexpr = @routineexpr + | @new_expr + | @delete_expr + | @delete_array_expr + | @ctordirectinit + | @ctorvirtualinit + | @ctordelegatinginit + | @dtordirectdestruct + | @dtorvirtualdestruct; + +@varbindexpr = @varaccess | @ctorfieldinit | @dtorfielddestruct; +@addressable = @function | @variable ; +@accessible = @addressable | @enumconstant ; + +@access = @varaccess | @routineexpr ; + +fold( + int expr: @foldexpr ref, + string operator: string ref, + boolean is_left_fold: boolean ref +); + +stmts( + unique int id: @stmt, + int kind: int ref, + int location: @location_stmt ref +); + +case @stmt.kind of + 1 = @stmt_expr +| 2 = @stmt_if +| 3 = @stmt_while +| 4 = @stmt_goto +| 5 = @stmt_label +| 6 = @stmt_return +| 7 = @stmt_block +| 8 = @stmt_end_test_while // do { ... } while ( ... ) +| 9 = @stmt_for +| 10 = @stmt_switch_case +| 11 = @stmt_switch +| 13 = @stmt_asm // "asm" statement or the body of an asm function +| 15 = @stmt_try_block +| 16 = @stmt_microsoft_try // Microsoft +| 17 = @stmt_decl +| 18 = @stmt_set_vla_size // C99 +| 19 = @stmt_vla_decl // C99 +| 25 = @stmt_assigned_goto // GNU +| 26 = @stmt_empty +| 27 = @stmt_continue +| 28 = @stmt_break +| 29 = @stmt_range_based_for // C++11 +// ... 30 @stmt_at_autoreleasepool_block deprecated +// ... 31 @stmt_objc_for_in deprecated +// ... 32 @stmt_at_synchronized deprecated +| 33 = @stmt_handler +// ... 34 @stmt_finally_end deprecated +| 35 = @stmt_constexpr_if +| 37 = @stmt_co_return +; + +type_vla( + int type_id: @type ref, + int decl: @stmt_vla_decl ref +); + +variable_vla( + int var: @variable ref, + int decl: @stmt_vla_decl ref +); + +if_initialization( + unique int if_stmt: @stmt_if ref, + int init_id: @stmt ref +); + +if_then( + unique int if_stmt: @stmt_if ref, + int then_id: @stmt ref +); + +if_else( + unique int if_stmt: @stmt_if ref, + int else_id: @stmt ref +); + +constexpr_if_initialization( + unique int constexpr_if_stmt: @stmt_constexpr_if ref, + int init_id: @stmt ref +); + +constexpr_if_then( + unique int constexpr_if_stmt: @stmt_constexpr_if ref, + int then_id: @stmt ref +); + +constexpr_if_else( + unique int constexpr_if_stmt: @stmt_constexpr_if ref, + int else_id: @stmt ref +); + +while_body( + unique int while_stmt: @stmt_while ref, + int body_id: @stmt ref +); + +do_body( + unique int do_stmt: @stmt_end_test_while ref, + int body_id: @stmt ref +); + +switch_initialization( + unique int switch_stmt: @stmt_switch ref, + int init_id: @stmt ref +); + +#keyset[switch_stmt, index] +switch_case( + int switch_stmt: @stmt_switch ref, + int index: int ref, + int case_id: @stmt_switch_case ref +); + +switch_body( + unique int switch_stmt: @stmt_switch ref, + int body_id: @stmt ref +); + +for_initialization( + unique int for_stmt: @stmt_for ref, + int init_id: @stmt ref +); + +for_condition( + unique int for_stmt: @stmt_for ref, + int condition_id: @expr ref +); + +for_update( + unique int for_stmt: @stmt_for ref, + int update_id: @expr ref +); + +for_body( + unique int for_stmt: @stmt_for ref, + int body_id: @stmt ref +); + +@stmtparent = @stmt | @expr_stmt ; +stmtparents( + unique int id: @stmt ref, + int index: int ref, + int parent: @stmtparent ref +); + +ishandler(unique int block: @stmt_block ref); + +@cfgnode = @stmt | @expr | @function | @initialiser ; + +stmt_decl_bind( + int stmt: @stmt_decl ref, + int num: int ref, + int decl: @declaration ref +); + +stmt_decl_entry_bind( + int stmt: @stmt_decl ref, + int num: int ref, + int decl_entry: @element ref +); + +@functionorblock = @function | @stmt_block; + +blockscope( + unique int block: @stmt_block ref, + int enclosing: @functionorblock ref +); + +@jump = @stmt_goto | @stmt_break | @stmt_continue; + +@jumporlabel = @jump | @stmt_label | @literal; + +jumpinfo( + unique int id: @jumporlabel ref, + string str: string ref, + int target: @stmt ref +); + +preprocdirects( + unique int id: @preprocdirect, + int kind: int ref, + int location: @location_default ref +); +case @preprocdirect.kind of + 0 = @ppd_if +| 1 = @ppd_ifdef +| 2 = @ppd_ifndef +| 3 = @ppd_elif +| 4 = @ppd_else +| 5 = @ppd_endif +| 6 = @ppd_plain_include +| 7 = @ppd_define +| 8 = @ppd_undef +| 9 = @ppd_line +| 10 = @ppd_error +| 11 = @ppd_pragma +| 12 = @ppd_objc_import +| 13 = @ppd_include_next +| 18 = @ppd_warning +; + +@ppd_include = @ppd_plain_include | @ppd_objc_import | @ppd_include_next; + +@ppd_branch = @ppd_if | @ppd_ifdef | @ppd_ifndef | @ppd_elif; + +preprocpair( + int begin : @ppd_branch ref, + int elseelifend : @preprocdirect ref +); + +preproctrue(int branch : @ppd_branch ref); +preprocfalse(int branch : @ppd_branch ref); + +preproctext( + unique int id: @preprocdirect ref, + string head: string ref, + string body: string ref +); + +includes( + unique int id: @ppd_include ref, + int included: @file ref +); + +link_targets( + unique int id: @link_target, + int binary: @file ref +); + +link_parent( + int element : @element ref, + int link_target : @link_target ref +); + +/* XML Files */ + +xmlEncoding(unique int id: @file ref, string encoding: string ref); + +xmlDTDs( + unique int id: @xmldtd, + string root: string ref, + string publicId: string ref, + string systemId: string ref, + int fileid: @file ref +); + +xmlElements( + unique int id: @xmlelement, + string name: string ref, + int parentid: @xmlparent ref, + int idx: int ref, + int fileid: @file ref +); + +xmlAttrs( + unique int id: @xmlattribute, + int elementid: @xmlelement ref, + string name: string ref, + string value: string ref, + int idx: int ref, + int fileid: @file ref +); + +xmlNs( + int id: @xmlnamespace, + string prefixName: string ref, + string 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, + string text: string ref, + int parentid: @xmlparent ref, + int fileid: @file ref +); + +xmlChars( + unique int id: @xmlcharacters, + string 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; diff --git a/cpp/ql/lib/upgrades/5b388693c66db1e7dc2e76a90aa67a2b6eb74f0f/upgrade.properties b/cpp/ql/lib/upgrades/5b388693c66db1e7dc2e76a90aa67a2b6eb74f0f/upgrade.properties new file mode 100644 index 000000000000..90e68eef3c82 --- /dev/null +++ b/cpp/ql/lib/upgrades/5b388693c66db1e7dc2e76a90aa67a2b6eb74f0f/upgrade.properties @@ -0,0 +1,2 @@ +description: Introduce extractor version numbers +compatibility: full diff --git a/cpp/ql/test/library-tests/dataflow/dataflow-tests/dataflow-ir-consistency.expected b/cpp/ql/test/library-tests/dataflow/dataflow-tests/dataflow-ir-consistency.expected index b7b2a8eab909..bacd714e6148 100644 --- a/cpp/ql/test/library-tests/dataflow/dataflow-tests/dataflow-ir-consistency.expected +++ b/cpp/ql/test/library-tests/dataflow/dataflow-tests/dataflow-ir-consistency.expected @@ -20,12 +20,8 @@ reverseRead argHasPostUpdate postWithInFlow | test.cpp:384:10:384:13 | memcpy output argument | PostUpdateNode should not be the target of local flow. | -| test.cpp:384:10:384:13 | memcpy output argument | PostUpdateNode should not be the target of local flow. | -| test.cpp:391:10:391:13 | memcpy output argument | PostUpdateNode should not be the target of local flow. | | test.cpp:391:10:391:13 | memcpy output argument | PostUpdateNode should not be the target of local flow. | | test.cpp:400:10:400:13 | memcpy output argument | PostUpdateNode should not be the target of local flow. | -| test.cpp:400:10:400:13 | memcpy output argument | PostUpdateNode should not be the target of local flow. | -| test.cpp:407:10:407:13 | memcpy output argument | PostUpdateNode should not be the target of local flow. | | test.cpp:407:10:407:13 | memcpy output argument | PostUpdateNode should not be the target of local flow. | viableImplInCallContextTooLarge uniqueParameterNodeAtPosition diff --git a/cpp/ql/test/library-tests/dataflow/fields/dataflow-ir-consistency.expected b/cpp/ql/test/library-tests/dataflow/fields/dataflow-ir-consistency.expected index 72818427b846..4b74de5a825f 100644 --- a/cpp/ql/test/library-tests/dataflow/fields/dataflow-ir-consistency.expected +++ b/cpp/ql/test/library-tests/dataflow/fields/dataflow-ir-consistency.expected @@ -44,8 +44,6 @@ reverseRead argHasPostUpdate postWithInFlow | realistic.cpp:54:16:54:47 | memcpy output argument | PostUpdateNode should not be the target of local flow. | -| realistic.cpp:54:16:54:47 | memcpy output argument | PostUpdateNode should not be the target of local flow. | -| realistic.cpp:60:16:60:18 | memcpy output argument | PostUpdateNode should not be the target of local flow. | | realistic.cpp:60:16:60:18 | memcpy output argument | PostUpdateNode should not be the target of local flow. | viableImplInCallContextTooLarge uniqueParameterNodeAtPosition diff --git a/cpp/ql/test/library-tests/dataflow/taint-tests/localTaint.expected b/cpp/ql/test/library-tests/dataflow/taint-tests/localTaint.expected index f134b647a14d..ceb3cde9a8e3 100644 --- a/cpp/ql/test/library-tests/dataflow/taint-tests/localTaint.expected +++ b/cpp/ql/test/library-tests/dataflow/taint-tests/localTaint.expected @@ -2199,6 +2199,19 @@ WARNING: Module TaintTracking has been deprecated and may be removed in future ( | map.cpp:436:55:436:59 | def | map.cpp:436:19:436:60 | call to pair | TAINT | | map.cpp:436:63:436:67 | first | map.cpp:436:7:436:67 | call to iterator | | | map.cpp:437:7:437:9 | m35 | map.cpp:437:7:437:9 | call to unordered_map | | +| map.cpp:446:23:446:23 | call to map | map.cpp:448:3:448:3 | m | | +| map.cpp:446:23:446:23 | call to map | map.cpp:449:12:449:12 | m | | +| map.cpp:446:23:446:23 | call to map | map.cpp:451:1:451:1 | m | | +| map.cpp:447:12:447:26 | call to indirect_source | map.cpp:448:10:448:10 | p | | +| map.cpp:448:3:448:3 | m | map.cpp:448:4:448:4 | call to operator[] | TAINT | +| map.cpp:448:3:448:3 | ref arg m | map.cpp:449:12:449:12 | m | | +| map.cpp:448:3:448:3 | ref arg m | map.cpp:451:1:451:1 | m | | +| map.cpp:448:3:448:10 | ... = ... | map.cpp:448:4:448:4 | call to operator[] [post update] | | +| map.cpp:448:4:448:4 | call to operator[] [post update] | map.cpp:448:3:448:3 | ref arg m | TAINT | +| map.cpp:448:10:448:10 | p | map.cpp:448:3:448:10 | ... = ... | | +| map.cpp:449:12:449:12 | m | map.cpp:449:13:449:13 | call to operator[] | TAINT | +| map.cpp:449:12:449:12 | ref arg m | map.cpp:451:1:451:1 | m | | +| map.cpp:449:13:449:13 | call to operator[] | map.cpp:450:8:450:8 | q | | | movableclass.cpp:8:2:8:15 | this | movableclass.cpp:8:27:8:31 | constructor init of field v [pre-this] | | | movableclass.cpp:8:21:8:22 | _v | movableclass.cpp:8:29:8:30 | _v | | | movableclass.cpp:8:29:8:30 | _v | movableclass.cpp:8:27:8:31 | constructor init of field v | TAINT | @@ -6609,6 +6622,27 @@ WARNING: Module TaintTracking has been deprecated and may be removed in future ( | taint.cpp:711:13:711:13 | s | taint.cpp:711:2:711:8 | call to strncpy | TAINT | | taint.cpp:711:13:711:13 | s | taint.cpp:711:10:711:10 | ref arg d | TAINT | | taint.cpp:712:7:712:7 | ref arg d | taint.cpp:709:25:709:25 | d | | +| taint.cpp:718:17:718:31 | call to indirect_source | taint.cpp:720:27:720:32 | source | | +| taint.cpp:719:22:719:29 | ,.-;:_ | taint.cpp:720:35:720:39 | delim | | +| taint.cpp:719:22:719:29 | ,.-;:_ | taint.cpp:722:8:722:12 | delim | | +| taint.cpp:720:20:720:25 | call to strtok | taint.cpp:721:8:721:16 | tokenized | | +| taint.cpp:720:27:720:32 | source | taint.cpp:720:20:720:25 | call to strtok | TAINT | +| taint.cpp:721:8:721:16 | tokenized | taint.cpp:721:7:721:16 | * ... | TAINT | +| taint.cpp:722:8:722:12 | delim | taint.cpp:722:7:722:12 | * ... | TAINT | +| taint.cpp:727:24:727:29 | source | taint.cpp:727:24:727:29 | source | | +| taint.cpp:727:24:727:29 | source | taint.cpp:729:18:729:23 | source | | +| taint.cpp:728:17:728:23 | 0 | taint.cpp:729:27:729:32 | endptr | | +| taint.cpp:728:17:728:23 | 0 | taint.cpp:731:7:731:12 | endptr | | +| taint.cpp:728:17:728:23 | 0 | taint.cpp:732:8:732:13 | endptr | | +| taint.cpp:729:11:729:16 | call to strtol | taint.cpp:730:7:730:7 | l | | +| taint.cpp:729:18:729:23 | source | taint.cpp:729:11:729:16 | call to strtol | TAINT | +| taint.cpp:729:18:729:23 | source | taint.cpp:729:26:729:32 | ref arg & ... | TAINT | +| taint.cpp:729:26:729:32 | ref arg & ... | taint.cpp:729:27:729:32 | endptr [inner post update] | | +| taint.cpp:729:26:729:32 | ref arg & ... | taint.cpp:731:7:731:12 | endptr | | +| taint.cpp:729:26:729:32 | ref arg & ... | taint.cpp:732:8:732:13 | endptr | | +| taint.cpp:729:27:729:32 | endptr | taint.cpp:729:26:729:32 | & ... | | +| taint.cpp:731:7:731:12 | ref arg endptr | taint.cpp:732:8:732:13 | endptr | | +| taint.cpp:732:8:732:13 | endptr | taint.cpp:732:7:732:13 | * ... | TAINT | | vector.cpp:16:43:16:49 | source1 | vector.cpp:17:26:17:32 | source1 | | | vector.cpp:16:43:16:49 | source1 | vector.cpp:31:38:31:44 | source1 | | | vector.cpp:17:21:17:33 | call to vector | vector.cpp:19:14:19:14 | v | | diff --git a/cpp/ql/test/library-tests/dataflow/taint-tests/map.cpp b/cpp/ql/test/library-tests/dataflow/taint-tests/map.cpp index 404d6627b27f..8eeb80a0f83e 100644 --- a/cpp/ql/test/library-tests/dataflow/taint-tests/map.cpp +++ b/cpp/ql/test/library-tests/dataflow/taint-tests/map.cpp @@ -436,3 +436,16 @@ void test_unordered_map() sink(m35.emplace(std::pair(source(), "def")).first); // $ MISSING: ast,ir sink(m35); // $ MISSING: ast,ir } + +namespace { + int* indirect_source(); + void indirect_sink(int*); +} + +void test_indirect_taint() { + std::map m; + int* p = indirect_source(); + m[1] = p; + int* q = m[1]; + sink(q); // $ ir MISSING: ast +} \ No newline at end of file diff --git a/cpp/ql/test/library-tests/dataflow/taint-tests/taint.cpp b/cpp/ql/test/library-tests/dataflow/taint-tests/taint.cpp index 2df0fc85bb6f..e479d7a11e01 100644 --- a/cpp/ql/test/library-tests/dataflow/taint-tests/taint.cpp +++ b/cpp/ql/test/library-tests/dataflow/taint-tests/taint.cpp @@ -710,4 +710,24 @@ void test_strncpy(char* d, char* s) { argument_source(s); strncpy(d, s, 16); sink(d); // $ ast ir +} + +char* indirect_source(); + +void test_strtok_indirect() { + char *source = indirect_source(); + const char* delim = ",.-;:_"; + char* tokenized = strtok(source, delim); + sink(*tokenized); // $ ir MISSING: ast + sink(*delim); +} + +long int strtol(const char*, char**, int); + +void test_strtol(char *source) { + char* endptr = nullptr; + long l = strtol(source, &endptr, 10); + sink(l); // $ ast,ir + sink(endptr); // $ ast,ir + sink(*endptr); // $ ast,ir } \ No newline at end of file diff --git a/cpp/ql/test/library-tests/dataflow/taint-tests/taint.ql b/cpp/ql/test/library-tests/dataflow/taint-tests/taint.ql index ef79f0659210..56c8cd8ba684 100644 --- a/cpp/ql/test/library-tests/dataflow/taint-tests/taint.ql +++ b/cpp/ql/test/library-tests/dataflow/taint-tests/taint.ql @@ -84,6 +84,8 @@ module IRTest { or source.asIndirectExpr().(FunctionCall).getTarget().getName() = "source" or + source.asIndirectExpr().(FunctionCall).getTarget().getName() = "indirect_source" + or source.asParameter().getName().matches("source%") or exists(FunctionCall fc | diff --git a/cpp/ql/test/library-tests/ir/ir/PrintAST.expected b/cpp/ql/test/library-tests/ir/ir/PrintAST.expected index d714f52629b3..10f1c32005b0 100644 --- a/cpp/ql/test/library-tests/ir/ir/PrintAST.expected +++ b/cpp/ql/test/library-tests/ir/ir/PrintAST.expected @@ -15938,6 +15938,44 @@ ir.cpp: # 2104| Type = [CTypedefType,Size_t] size_t # 2104| ValueCategory = prvalue(load) # 2105| getStmt(6): [ReturnStmt] return ... +# 2107| [TopLevelFunction] double strtod(char const*, char**) +# 2107| : +# 2107| getParameter(0): [Parameter] str +# 2107| Type = [PointerType] const char * +# 2107| getParameter(1): [Parameter] endptr +# 2107| Type = [PointerType] char ** +# 2109| [TopLevelFunction] char* test_strtod(char*) +# 2109| : +# 2109| getParameter(0): [Parameter] s +# 2109| Type = [CharPointerType] char * +# 2109| getEntryPoint(): [BlockStmt] { ... } +# 2110| getStmt(0): [DeclStmt] declaration +# 2110| getDeclarationEntry(0): [VariableDeclarationEntry] definition of end +# 2110| Type = [CharPointerType] char * +# 2111| getStmt(1): [DeclStmt] declaration +# 2111| getDeclarationEntry(0): [VariableDeclarationEntry] definition of d +# 2111| Type = [DoubleType] double +# 2111| getVariable().getInitializer(): [Initializer] initializer for d +# 2111| getExpr(): [FunctionCall] call to strtod +# 2111| Type = [DoubleType] double +# 2111| ValueCategory = prvalue +# 2111| getArgument(0): [VariableAccess] s +# 2111| Type = [CharPointerType] char * +# 2111| ValueCategory = prvalue(load) +# 2111| getArgument(1): [AddressOfExpr] & ... +# 2111| Type = [PointerType] char ** +# 2111| ValueCategory = prvalue +# 2111| getOperand(): [VariableAccess] end +# 2111| Type = [CharPointerType] char * +# 2111| ValueCategory = lvalue +# 2111| getArgument(0).getFullyConverted(): [CStyleCast] (const char *)... +# 2111| Conversion = [PointerConversion] pointer conversion +# 2111| Type = [PointerType] const char * +# 2111| ValueCategory = prvalue +# 2112| getStmt(2): [ReturnStmt] return ... +# 2112| getExpr(): [VariableAccess] end +# 2112| Type = [CharPointerType] char * +# 2112| ValueCategory = prvalue(load) perf-regression.cpp: # 4| [CopyAssignmentOperator] Big& Big::operator=(Big const&) # 4| : diff --git a/cpp/ql/test/library-tests/ir/ir/aliased_ir.expected b/cpp/ql/test/library-tests/ir/ir/aliased_ir.expected index 150bed79ef4e..d7e3c36d204a 100644 --- a/cpp/ql/test/library-tests/ir/ir/aliased_ir.expected +++ b/cpp/ql/test/library-tests/ir/ir/aliased_ir.expected @@ -12333,6 +12333,40 @@ ir.cpp: # 2098| v2098_8(void) = AliasedUse : ~m2104_8 # 2098| v2098_9(void) = ExitFunction : +# 2109| char* test_strtod(char*) +# 2109| Block 0 +# 2109| v2109_1(void) = EnterFunction : +# 2109| m2109_2(unknown) = AliasedDefinition : +# 2109| m2109_3(unknown) = InitializeNonLocal : +# 2109| m2109_4(unknown) = Chi : total:m2109_2, partial:m2109_3 +# 2109| r2109_5(glval) = VariableAddress[s] : +# 2109| m2109_6(char *) = InitializeParameter[s] : &:r2109_5 +# 2109| r2109_7(char *) = Load[s] : &:r2109_5, m2109_6 +# 2109| m2109_8(unknown) = InitializeIndirection[s] : &:r2109_7 +# 2110| r2110_1(glval) = VariableAddress[end] : +# 2110| m2110_2(char *) = Uninitialized[end] : &:r2110_1 +# 2111| r2111_1(glval) = VariableAddress[d] : +# 2111| r2111_2(glval) = FunctionAddress[strtod] : +# 2111| r2111_3(glval) = VariableAddress[s] : +# 2111| r2111_4(char *) = Load[s] : &:r2111_3, m2109_6 +# 2111| r2111_5(char *) = Convert : r2111_4 +# 2111| r2111_6(glval) = VariableAddress[end] : +# 2111| r2111_7(char **) = CopyValue : r2111_6 +# 2111| r2111_8(double) = Call[strtod] : func:r2111_2, 0:r2111_5, 1:r2111_7 +# 2111| v2111_9(void) = ^BufferReadSideEffect[0] : &:r2111_5, ~m2109_8 +# 2111| m2111_10(char *) = ^IndirectMayWriteSideEffect[1] : &:r2111_7 +# 2111| m2111_11(char *) = Chi : total:m2110_2, partial:m2111_10 +# 2111| m2111_12(double) = Store[d] : &:r2111_1, r2111_8 +# 2112| r2112_1(glval) = VariableAddress[#return] : +# 2112| r2112_2(glval) = VariableAddress[end] : +# 2112| r2112_3(char *) = Load[end] : &:r2112_2, m2111_11 +# 2112| m2112_4(char *) = Store[#return] : &:r2112_1, r2112_3 +# 2109| v2109_9(void) = ReturnIndirection[s] : &:r2109_7, m2109_8 +# 2109| r2109_10(glval) = VariableAddress[#return] : +# 2109| v2109_11(void) = ReturnValue : &:r2109_10, m2112_4 +# 2109| v2109_12(void) = AliasedUse : m2109_3 +# 2109| v2109_13(void) = ExitFunction : + perf-regression.cpp: # 6| void Big::Big() # 6| Block 0 diff --git a/cpp/ql/test/library-tests/ir/ir/ir.cpp b/cpp/ql/test/library-tests/ir/ir/ir.cpp index 813f7c2448a9..adaae6b7e593 100644 --- a/cpp/ql/test/library-tests/ir/ir/ir.cpp +++ b/cpp/ql/test/library-tests/ir/ir/ir.cpp @@ -2104,4 +2104,12 @@ void newArrayCorrectType(size_t n) { new int[n] { 0, 1, 2 }; } +double strtod (const char* str, char** endptr); + +char* test_strtod(char *s) { + char *end; + double d = strtod(s, &end); + return end; +} + // semmle-extractor-options: -std=c++17 --clang diff --git a/cpp/ql/test/library-tests/ir/ir/operand_locations.expected b/cpp/ql/test/library-tests/ir/ir/operand_locations.expected index af1939abd03c..39d238c1faed 100644 --- a/cpp/ql/test/library-tests/ir/ir/operand_locations.expected +++ b/cpp/ql/test/library-tests/ir/ir/operand_locations.expected @@ -10004,6 +10004,36 @@ | ir.cpp:2104:11:2104:11 | Address | &:r2104_2 | | ir.cpp:2104:11:2104:11 | Left | r2104_3 | | ir.cpp:2104:11:2104:11 | Load | m2098_6 | +| ir.cpp:2109:7:2109:17 | Address | &:r2109_10 | +| ir.cpp:2109:7:2109:17 | ChiPartial | partial:m2109_3 | +| ir.cpp:2109:7:2109:17 | ChiTotal | total:m2109_2 | +| ir.cpp:2109:7:2109:17 | Load | m2112_4 | +| ir.cpp:2109:7:2109:17 | SideEffect | m2109_3 | +| ir.cpp:2109:25:2109:25 | Address | &:r2109_5 | +| ir.cpp:2109:25:2109:25 | Address | &:r2109_5 | +| ir.cpp:2109:25:2109:25 | Address | &:r2109_7 | +| ir.cpp:2109:25:2109:25 | Address | &:r2109_7 | +| ir.cpp:2109:25:2109:25 | Load | m2109_6 | +| ir.cpp:2109:25:2109:25 | SideEffect | m2109_8 | +| ir.cpp:2110:9:2110:11 | Address | &:r2110_1 | +| ir.cpp:2111:10:2111:10 | Address | &:r2111_1 | +| ir.cpp:2111:14:2111:19 | CallTarget | func:r2111_2 | +| ir.cpp:2111:14:2111:19 | StoreValue | r2111_8 | +| ir.cpp:2111:21:2111:21 | Address | &:r2111_3 | +| ir.cpp:2111:21:2111:21 | Address | &:r2111_5 | +| ir.cpp:2111:21:2111:21 | Arg(0) | 0:r2111_5 | +| ir.cpp:2111:21:2111:21 | Load | m2109_6 | +| ir.cpp:2111:21:2111:21 | SideEffect | ~m2109_8 | +| ir.cpp:2111:21:2111:21 | Unary | r2111_4 | +| ir.cpp:2111:24:2111:27 | Address | &:r2111_7 | +| ir.cpp:2111:24:2111:27 | Arg(1) | 1:r2111_7 | +| ir.cpp:2111:24:2111:27 | ChiPartial | partial:m2111_10 | +| ir.cpp:2111:24:2111:27 | ChiTotal | total:m2110_2 | +| ir.cpp:2111:25:2111:27 | Unary | r2111_6 | +| ir.cpp:2112:3:2112:13 | Address | &:r2112_1 | +| ir.cpp:2112:10:2112:12 | Address | &:r2112_2 | +| ir.cpp:2112:10:2112:12 | Load | m2111_11 | +| ir.cpp:2112:10:2112:12 | StoreValue | r2112_3 | | perf-regression.cpp:6:3:6:5 | Address | &:r6_5 | | perf-regression.cpp:6:3:6:5 | Address | &:r6_5 | | perf-regression.cpp:6:3:6:5 | Address | &:r6_7 | diff --git a/cpp/ql/test/library-tests/ir/ir/raw_ir.expected b/cpp/ql/test/library-tests/ir/ir/raw_ir.expected index c4774b10f89d..f43a105f70ae 100644 --- a/cpp/ql/test/library-tests/ir/ir/raw_ir.expected +++ b/cpp/ql/test/library-tests/ir/ir/raw_ir.expected @@ -11538,6 +11538,38 @@ ir.cpp: # 2098| v2098_7(void) = AliasedUse : ~m? # 2098| v2098_8(void) = ExitFunction : +# 2109| char* test_strtod(char*) +# 2109| Block 0 +# 2109| v2109_1(void) = EnterFunction : +# 2109| mu2109_2(unknown) = AliasedDefinition : +# 2109| mu2109_3(unknown) = InitializeNonLocal : +# 2109| r2109_4(glval) = VariableAddress[s] : +# 2109| mu2109_5(char *) = InitializeParameter[s] : &:r2109_4 +# 2109| r2109_6(char *) = Load[s] : &:r2109_4, ~m? +# 2109| mu2109_7(unknown) = InitializeIndirection[s] : &:r2109_6 +# 2110| r2110_1(glval) = VariableAddress[end] : +# 2110| mu2110_2(char *) = Uninitialized[end] : &:r2110_1 +# 2111| r2111_1(glval) = VariableAddress[d] : +# 2111| r2111_2(glval) = FunctionAddress[strtod] : +# 2111| r2111_3(glval) = VariableAddress[s] : +# 2111| r2111_4(char *) = Load[s] : &:r2111_3, ~m? +# 2111| r2111_5(char *) = Convert : r2111_4 +# 2111| r2111_6(glval) = VariableAddress[end] : +# 2111| r2111_7(char **) = CopyValue : r2111_6 +# 2111| r2111_8(double) = Call[strtod] : func:r2111_2, 0:r2111_5, 1:r2111_7 +# 2111| v2111_9(void) = ^BufferReadSideEffect[0] : &:r2111_5, ~m? +# 2111| mu2111_10(char *) = ^IndirectMayWriteSideEffect[1] : &:r2111_7 +# 2111| mu2111_11(double) = Store[d] : &:r2111_1, r2111_8 +# 2112| r2112_1(glval) = VariableAddress[#return] : +# 2112| r2112_2(glval) = VariableAddress[end] : +# 2112| r2112_3(char *) = Load[end] : &:r2112_2, ~m? +# 2112| mu2112_4(char *) = Store[#return] : &:r2112_1, r2112_3 +# 2109| v2109_8(void) = ReturnIndirection[s] : &:r2109_6, ~m? +# 2109| r2109_9(glval) = VariableAddress[#return] : +# 2109| v2109_10(void) = ReturnValue : &:r2109_9, ~m? +# 2109| v2109_11(void) = AliasedUse : ~m? +# 2109| v2109_12(void) = ExitFunction : + perf-regression.cpp: # 6| void Big::Big() # 6| Block 0 diff --git a/cpp/ql/test/library-tests/ir/range-analysis/test.cpp b/cpp/ql/test/library-tests/ir/range-analysis/test.cpp index ff9acbfae1a4..61d171029483 100644 --- a/cpp/ql/test/library-tests/ir/range-analysis/test.cpp +++ b/cpp/ql/test/library-tests/ir/range-analysis/test.cpp @@ -56,7 +56,7 @@ while (f3_get(n)) n+=2; for (int i = 0; i < n; i += 2) { - range(i); // $ range=>=0 SPURIOUS: range="<=Phi: call to f3_get-1" range="<=Phi: call to f3_get-2" + range(i); // $ range=>=0 range="<=Phi: call to f3_get-2" } } @@ -117,3 +117,16 @@ void test_sub(int x, int y, int n) { } } } + +void test_div(int x) { + if (3 <= x && x <= 7) { + range(x / 2); // $ range=>=1 range=<=3 + range(x / 3); // $ range=>=1 range=<=2 + range(x >> 2); // $ range=>=0 range=<=1 + } + if (2 <= x && x <= 8) { + range(x / 2); // $ range=>=1 range=<=4 + range(x / 3); // $ range=>=0 range=<=2 + range(x >> 2); // $ range=>=0 range=<=2 + } +} diff --git a/cpp/ql/test/query-tests/Critical/MemoryFreed/MemoryFreed.expected b/cpp/ql/test/query-tests/Critical/MemoryFreed/MemoryFreed.expected index 141b7091d191..f5a3553ce542 100644 --- a/cpp/ql/test/query-tests/Critical/MemoryFreed/MemoryFreed.expected +++ b/cpp/ql/test/query-tests/Critical/MemoryFreed/MemoryFreed.expected @@ -97,6 +97,10 @@ | test_free.cpp:260:9:260:9 | p | | test_free.cpp:263:12:263:12 | p | | test_free.cpp:269:7:269:11 | ... = ... | +| test_free.cpp:277:11:277:13 | buf | +| test_free.cpp:282:10:282:12 | buf | +| test_free.cpp:288:8:288:10 | buf | +| test_free.cpp:293:8:293:10 | buf | | virtual.cpp:18:10:18:10 | a | | virtual.cpp:19:10:19:10 | c | | virtual.cpp:38:10:38:10 | b | diff --git a/cpp/ql/test/query-tests/Critical/MemoryFreed/UseAfterFree.expected b/cpp/ql/test/query-tests/Critical/MemoryFreed/UseAfterFree.expected index b4ac51dc72e9..6df347582cb8 100644 --- a/cpp/ql/test/query-tests/Critical/MemoryFreed/UseAfterFree.expected +++ b/cpp/ql/test/query-tests/Critical/MemoryFreed/UseAfterFree.expected @@ -12,6 +12,10 @@ edges | test_free.cpp:233:14:233:15 | * ... | test_free.cpp:236:9:236:10 | * ... | | test_free.cpp:239:14:239:15 | * ... | test_free.cpp:241:9:241:10 | * ... | | test_free.cpp:245:10:245:11 | * ... | test_free.cpp:246:9:246:10 | * ... | +| test_free.cpp:293:8:293:10 | buf | test_free.cpp:294:3:294:13 | ... = ... | +| test_free.cpp:294:3:294:13 | ... = ... | test_free.cpp:294:5:294:7 | s indirection [post update] [buf] | +| test_free.cpp:294:5:294:7 | s indirection [post update] [buf] | test_free.cpp:295:12:295:12 | s indirection [buf] | +| test_free.cpp:295:12:295:12 | s indirection [buf] | test_free.cpp:295:14:295:16 | buf | nodes | test_free.cpp:11:10:11:10 | a | semmle.label | a | | test_free.cpp:12:5:12:5 | a | semmle.label | a | @@ -38,6 +42,11 @@ nodes | test_free.cpp:241:9:241:10 | * ... | semmle.label | * ... | | test_free.cpp:245:10:245:11 | * ... | semmle.label | * ... | | test_free.cpp:246:9:246:10 | * ... | semmle.label | * ... | +| test_free.cpp:293:8:293:10 | buf | semmle.label | buf | +| test_free.cpp:294:3:294:13 | ... = ... | semmle.label | ... = ... | +| test_free.cpp:294:5:294:7 | s indirection [post update] [buf] | semmle.label | s indirection [post update] [buf] | +| test_free.cpp:295:12:295:12 | s indirection [buf] | semmle.label | s indirection [buf] | +| test_free.cpp:295:14:295:16 | buf | semmle.label | buf | subpaths #select | test_free.cpp:12:5:12:5 | a | test_free.cpp:11:10:11:10 | a | test_free.cpp:12:5:12:5 | a | Memory may have been previously freed by $@. | test_free.cpp:11:5:11:8 | call to free | call to free | @@ -53,3 +62,4 @@ subpaths | test_free.cpp:236:9:236:10 | * ... | test_free.cpp:233:14:233:15 | * ... | test_free.cpp:236:9:236:10 | * ... | Memory may have been previously freed by $@. | test_free.cpp:233:9:233:12 | call to free | call to free | | test_free.cpp:241:9:241:10 | * ... | test_free.cpp:239:14:239:15 | * ... | test_free.cpp:241:9:241:10 | * ... | Memory may have been previously freed by $@. | test_free.cpp:239:9:239:12 | call to free | call to free | | test_free.cpp:246:9:246:10 | * ... | test_free.cpp:245:10:245:11 | * ... | test_free.cpp:246:9:246:10 | * ... | Memory may have been previously freed by $@. | test_free.cpp:245:5:245:8 | call to free | call to free | +| test_free.cpp:295:14:295:16 | buf | test_free.cpp:293:8:293:10 | buf | test_free.cpp:295:14:295:16 | buf | Memory may have been previously freed by $@. | test_free.cpp:293:3:293:6 | call to free | call to free | diff --git a/cpp/ql/test/query-tests/Critical/MemoryFreed/test_free.cpp b/cpp/ql/test/query-tests/Critical/MemoryFreed/test_free.cpp index b9ea0ec6fbf3..5c6d2e4c3595 100644 --- a/cpp/ql/test/query-tests/Critical/MemoryFreed/test_free.cpp +++ b/cpp/ql/test/query-tests/Critical/MemoryFreed/test_free.cpp @@ -267,4 +267,30 @@ void test_free_assign() { void *a = malloc(10); void *b; free(b = a); // GOOD +} + +struct MyStruct { + char* buf; +}; + +void test_free_struct(MyStruct* s) { + free(s->buf); + char c = s->buf[0]; // BAD [FALSE NEGATIVE] +} + +void test_free_struct2(MyStruct s) { + free(s.buf); + char c = s.buf[0]; // BAD [FALSE NEGATIVE] +} + +void test_free_struct3(MyStruct s) { + char* buf = s.buf; + free(buf); + char c = s.buf[0]; // BAD [FALSE NEGATIVE] +} + +void test_free_struct4(char* buf, MyStruct s) { + free(buf); + s.buf = buf; + char c = s.buf[0]; // BAD } \ No newline at end of file diff --git a/csharp/extractor/Semmle.Extraction.CSharp.StubGenerator/StubVisitor.cs b/csharp/extractor/Semmle.Extraction.CSharp.StubGenerator/StubVisitor.cs index 664188c41c22..e29cd532a5ce 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp.StubGenerator/StubVisitor.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp.StubGenerator/StubVisitor.cs @@ -186,7 +186,8 @@ private void StubTypedConstant(TypedConstant c) } break; case TypedConstantKind.Enum: - stubWriter.Write("throw null"); + stubWriter.Write($"({c.Type!.GetQualifiedName()}) "); + stubWriter.Write(c.Value!.ToString()); break; case TypedConstantKind.Array: stubWriter.Write("new []{"); @@ -200,7 +201,8 @@ private void StubTypedConstant(TypedConstant c) } private static readonly HashSet attributeAllowList = new() { - "System.FlagsAttribute" + "System.FlagsAttribute", + "System.AttributeUsageAttribute" }; private void StubAttribute(AttributeData a, string prefix) @@ -219,6 +221,14 @@ private void StubAttribute(AttributeData a, string prefix) { stubWriter.Write("("); WriteCommaSep(a.ConstructorArguments, StubTypedConstant); + if (a.ConstructorArguments.Any() && a.NamedArguments.Any()) + stubWriter.Write(","); + WriteCommaSep(a.NamedArguments, arg => + { + stubWriter.Write(arg.Key); + stubWriter.Write(" = "); + StubTypedConstant(arg.Value); + }); stubWriter.Write(")"); } stubWriter.WriteLine("]"); diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Attribute.cs b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Attribute.cs index d0130385f42c..08e8f391a342 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Attribute.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Attribute.cs @@ -82,10 +82,16 @@ private void ExtractArguments(TextWriter trapFile) var paramName = Symbol.AttributeConstructor?.Parameters[i].Name; var argSyntax = ctorArguments?.SingleOrDefault(a => a.NameColon is not null && a.NameColon.Name.Identifier.Text == paramName); + var isParamsParameter = false; + if (argSyntax is null && // couldn't find named argument ctorArguments?.Count > childIndex && // there're more arguments ctorArguments[childIndex].NameColon is null) // the argument is positional { + // The current argument is not named + // so the previous ones were also not named + // so the child index matches the parameter index. + isParamsParameter = Symbol?.AttributeConstructor?.Parameters[childIndex].IsParams == true; argSyntax = ctorArguments[childIndex]; } @@ -94,6 +100,28 @@ private void ExtractArguments(TextWriter trapFile) argSyntax?.Expression, this, childIndex++); + + if (isParamsParameter && + ctorArguments is not null) + { + // The current argument is a params argument, so we're processing all the remaining arguments: + while (childIndex < ctorArguments.Count) + { + if (ctorArguments[childIndex].Expression is null) + { + // This shouldn't happen + continue; + } + + CreateExpressionFromArgument( + constructorArgument, + ctorArguments[childIndex].Expression, + this, + childIndex); + + childIndex++; + } + } } foreach (var namedArgument in Symbol.NamedArguments) diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/Bound.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/Bound.qll index b881161f66f5..08826b7ae8f1 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/Bound.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/Bound.qll @@ -25,16 +25,8 @@ abstract class Bound extends TBound { /** Gets an expression that equals this bound. */ Expr getExpr() { result = this.getExpr(0) } - /** - * Holds if this element is at the specified location. - * The location spans column `sc` of line `sl` to - * column `ec` of line `el` in file `path`. - * For more information, see - * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). - */ - predicate hasLocationInfo(string path, int sl, int sc, int el, int ec) { - path = "" and sl = 0 and sc = 0 and el = 0 and ec = 0 - } + /** Gets the location of this bound. */ + abstract Location getLocation(); } /** @@ -45,6 +37,8 @@ class ZeroBound extends Bound, TBoundZero { override string toString() { result = "0" } override Expr getExpr(int delta) { result.(ConstantIntegerExpr).getIntValue() = delta } + + override Location getLocation() { result.hasLocationInfo("", 0, 0, 0, 0) } } /** @@ -58,9 +52,7 @@ class SsaBound extends Bound, TBoundSsa { override Expr getExpr(int delta) { result = this.getSsa().getAUse() and delta = 0 } - override predicate hasLocationInfo(string path, int sl, int sc, int el, int ec) { - this.getSsa().getLocation().hasLocationInfo(path, sl, sc, el, ec) - } + override Location getLocation() { result = this.getSsa().getLocation() } } /** @@ -72,7 +64,5 @@ class ExprBound extends Bound, TBoundExpr { override Expr getExpr(int delta) { this = TBoundExpr(result) and delta = 0 } - override predicate hasLocationInfo(string path, int sl, int sc, int el, int ec) { - this.getExpr().getLocation().hasLocationInfo(path, sl, sc, el, ec) - } + override Location getLocation() { result = this.getExpr().getLocation() } } diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/rangeanalysis/BoundSpecific.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/rangeanalysis/BoundSpecific.qll index 3515f2f96c82..3885c11afd14 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/rangeanalysis/BoundSpecific.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/rangeanalysis/BoundSpecific.qll @@ -12,6 +12,8 @@ class SsaVariable = SU::SsaVariable; class Expr = CS::ControlFlow::Nodes::ExprNode; +class Location = CS::Location; + class IntegralType = CS::IntegralType; class ConstantIntegerExpr = CU::ConstantIntegerExpr; diff --git a/csharp/ql/src/Stubs/AllStubsFromReference.ql b/csharp/ql/src/Stubs/AllStubsFromReference.ql deleted file mode 100644 index e8d0debb3169..000000000000 --- a/csharp/ql/src/Stubs/AllStubsFromReference.ql +++ /dev/null @@ -1,15 +0,0 @@ -/** - * Tool to generate C# stubs from a qltest snapshot. - */ - -import csharp -import Stubs - -/** All public declarations from assemblies. */ -class AllExternalPublicDeclarations extends GeneratedDeclaration { - AllExternalPublicDeclarations() { this.fromLibrary() } -} - -from Assembly a -select a.getFullName(), a.getName(), a.getVersion().toString(), a.getFile().getAbsolutePath(), - generatedCode(a) diff --git a/csharp/ql/src/Stubs/AllStubsFromSource.ql b/csharp/ql/src/Stubs/AllStubsFromSource.ql deleted file mode 100644 index 1a8a816b72ff..000000000000 --- a/csharp/ql/src/Stubs/AllStubsFromSource.ql +++ /dev/null @@ -1,22 +0,0 @@ -/** - * Tool to generate C# stubs from a qltest snapshot. - */ - -import csharp -import Stubs - -/** All public declarations from source. */ -class AllDeclarations extends GeneratedDeclaration { - AllDeclarations() { not this.fromLibrary() } -} - -/** Exclude types from these standard assemblies. */ -private class DefaultLibs extends ExcludedAssembly { - DefaultLibs() { - this.getName() = "System.Private.CoreLib" or - this.getName() = "mscorlib" or - this.getName() = "System.Runtime" - } -} - -select concat(generatedCode(_) + "\n\n") diff --git a/csharp/ql/src/Stubs/MinimalStubsFromSource.ql b/csharp/ql/src/Stubs/MinimalStubsFromSource.ql deleted file mode 100644 index 14df8576caa5..000000000000 --- a/csharp/ql/src/Stubs/MinimalStubsFromSource.ql +++ /dev/null @@ -1,41 +0,0 @@ -/** - * Tool to generate C# stubs from a qltest snapshot. - * - * It finds all declarations used in the source code, - * and generates minimal C# stubs containing those declarations - * and their dependencies. - */ - -import csharp -import Stubs - -/** Declarations used by source code. */ -class UsedInSource extends GeneratedDeclaration { - UsedInSource() { - ( - this = any(Access a).getTarget() - or - this = any(Call c).getTarget() - or - this = any(TypeMention tm).getType() - or - exists(Virtualizable v | v.fromSource() | - this = v.getImplementee() or this = v.getOverridee() - ) - or - this = any(Attribute a).getType().getAConstructor() - ) and - this.fromLibrary() - } -} - -/** Exclude types from these standard assemblies. */ -private class DefaultLibs extends ExcludedAssembly { - DefaultLibs() { - this.getName() = "System.Private.CoreLib" or - this.getName() = "mscorlib" or - this.getName() = "System.Runtime" - } -} - -select concat(generatedCode(_) + "\n\n") diff --git a/csharp/ql/src/Stubs/Stubs.qll b/csharp/ql/src/Stubs/Stubs.qll deleted file mode 100644 index 78cd18c34ec8..000000000000 --- a/csharp/ql/src/Stubs/Stubs.qll +++ /dev/null @@ -1,965 +0,0 @@ -/** - * Generates C# stubs for use in test code. - * - * Extend the abstract class `GeneratedDeclaration` with the declarations that should be generated. - * This will generate stubs for all the required dependencies as well. - * - * Use - * ```ql - * select generatedCode() - * ``` - * to retrieve the generated C# code. - */ - -import csharp -private import semmle.code.csharp.commons.QualifiedName -private import semmle.code.csharp.frameworks.System -private import semmle.code.dotnet.DotNet as DotNet // added to handle VoidType as a ValueOrRefType - -/** An element that should be in the generated code. */ -abstract class GeneratedElement extends Element { } - -/** A member that should be in the generated code. */ -abstract class GeneratedMember extends Member, GeneratedElement { } - -/** Class representing all `struct`s, such as user defined ones and built-in ones, like `int`. */ -private class StructExt extends Type { - StructExt() { - this instanceof Struct or - this instanceof SimpleType or - this instanceof VoidType or - this instanceof SystemIntPtrType - } -} - -/** A type that should be in the generated code. */ -abstract private class GeneratedType extends Type, GeneratedElement { - GeneratedType() { - ( - this instanceof Interface - or - this instanceof Class - or - this instanceof StructExt - or - this instanceof Enum - or - this instanceof DelegateType - ) and - not this instanceof ConstructedType and - not this.getALocation() instanceof ExcludedAssembly - } - - /** - * Holds if this type is defined in multiple assemblies, and at least one of - * them is in the `Microsoft.NETCore.App.Ref` folder. In this case, we only stub - * the type in the assembly in `Microsoft.NETCore.App.Ref`. In case there are - * multiple assemblies in this folder, then we prefer `System.Runtime`. - */ - private predicate isDuplicate(Assembly assembly) { - // type exists in multiple assemblies - count(this.getALocation().(Assembly)) > 1 and - // at least one of them is in the `Microsoft.NETCore.App.Ref` folder - this.getALocation() - .(Assembly) - .getFile() - .getAbsolutePath() - .matches("%Microsoft.NETCore.App.Ref%") and - exists(int i | - i = - count(Assembly a | - this.getALocation() = a and - a.getFile().getAbsolutePath().matches("%Microsoft.NETCore.App.Ref%") - ) - | - i = 1 and - // assemblies not in `Microsoft.NETCore.App.Ref` folder are considered duplicates - not assembly.getFile().getAbsolutePath().matches("%Microsoft.NETCore.App.Ref%") - or - i > 1 and - // one of the assemblies is named `System.Runtime` - this.getALocation().(Assembly).getName() = "System.Runtime" and - // all others are considered duplicates - assembly.getName() != "System.Runtime" - ) - } - - predicate isInAssembly(Assembly assembly) { this.getALocation() = assembly } - - private string stubKeyword() { - this instanceof Interface and result = "interface" - or - this instanceof StructExt and result = "struct" - or - this instanceof Class and result = "class" - or - this instanceof Enum and result = "enum" - or - this instanceof DelegateType and result = "delegate" - } - - private string stubAbstractModifier() { - if this.(Class).isAbstract() then result = "abstract " else result = "" - } - - private string stubStaticModifier() { - if this.isStatic() then result = "static " else result = "" - } - - private string stubPartialModifier() { - if - count(Assembly a | this.getALocation() = a) <= 1 or - this instanceof Enum - then result = "" - else result = "partial " - } - - private string stubAttributes() { - if this.(ValueOrRefType).getAnAttribute().getType().hasQualifiedName("System", "FlagsAttribute") - then result = "[System.Flags]\n" - else result = "" - } - - /** Gets the entire C# stub code for this type. */ - pragma[nomagic] - final string getStub(Assembly assembly) { - this.isInAssembly(assembly) and - if this.isDuplicate(assembly) - then - result = - "/* Duplicate type '" + this.getName() + "' is not stubbed in this assembly '" + - assembly.toString() + "'. */\n\n" - else ( - not this instanceof DelegateType and - result = - this.stubAttributes() + stubUnsafe(this) + stubAccessibility(this) + - this.stubAbstractModifier() + this.stubStaticModifier() + this.stubPartialModifier() + - this.stubKeyword() + " " + this.getUndecoratedName() + stubGenericArguments(this) + - this.stubBaseTypesString() + stubTypeParametersConstraints(this) + "\n{\n" + - this.stubPrivateConstructor() + this.stubMembers(assembly) + "}\n\n" - or - result = - this.stubAttributes() + stubUnsafe(this) + stubAccessibility(this) + this.stubKeyword() + - " " + stubClassName(this.(DelegateType).getReturnType()) + " " + this.getUndecoratedName() - + stubGenericArguments(this) + "(" + stubParameters(this) + ");\n\n" - ) - } - - private ValueOrRefType getAnInterestingBaseType() { - result = this.(ValueOrRefType).getABaseType() and - not result instanceof ObjectType and - not result.hasQualifiedName("System", "ValueType") and - (not result instanceof Interface or result.(Interface).isEffectivelyPublic()) - } - - private string stubBaseTypesString() { - if this instanceof Enum - then result = " : " + this.(Enum).getUnderlyingType().toStringWithTypes() - else - if exists(this.getAnInterestingBaseType()) - then - result = - " : " + - concat(int i, ValueOrRefType t | - t = this.getAnInterestingBaseType() and - (if t instanceof Class then i = 0 else i = 1) - | - stubClassName(t), ", " order by i, t.getQualifiedName() - ) - else result = "" - } - - language[monotonicAggregates] - private string stubMembers(Assembly assembly) { - result = - concat(GeneratedMember m | - m = this.getAGeneratedMember(assembly) - | - stubMember(m, assembly) - order by - m.getQualifiedNameWithTypes(), stubExplicitImplementation(m) - ) - } - - string stubPrivateConstructor() { - if - this instanceof Interface - or - this.isStatic() - or - this.isAbstract() - or - exists(this.(ValueOrRefType).getAConstructor()) - or - not exists(this.getAnInterestingBaseType()) - or - not exists(this.getAnInterestingBaseType().getAConstructor()) - or - exists(Constructor bc | - bc = this.getAnInterestingBaseType().getAConstructor() and - bc.getNumberOfParameters() = 0 and - not bc.isStatic() - ) - then result = "" - else - result = - " private " + this.getUndecoratedName() + "() : base(" + - stubDefaultArguments(getBaseConstructor(this), this) + ")" + " => throw null;\n" - } - - private GeneratedMember getAGeneratedMember() { result.getDeclaringType() = this } - - pragma[noinline] - private GeneratedMember getAGeneratedMember(Assembly assembly) { - result = this.getAGeneratedMember() and assembly = result.getALocation() - } - - final Type getAGeneratedType() { - result = this.getAnInterestingBaseType() - or - result = this.getAGeneratedMember().(Callable).getReturnType() - or - result = this.getAGeneratedMember().(Callable).getAParameter().getType() - or - result = this.getAGeneratedMember().(Property).getType() - or - result = this.getAGeneratedMember().(Field).getType() - } -} - -/** - * A declaration that should be generated. - * This is extended in client code to identify the actual - * declarations that should be generated. - */ -abstract class GeneratedDeclaration extends Modifiable { - GeneratedDeclaration() { this.isEffectivelyPublic() } -} - -private class IndirectType extends GeneratedType { - IndirectType() { - this.(ValueOrRefType).getASubType() instanceof GeneratedType - or - this.(ValueOrRefType).getAChildType() instanceof GeneratedType - or - this.(UnboundGenericType).getAConstructedGeneric().getASubType() instanceof GeneratedType - or - exists(GeneratedType t | - this = getAContainedType(t.getAGeneratedType()).getUnboundDeclaration() - ) - or - exists(GeneratedDeclaration decl | - decl.(Member).getDeclaringType().getUnboundDeclaration() = this - ) - } -} - -private class RootGeneratedType extends GeneratedType { - RootGeneratedType() { this = any(GeneratedDeclaration decl).getUnboundDeclaration() } -} - -private Type getAContainedType(Type t) { - result = t - or - result = getAContainedType(t.(ConstructedType).getATypeArgument()) -} - -private class RootGeneratedMember extends GeneratedMember { - RootGeneratedMember() { this = any(GeneratedDeclaration d).getUnboundDeclaration() } -} - -private predicate declarationExists(Virtualizable m) { - m instanceof GeneratedMember - or - m.getLocation() instanceof ExcludedAssembly -} - -private class InheritedMember extends GeneratedMember, Virtualizable { - InheritedMember() { - declarationExists(this.getImplementee+()) - or - declarationExists(this.getAnImplementor+()) - or - declarationExists(this.getOverridee+()) - or - declarationExists(this.getAnOverrider+()) - } -} - -private class ExtraGeneratedConstructor extends GeneratedMember, Constructor { - ExtraGeneratedConstructor() { - not this.isStatic() and - not this.isEffectivelyPublic() and - this.getDeclaringType() instanceof GeneratedType and - ( - // if the base class has no 0 parameter constructor - not exists(Constructor c | - c = this.getDeclaringType().getBaseClass().getAMember() and - c.getNumberOfParameters() = 0 and - not c.isStatic() - ) - or - // if this constructor might be called from a (generic) derived class - exists(Class c | - this.getDeclaringType() = c.getBaseClass().getUnboundDeclaration() and - this = getBaseConstructor(c).getUnboundDeclaration() - ) - ) - } -} - -/** A namespace that contains at least one generated type. */ -private class GeneratedNamespace extends Namespace, GeneratedElement { - GeneratedNamespace() { - this.getATypeDeclaration() instanceof GeneratedType - or - this.getAChildNamespace() instanceof GeneratedNamespace - } - - private string getPreamble() { - if this.isGlobalNamespace() - then result = "" - else result = "namespace " + this.getName() + "\n{\n" - } - - private string getPostAmble() { if this.isGlobalNamespace() then result = "" else result = "}\n" } - - final string getStubs(Assembly assembly) { - result = - this.getPreamble() + this.getTypeStubs(assembly) + this.getSubNamespaceStubs(assembly) + - this.getPostAmble() - } - - /** Gets the `n`th generated child namespace, indexed from 0. */ - pragma[nomagic] - final GeneratedNamespace getChildNamespace(int n) { - result.getParentNamespace() = this and - result.getName() = - rank[n + 1](GeneratedNamespace g | g.getParentNamespace() = this | g.getName()) - } - - final int getChildNamespaceCount() { - result = count(GeneratedNamespace g | g.getParentNamespace() = this) - } - - private predicate isInAssembly(Assembly assembly) { - any(GeneratedType gt | gt.(DotNet::ValueOrRefType).getDeclaringNamespace() = this) - .isInAssembly(assembly) - or - this.getChildNamespace(_).isInAssembly(assembly) - } - - language[monotonicAggregates] - string getSubNamespaceStubs(Assembly assembly) { - this.isInAssembly(assembly) and - result = - concat(GeneratedNamespace child, int i | - child = this.getChildNamespace(i) and child.isInAssembly(assembly) - | - child.getStubs(assembly) order by i - ) - } - - string getTypeStubs(Assembly assembly) { - this.isInAssembly(assembly) and - result = - concat(GeneratedType gt | - gt.(DotNet::ValueOrRefType).getDeclaringNamespace() = this and gt.isInAssembly(assembly) - | - gt.getStub(assembly) order by gt.getName() - ) - } -} - -/** - * Specify assemblies to exclude. - * Do not generate any types from these assemblies. - */ -abstract class ExcludedAssembly extends Assembly { } - -private Virtualizable getAccessibilityDeclaringVirtualizable(Virtualizable v) { - if not v.isOverride() - then result = v - else - if not v.getOverridee().getLocation() instanceof ExcludedAssembly - then result = getAccessibilityDeclaringVirtualizable(v.getOverridee()) - else result = v -} - -private string stubAccessibility(Member m) { - if - m.getDeclaringType() instanceof Interface - or - exists(getExplicitImplementedInterface(m)) - or - m instanceof Constructor and m.isStatic() - then result = "" - else - if m.isPublic() - then result = "public " - else - if m.isProtected() - then - if m.isPrivate() or getAccessibilityDeclaringVirtualizable(m).isPrivate() - then result = "protected private " - else - if m.isInternal() or getAccessibilityDeclaringVirtualizable(m).isInternal() - then result = "protected internal " - else result = "protected " - else - if m.isPrivate() - then result = "private " - else - if m.isInternal() - then result = "internal " - else result = "unknown-accessibility" -} - -private string stubModifiers(Member m) { - result = stubUnsafe(m) + stubAccessibility(m) + stubStaticOrConst(m) + stubOverride(m) -} - -private string stubUnsafe(Member m) { - if m.(Modifiable).isUnsafe() then result = "unsafe " else result = "" -} - -private string stubStaticOrConst(Member m) { - if m.(Modifiable).isStatic() - then result = "static " - else - if m.(Modifiable).isConst() - then result = "const " - else result = "" -} - -private string stubOverride(Member m) { - if m.getDeclaringType() instanceof Interface and not m.isStatic() - then result = "" - else - if m.(Virtualizable).isVirtual() - then result = "virtual " - else - if m.(Virtualizable).isAbstract() - then - if m.(Virtualizable).isOverride() - then result = "abstract override " - else result = "abstract " - else - if m.(Virtualizable).isOverride() - then result = "override " - else result = "" -} - -private string stubQualifiedNamePrefix(ValueOrRefType t) { - if t.getParent() instanceof GlobalNamespace - then result = "" - else - if t.getParent() instanceof Namespace - then result = t.getDeclaringNamespace().getFullName() + "." - else result = stubClassName(t.getDeclaringType()) + "." -} - -language[monotonicAggregates] -private string stubClassName(Type t) { - if t instanceof ObjectType - then result = "object" - else - if t instanceof StringType - then result = "string" - else - if t instanceof IntType - then result = "int" - else - if t instanceof BoolType - then result = "bool" - else - if t instanceof VoidType - then result = "void" - else - if t instanceof FloatType - then result = "float" - else - if t instanceof DoubleType - then result = "double" - else - if t instanceof NullableType - then result = stubClassName(t.(NullableType).getUnderlyingType()) + "?" - else - if t instanceof TypeParameter - then result = t.getName() - else - if t instanceof ArrayType - then result = stubClassName(t.(ArrayType).getElementType()) + "[]" - else - if t instanceof PointerType - then result = stubClassName(t.(PointerType).getReferentType()) + "*" - else - if t instanceof TupleType - then - exists(TupleType tt | tt = t | - if tt.getArity() < 2 - then result = stubClassName(tt.getUnderlyingType()) - else - result = - "(" + - concat(int i, Type element | - element = tt.getElementType(i) - | - stubClassName(element), "," order by i - ) + ")" - ) - else - if t instanceof FunctionPointerType - then - exists( - FunctionPointerType fpt, CallingConvention callconvention, - string calltext - | - fpt = t - | - callconvention = fpt.getCallingConvention() and - ( - if callconvention instanceof UnmanagedCallingConvention - then calltext = "unmanaged" - else calltext = "" - ) and - result = - "delegate* " + calltext + "<" + - concat(int i, Parameter p | - p = fpt.getParameter(i) - | - stubClassName(p.getType()) + "," order by i - ) + stubClassName(fpt.getReturnType()) + ">" - ) - else - if t instanceof ValueOrRefType - then - result = - stubQualifiedNamePrefix(t) + t.getUndecoratedName() + - stubGenericArguments(t) - else result = "" -} - -language[monotonicAggregates] -private string stubGenericArguments(Type t) { - if t instanceof UnboundGenericType - then - result = - "<" + - concat(int n | - exists(t.(UnboundGenericType).getTypeParameter(n)) - | - t.(UnboundGenericType).getTypeParameter(n).getName(), "," order by n - ) + ">" - else - if t instanceof ConstructedType - then - result = - "<" + - concat(int n | - exists(t.(ConstructedType).getTypeArgument(n)) - | - stubClassName(t.(ConstructedType).getTypeArgument(n)), "," order by n - ) + ">" - else result = "" -} - -private string stubGenericMethodParams(Method m) { - if m instanceof UnboundGenericMethod - then - result = - "<" + - concat(int n, TypeParameter param | - param = m.(UnboundGenericMethod).getTypeParameter(n) - | - param.getName(), "," order by n - ) + ">" - else result = "" -} - -private string stubConstraints(TypeParameterConstraints tpc, int i) { - tpc.hasConstructorConstraint() and result = "new()" and i = 4 - or - tpc.hasUnmanagedTypeConstraint() and result = "unmanaged" and i = 0 - or - tpc.hasValueTypeConstraint() and - result = "struct" and - i = 0 and - not tpc.hasUnmanagedTypeConstraint() and - not stubClassName(tpc.getATypeConstraint().(Class)) = "System.Enum" - or - tpc.hasRefTypeConstraint() and result = "class" and i = 0 - or - result = tpc.getATypeConstraint().(TypeParameter).getName() and i = 3 - or - result = stubClassName(tpc.getATypeConstraint().(Interface)) and i = 2 - or - result = stubClassName(tpc.getATypeConstraint().(Class)) and i = 1 -} - -private string stubTypeParameterConstraints(TypeParameter tp) { - if - tp.getDeclaringGeneric().(Virtualizable).isOverride() or - tp.getDeclaringGeneric().(Virtualizable).implementsExplicitInterface() - then - if tp.getConstraints().hasValueTypeConstraint() - then result = " where " + tp.getName() + ": struct" - else - if tp.getConstraints().hasRefTypeConstraint() - then result = " where " + tp.getName() + ": class" - else result = "" - else - exists(TypeParameterConstraints tpc | tpc = tp.getConstraints() | - result = - " where " + tp.getName() + ": " + - strictconcat(string s, int i | s = stubConstraints(tpc, i) | s, ", " order by i) - ) -} - -private string stubTypeParametersConstraints(Declaration d) { - if d instanceof UnboundGeneric - then - result = - concat(TypeParameter tp | - tp = d.(UnboundGeneric).getATypeParameter() - | - stubTypeParameterConstraints(tp), " " - ) - else result = "" -} - -private string stubImplementation(Virtualizable c) { - if c.isAbstract() then result = "" else result = " => throw null" -} - -private predicate isKeyword(string s) { - s = - [ - "abstract", "as", "base", "bool", "break", "byte", "case", "catch", "char", "checked", - "class", "const", "continue", "decimal", "default", "delegate", "do", "double", "else", - "enum", "event", "explicit", "extern", "false", "finally", "fixed", "float", "for", "foreach", - "goto", "if", "implicit", "in", "int", "interface", "internal", "is", "lock", "long", - "namespace", "new", "null", "object", "operator", "out", "override", "params", "private", - "protected", "public", "readonly", "ref", "return", "sbyte", "sealed", "short", "sizeof", - "stackalloc", "static", "string", "struct", "switch", "this", "throw", "true", "try", - "typeof", "uint", "ulong", "unchecked", "unsafe", "ushort", "using", "virtual", "void", - "volatile", "while" - ] -} - -bindingset[s] -private string escapeIfKeyword(string s) { if isKeyword(s) then result = "@" + s else result = s } - -private string stubParameters(Parameterizable p) { - result = - concat(int i, Parameter param | - param = p.getParameter(i) and not param.getType() instanceof ArglistType - | - stubParameterModifiers(param) + stubClassName(param.getType()) + " " + - escapeIfKeyword(param.getName()) + stubDefaultValue(param), ", " - order by - i - ) -} - -private string stubDefaultArguments(Constructor baseCtor, ValueOrRefType callingType) { - baseCtor = getBaseConstructor(callingType) and - baseCtor.getNumberOfParameters() > 0 and - result = - concat(int i, Parameter param | - param = baseCtor.getParameter(i) and not param.getType() instanceof ArglistType - | - "default(" + stubClassName(param.getType()) + ")", ", " order by i - ) -} - -private string stubParameterModifiers(Parameter p) { - if p.isOut() - then result = "out " - else - if p.isRef() - then result = "ref " - else - if p.isParams() - then result = "params " - else - if p.isIn() - then result = "" // Only C# 7.1 so ignore - else - if p.hasExtensionMethodModifier() - then result = "this " - else result = "" -} - -private string stubDefaultValue(Parameter p) { - if p.hasDefaultValue() - then result = " = default(" + stubClassName(p.getType()) + ")" - else result = "" -} - -private string stubEventAccessors(Event e) { - if exists(e.(Virtualizable).getExplicitlyImplementedInterface()) - then result = " { add => throw null; remove => throw null; }" - else result = ";" -} - -/** - * Returns an interface that `c` explicitly implements, if either of the - * following also holds. - * (1) `c` is not static. - * (2) `c` is static and an implementation of a generic with type constraints. - * (3) `c` is static and there is another member with the same name - * but different return type. - * - * We use these rules as explicit interfaces are needed in some cases - * for compilation purposes (both to distinguish members but also to ensure - * type constraints are satisfied). We can't always use explicit interface - * implementation due to the generic math support, because then in some cases - * we will only be able to access a static via a type variable with type - * constraints (C# 11 language feature). - */ -private Interface getExplicitImplementedInterface(Virtualizable c) { - result = unique(Interface i | i = c.getExplicitlyImplementedInterface()) and - ( - not c.isStatic() - or - c.isStatic() and - ( - not c instanceof Method - or - c instanceof Method and - ( - exists(TypeParameter t | t = c.getImplementee().(UnboundGeneric).getATypeParameter() | - exists(t.getConstraints().getATypeConstraint()) - ) - or - exists(Member m | - (not m.isStatic() or m.(Method).getReturnType() != c.(Method).getReturnType()) and - m.getName() = c.getName() and - m.getDeclaringType() = c.getDeclaringType() - ) - ) - ) - ) -} - -private string stubExplicitImplementation(Member c) { - if exists(getExplicitImplementedInterface(c)) - then result = stubClassName(getExplicitImplementedInterface(c)) + "." - else result = "" -} - -pragma[noinline] -private string stubMethod(Method m, Assembly assembly) { - m instanceof GeneratedMember and - m.getALocation() = assembly and - if not m.getDeclaringType() instanceof Enum - then - result = - " " + stubModifiers(m) + stubClassName(m.getReturnType()) + " " + - stubExplicitImplementation(m) + escapeIfKeyword(m.getUndecoratedName()) + - stubGenericMethodParams(m) + "(" + stubParameters(m) + ")" + - stubTypeParametersConstraints(m) + stubImplementation(m) + ";\n" - else result = " // Stub generator skipped method: " + m.getName() + "\n" -} - -pragma[noinline] -private string stubOperator(Operator o, Assembly assembly) { - o instanceof GeneratedMember and - o.getALocation() = assembly and - if o instanceof ConversionOperator - then - result = - " " + stubModifiers(o) + stubExplicit(o) + stubExplicitImplementation(o) + "operator " + - stubChecked(o) + stubClassName(o.getReturnType()) + "(" + stubParameters(o) + ")" + - stubImplementation(o) + ";\n" - else - if not o.getDeclaringType() instanceof Enum - then - result = - " " + stubModifiers(o) + stubClassName(o.getReturnType()) + " " + - stubExplicitImplementation(o) + "operator " + o.getName() + "(" + stubParameters(o) + ")" + - stubImplementation(o) + ";\n" - else result = " // Stub generator skipped operator: " + o.getName() + "\n" -} - -pragma[noinline] -private string stubEnumConstant(EnumConstant ec, Assembly assembly) { - ec instanceof GeneratedMember and - ec.getALocation() = assembly and - result = " " + escapeIfKeyword(ec.getName()) + " = " + ec.getValue() + ",\n" -} - -pragma[noinline] -private string stubProperty(Property p, Assembly assembly) { - p instanceof GeneratedMember and - p.getALocation() = assembly and - result = - " " + stubModifiers(p) + stubClassName(p.getType()) + " " + stubExplicitImplementation(p) + - escapeIfKeyword(p.getName()) + " { " + stubGetter(p) + stubSetter(p) + "}\n" -} - -pragma[noinline] -private string stubConstructor(Constructor c, Assembly assembly) { - c instanceof GeneratedMember and - c.getALocation() = assembly and - if c.getDeclaringType() instanceof Enum - then result = "" - else - if - not c.getDeclaringType() instanceof StructExt or - c.getNumberOfParameters() > 0 - then - result = - " " + stubModifiers(c) + escapeIfKeyword(c.getName()) + "(" + stubParameters(c) + ")" + - stubConstructorInitializer(c) + " => throw null;\n" - else result = " // Stub generator skipped constructor \n" -} - -pragma[noinline] -private string stubIndexer(Indexer i, Assembly assembly) { - i instanceof GeneratedMember and - i.getALocation() = assembly and - result = - " " + stubIndexerNameAttribute(i) + stubModifiers(i) + stubClassName(i.getType()) + " " + - stubExplicitImplementation(i) + "this[" + stubParameters(i) + "] { " + stubGetter(i) + - stubSetter(i) + "}\n" -} - -pragma[noinline] -private string stubField(Field f, Assembly assembly) { - f instanceof GeneratedMember and - f.getALocation() = assembly and - not f instanceof EnumConstant and // EnumConstants are already stubbed - exists(string impl | - (if f.isConst() then impl = " = default" else impl = "") and - result = - " " + stubModifiers(f) + stubClassName(f.getType()) + " " + escapeIfKeyword(f.getName()) + - impl + ";\n" - ) -} - -pragma[noinline] -private string stubEvent(Event e, Assembly assembly) { - e instanceof GeneratedMember and - e.getALocation() = assembly and - result = - " " + stubModifiers(e) + "event " + stubClassName(e.getType()) + " " + - stubExplicitImplementation(e) + escapeIfKeyword(e.getName()) + stubEventAccessors(e) + "\n" -} - -pragma[nomagic] -private string stubMember(GeneratedMember m, Assembly assembly) { - result = stubMethod(m, assembly) - or - result = stubOperator(m, assembly) - or - result = stubEnumConstant(m, assembly) - or - result = stubProperty(m, assembly) - or - result = stubConstructor(m, assembly) - or - result = stubIndexer(m, assembly) - or - result = stubField(m, assembly) - or - result = stubEvent(m, assembly) - or - not m instanceof Method and - not m instanceof Operator and - not m instanceof EnumConstant and - not m instanceof Property and - not m instanceof Constructor and - not m instanceof Indexer and - not m instanceof Field and - not m instanceof Event and - m.getALocation() = assembly and - ( - result = m.(GeneratedType).getStub(assembly) + "\n" - or - not m instanceof GeneratedType and - result = " // ERR: Stub generator didn't handle member: " + m.getName() + "\n" - ) -} - -private string stubIndexerNameAttribute(Indexer i) { - if i.getName() != "Item" - then result = "[System.Runtime.CompilerServices.IndexerName(\"" + i.getName() + "\")]\n " - else result = "" -} - -private Constructor getBaseConstructor(ValueOrRefType type) { - result = - min(Constructor bc | - type.getBaseClass().getAMember() = bc and - // not the `static` constructor - not bc.isStatic() and - // not a `private` constructor, unless it's `private protected`, or if the derived class is nested - (not bc.isPrivate() or bc.isProtected() or bc.getDeclaringType() = type.getDeclaringType+()) - | - bc order by bc.getNumberOfParameters(), stubParameters(bc) - ) -} - -private string stubConstructorInitializer(Constructor c) { - exists(Constructor baseCtor | - baseCtor = getBaseConstructor(c.getDeclaringType()) and - if baseCtor.getNumberOfParameters() = 0 or c.isStatic() - then result = "" - else result = " : base(" + stubDefaultArguments(baseCtor, c.getDeclaringType()) + ")" - ) - or - // abstract base class might not have a constructor - not exists(Constructor baseCtor | - c.getDeclaringType().getBaseClass().getAMember() = baseCtor and not baseCtor.isStatic() - ) and - result = "" -} - -private string stubExplicit(ConversionOperator op) { - op instanceof ImplicitConversionOperator and result = "implicit " - or - ( - op instanceof ExplicitConversionOperator - or - op instanceof CheckedExplicitConversionOperator - ) and - result = "explicit " -} - -private string stubChecked(Operator o) { - if o instanceof CheckedExplicitConversionOperator then result = "checked " else result = "" -} - -private string stubGetter(DeclarationWithGetSetAccessors p) { - if exists(p.getGetter()) - then if p.isAbstract() then result = "get; " else result = "get => throw null; " - else result = "" -} - -private string stubSetter(DeclarationWithGetSetAccessors p) { - if exists(p.getSetter()) - then if p.isAbstract() then result = "set; " else result = "set => throw null; " - else result = "" -} - -private string stubSemmleExtractorOptions() { - result = - concat(string s | - exists(CommentLine comment | - s = - "// original-extractor-options:" + - comment.getText().regexpCapture("\\w*semmle-extractor-options:(.*)", 1) + "\n" - ) - ) -} - -/** Gets the generated C# code. */ -string generatedCode(Assembly assembly) { - result = - "// This file contains auto-generated code.\n" // - + "// Generated from `" + assembly.getFullName() + "`.\n" // - + stubSemmleExtractorOptions() + "\n" // - + any(GeneratedNamespace ns | ns.isGlobalNamespace()).getStubs(assembly) -} diff --git a/csharp/ql/src/Stubs/make_stubs.py b/csharp/ql/src/Stubs/make_stubs.py deleted file mode 100644 index e66371f2b957..000000000000 --- a/csharp/ql/src/Stubs/make_stubs.py +++ /dev/null @@ -1,96 +0,0 @@ -# Tool to generate 'stub.cs' files inside C# qltest projects. -# The purpose of this is to stub out assemblies from the qltest case -# so that the test is self-contained and will still run without them. -# -# To do this, it -# 1. Performs a regular qltest to generate a snapshot -# 2. Runs a QL query on the snapshot to find out which symbols are needed, -# then uses QL to generate a string of C# code. -# 3. Re-runs the test to ensure that it still compiles and passes. - -import sys -import os -import subprocess -import helpers - -print('Script to generate stub.cs files for C# qltest projects') - -if len(sys.argv) < 2: - print("Please supply a qltest directory.") - exit(1) - -testDir = sys.argv[1] - -if not os.path.isdir(testDir): - print("Directory", testDir, "does not exist") - exit(1) - -# Does it contain a .ql file and a .cs file? - -foundCS = False -foundQL = False - -for file in os.listdir(testDir): - if file.endswith(".cs"): - foundCS = True - if file.endswith(".ql") or file.endswith(".qlref"): - foundQL = True - -if not foundQL: - print("Test directory does not contain .ql files. Please specify a working qltest directory.") - exit(1) - -if not foundCS: - print("Test directory does not contain .cs files. Please specify a working qltest directory.") - exit(1) - -csharpQueries = os.path.abspath(os.path.dirname(sys.argv[0])) -outputFile = os.path.join(testDir, 'stubs.cs') -bqrsFile = os.path.join(testDir, 'stubs.bqrs') - -print("Stubbing qltest in", testDir) - -if os.path.isfile(outputFile): - os.remove(outputFile) # It would interfere with the test. - print("Removed previous", outputFile) - -helpers.run_cmd(['codeql', 'test', 'run', '--keep-databases', testDir], - "codeql test failed. Please fix up the test before proceeding.") - -dbDir = os.path.join(testDir, os.path.basename(testDir) + ".testproj") - -if not os.path.isdir(dbDir): - print("Expected database directory " + dbDir + " not found.") - exit(1) - -helpers.run_cmd(['codeql', 'query', 'run', os.path.join( - csharpQueries, 'MinimalStubsFromSource.ql'), '--database', dbDir, '--output', bqrsFile], 'Failed to run the query to generate output file.') - -helpers.run_cmd(['codeql', 'bqrs', 'decode', bqrsFile, '--output', - outputFile, '--format=text', '--no-titles'], 'Failed to run the query to generate output file.') - -helpers.trim_output_file(outputFile) - -if os.path.isfile(bqrsFile): - os.remove(bqrsFile) # Cleanup - print("Removed temp BQRS file", bqrsFile) - -cmd = ['codeql', 'test', 'run', testDir] -print('Running ' + ' '.join(cmd)) -if subprocess.check_call(cmd): - print('\nTest failed. You may need to fix up', outputFile) - print('It may help to view', outputFile, ' in Visual Studio') - print("Next steps:") - print('1. Look at the compilation errors, and fix up', - outputFile, 'so that the test compiles') - print('2. Re-run codeql test run "' + testDir + '"') - print('3. git add "' + outputFile + '"') - exit(1) - -print("\nStub generation successful! Next steps:") -print('1. Edit "semmle-extractor-options" in the .cs files to remove unused references') -print('2. Re-run codeql test run "' + testDir + '"') -print('3. git add "' + outputFile + '"') -print('4. Commit your changes.') - -exit(0) diff --git a/csharp/ql/test/library-tests/attributes/AttributeArguments.expected b/csharp/ql/test/library-tests/attributes/AttributeArguments.expected index fe29160c8e08..dc7bc9330d99 100644 --- a/csharp/ql/test/library-tests/attributes/AttributeArguments.expected +++ b/csharp/ql/test/library-tests/attributes/AttributeArguments.expected @@ -90,6 +90,22 @@ arguments | attributes.cs:125:18:125:29 | [return: My3(...)] | 0 | attributes.cs:125:31:125:32 | 12 | | attributes.cs:128:10:128:21 | [My3(...)] | 0 | attributes.cs:128:23:128:24 | 13 | | attributes.cs:129:17:129:28 | [My3(...)] | 0 | attributes.cs:129:30:129:31 | 14 | +| attributes.cs:141:6:141:11 | [Params(...)] | 0 | attributes.cs:141:13:141:15 | "a" | +| attributes.cs:141:6:141:11 | [Params(...)] | 1 | attributes.cs:141:18:141:20 | "b" | +| attributes.cs:141:6:141:11 | [Params(...)] | 2 | attributes.cs:141:23:141:23 | 1 | +| attributes.cs:141:6:141:11 | [Params(...)] | 3 | attributes.cs:141:26:141:26 | 2 | +| attributes.cs:141:6:141:11 | [Params(...)] | 4 | attributes.cs:141:29:141:29 | 3 | +| attributes.cs:144:6:144:11 | [Params(...)] | 0 | attributes.cs:144:17:144:19 | "a" | +| attributes.cs:144:6:144:11 | [Params(...)] | 1 | attributes.cs:144:26:144:28 | "b" | +| attributes.cs:144:6:144:11 | [Params(...)] | 2 | attributes.cs:144:31:144:31 | 1 | +| attributes.cs:144:6:144:11 | [Params(...)] | 3 | attributes.cs:144:34:144:34 | 2 | +| attributes.cs:144:6:144:11 | [Params(...)] | 4 | attributes.cs:144:37:144:37 | 3 | +| attributes.cs:147:6:147:11 | [Params(...)] | 0 | attributes.cs:147:35:147:37 | "a" | +| attributes.cs:147:6:147:11 | [Params(...)] | 1 | attributes.cs:147:26:147:28 | "b" | +| attributes.cs:147:6:147:11 | [Params(...)] | 2 | attributes.cs:147:19:147:19 | 1 | +| attributes.cs:150:6:150:11 | [Params(...)] | 0 | attributes.cs:150:45:150:47 | "a" | +| attributes.cs:150:6:150:11 | [Params(...)] | 1 | attributes.cs:150:36:150:38 | "b" | +| attributes.cs:150:6:150:11 | [Params(...)] | 2 | attributes.cs:150:19:150:29 | array creation of type Int32[] | constructorArguments | Assembly1.dll:0:0:0:0 | [Custom(...)] | 0 | Assembly1.dll:0:0:0:0 | 1 | | Assembly1.dll:0:0:0:0 | [Custom(...)] | 0 | Assembly1.dll:0:0:0:0 | 3 | @@ -170,6 +186,22 @@ constructorArguments | attributes.cs:125:18:125:29 | [return: My3(...)] | 0 | attributes.cs:125:31:125:32 | 12 | | attributes.cs:128:10:128:21 | [My3(...)] | 0 | attributes.cs:128:23:128:24 | 13 | | attributes.cs:129:17:129:28 | [My3(...)] | 0 | attributes.cs:129:30:129:31 | 14 | +| attributes.cs:141:6:141:11 | [Params(...)] | 0 | attributes.cs:141:13:141:15 | "a" | +| attributes.cs:141:6:141:11 | [Params(...)] | 1 | attributes.cs:141:18:141:20 | "b" | +| attributes.cs:141:6:141:11 | [Params(...)] | 2 | attributes.cs:141:23:141:23 | 1 | +| attributes.cs:141:6:141:11 | [Params(...)] | 3 | attributes.cs:141:26:141:26 | 2 | +| attributes.cs:141:6:141:11 | [Params(...)] | 4 | attributes.cs:141:29:141:29 | 3 | +| attributes.cs:144:6:144:11 | [Params(...)] | 0 | attributes.cs:144:17:144:19 | "a" | +| attributes.cs:144:6:144:11 | [Params(...)] | 1 | attributes.cs:144:26:144:28 | "b" | +| attributes.cs:144:6:144:11 | [Params(...)] | 2 | attributes.cs:144:31:144:31 | 1 | +| attributes.cs:144:6:144:11 | [Params(...)] | 3 | attributes.cs:144:34:144:34 | 2 | +| attributes.cs:144:6:144:11 | [Params(...)] | 4 | attributes.cs:144:37:144:37 | 3 | +| attributes.cs:147:6:147:11 | [Params(...)] | 0 | attributes.cs:147:35:147:37 | "a" | +| attributes.cs:147:6:147:11 | [Params(...)] | 1 | attributes.cs:147:26:147:28 | "b" | +| attributes.cs:147:6:147:11 | [Params(...)] | 2 | attributes.cs:147:19:147:19 | 1 | +| attributes.cs:150:6:150:11 | [Params(...)] | 0 | attributes.cs:150:45:150:47 | "a" | +| attributes.cs:150:6:150:11 | [Params(...)] | 1 | attributes.cs:150:36:150:38 | "b" | +| attributes.cs:150:6:150:11 | [Params(...)] | 2 | attributes.cs:150:19:150:29 | array creation of type Int32[] | namedArguments | Assembly1.dll:0:0:0:0 | [Custom(...)] | Prop2 | Assembly1.dll:0:0:0:0 | array creation of type Object[] | | Assembly1.dll:0:0:0:0 | [Custom(...)] | Prop2 | Assembly1.dll:0:0:0:0 | array creation of type Object[] | diff --git a/csharp/ql/test/library-tests/attributes/AttributeElements.expected b/csharp/ql/test/library-tests/attributes/AttributeElements.expected index ffdef293b70d..11291a73338b 100644 --- a/csharp/ql/test/library-tests/attributes/AttributeElements.expected +++ b/csharp/ql/test/library-tests/attributes/AttributeElements.expected @@ -32,6 +32,10 @@ | attributes.cs:126:9:126:11 | get_Prop1 | attributes.cs:125:18:125:29 | [return: My3(...)] | My3Attribute | | attributes.cs:130:9:130:11 | set_Prop1 | attributes.cs:128:10:128:21 | [My3(...)] | My3Attribute | | attributes.cs:130:9:130:11 | value | attributes.cs:129:17:129:28 | [My3(...)] | My3Attribute | +| attributes.cs:142:17:142:18 | M1 | attributes.cs:141:6:141:11 | [Params(...)] | Class1+ParamsAttribute | +| attributes.cs:145:17:145:18 | M2 | attributes.cs:144:6:144:11 | [Params(...)] | Class1+ParamsAttribute | +| attributes.cs:148:17:148:18 | M3 | attributes.cs:147:6:147:11 | [Params(...)] | Class1+ParamsAttribute | +| attributes.cs:151:17:151:18 | M4 | attributes.cs:150:6:150:11 | [Params(...)] | Class1+ParamsAttribute | | attributes.dll:0:0:0:0 | attributes, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null | attributes.cs:10:12:10:24 | [assembly: AssemblyTitle(...)] | System.Reflection.AssemblyTitleAttribute | | attributes.dll:0:0:0:0 | attributes, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null | attributes.cs:11:12:11:30 | [assembly: AssemblyDescription(...)] | System.Reflection.AssemblyDescriptionAttribute | | attributes.dll:0:0:0:0 | attributes, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null | attributes.cs:12:12:12:32 | [assembly: AssemblyConfiguration(...)] | System.Reflection.AssemblyConfigurationAttribute | diff --git a/csharp/ql/test/library-tests/attributes/PrintAst.expected b/csharp/ql/test/library-tests/attributes/PrintAst.expected index c35d40d3aeb0..77be3f7461dd 100644 --- a/csharp/ql/test/library-tests/attributes/PrintAst.expected +++ b/csharp/ql/test/library-tests/attributes/PrintAst.expected @@ -405,3 +405,59 @@ attributes.cs: # 130| 0: [AssignExpr] ... = ... # 130| 0: [FieldAccess] access to field p # 130| 1: [ParameterAccess] access to parameter value +# 134| [Class] Class1 +# 136| 5: [Class] ParamsAttribute +#-----| 3: (Base types) +# 136| 0: [TypeMention] Attribute +# 138| 4: [InstanceConstructor] ParamsAttribute +#-----| 2: (Parameters) +# 138| 0: [Parameter] s1 +# 138| -1: [TypeMention] string +# 138| 1: [Parameter] s2 +# 138| -1: [TypeMention] string +# 138| 2: [Parameter] args +# 138| -1: [TypeMention] Int32[] +# 138| 1: [TypeMention] int +# 138| 4: [BlockStmt] {...} +# 142| 6: [Method] M1 +# 142| -1: [TypeMention] Void +#-----| 0: (Attributes) +# 141| 1: [DefaultAttribute] [Params(...)] +# 141| -1: [TypeMention] ParamsAttribute +# 141| 0: [StringLiteralUtf16] "a" +# 141| 1: [StringLiteralUtf16] "b" +# 141| 2: [IntLiteral] 1 +# 141| 3: [IntLiteral] 2 +# 141| 4: [IntLiteral] 3 +# 142| 4: [BlockStmt] {...} +# 145| 7: [Method] M2 +# 145| -1: [TypeMention] Void +#-----| 0: (Attributes) +# 144| 1: [DefaultAttribute] [Params(...)] +# 144| -1: [TypeMention] ParamsAttribute +# 144| 0: [StringLiteralUtf16] "a" +# 144| 1: [StringLiteralUtf16] "b" +# 144| 2: [IntLiteral] 1 +# 144| 3: [IntLiteral] 2 +# 144| 4: [IntLiteral] 3 +# 145| 4: [BlockStmt] {...} +# 148| 8: [Method] M3 +# 148| -1: [TypeMention] Void +#-----| 0: (Attributes) +# 147| 1: [DefaultAttribute] [Params(...)] +# 147| -1: [TypeMention] ParamsAttribute +# 147| 0: [StringLiteralUtf16] "a" +# 147| 1: [StringLiteralUtf16] "b" +# 147| 2: [IntLiteral] 1 +# 148| 4: [BlockStmt] {...} +# 151| 9: [Method] M4 +# 151| -1: [TypeMention] Void +#-----| 0: (Attributes) +# 150| 1: [DefaultAttribute] [Params(...)] +# 150| -1: [TypeMention] ParamsAttribute +# 150| 0: [StringLiteralUtf16] "a" +# 150| 1: [StringLiteralUtf16] "b" +# 150| 2: [ArrayCreation] array creation of type Int32[] +# 150| -1: [ArrayInitializer] { ..., ... } +# 150| 0: [IntLiteral] 1 +# 151| 4: [BlockStmt] {...} diff --git a/csharp/ql/test/library-tests/attributes/attributes.cs b/csharp/ql/test/library-tests/attributes/attributes.cs index 6790d7ff02d6..3f1018c94162 100644 --- a/csharp/ql/test/library-tests/attributes/attributes.cs +++ b/csharp/ql/test/library-tests/attributes/attributes.cs @@ -129,4 +129,24 @@ public int Prop1 [param: My3Attribute(14)] set { p = value; } } +} + +class Class1 +{ + public class ParamsAttribute : Attribute + { + public ParamsAttribute(string s1, string s2, params int[] args) { } + } + + [Params("a", "b", 1, 2, 3)] + public void M1() { } + + [Params(s1: "a", s2: "b", 1, 2, 3)] + public void M2() { } + + [Params(args: 1, s2: "b", s1: "a")] + public void M3() { } + + [Params(args: new[] { 1 }, s2: "b", s1: "a")] + public void M4() { } } \ No newline at end of file diff --git a/csharp/ql/test/query-tests/Stubs/All/AllStubs.expected b/csharp/ql/test/query-tests/Stubs/All/AllStubs.expected deleted file mode 100644 index 0fd2ca780886..000000000000 --- a/csharp/ql/test/query-tests/Stubs/All/AllStubs.expected +++ /dev/null @@ -1 +0,0 @@ -| // This file contains auto-generated code.\n// Generated from `Test, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null`.\n\nnamespace A1\n{\npublic class C1\n{\n}\n\n}\nnamespace A2\n{\nnamespace B2\n{\npublic class C2\n{\n}\n\n}\n}\nnamespace A3\n{\npublic class C3\n{\n}\n\n}\nnamespace A4\n{\npublic class C4\n{\n}\n\nnamespace B4\n{\npublic class D4\n{\n}\n\n}\n}\nnamespace Test\n{\npublic class Class1\n{\npublic class Class11 : Test.Class1.Interface1, Test.Class1.Interface2\n{\n int Test.Class1.Interface2.this[int i] { get => throw null; }\n public void Method1() => throw null;\n void Test.Class1.Interface2.Method2() => throw null;\n}\n\n\npublic class Class12 : Test.Class1.Class11\n{\n}\n\n\npublic abstract class Class13\n{\n protected internal virtual void M() => throw null;\n public virtual void M1() where T: Test.Class1.Class13 => throw null;\n public abstract void M2();\n}\n\n\npublic abstract class Class14 : Test.Class1.Class13\n{\n protected internal override void M() => throw null;\n public override void M1() => throw null;\n public abstract override void M2();\n}\n\n\npublic delegate void Delegate1(T i, int j);\n\n\npublic class GenericType\n{\npublic class X\n{\n}\n\n\n}\n\n\npublic interface Interface1\n{\n void Method1();\n}\n\n\nprotected internal interface Interface2\n{\n int this[int i] { get; }\n void Method2();\n}\n\n\npublic struct Struct1\n{\n public void Method(Test.Class1.Struct1 s = default(Test.Class1.Struct1)) => throw null;\n public int i;\n public static int j = default;\n public System.ValueTuple t1;\n public (int,int) t2;\n}\n\n\n public event Test.Class1.Delegate1 Event1;\n public Test.Class1.GenericType.X Prop { get => throw null; }\n}\n\npublic class Class10\n{\n unsafe public void M1(delegate* unmanaged f) => throw null;\n}\n\npublic class Class11 : Test.IInterface2, Test.IInterface3\n{\n static Test.Class11 Test.IInterface2.operator *(Test.Class11 left, Test.Class11 right) => throw null;\n public static Test.Class11 operator +(Test.Class11 left, Test.Class11 right) => throw null;\n public static Test.Class11 operator -(Test.Class11 left, Test.Class11 right) => throw null;\n static Test.Class11 Test.IInterface2.operator /(Test.Class11 left, Test.Class11 right) => throw null;\n public void M1() => throw null;\n void Test.IInterface2.M2() => throw null;\n public static explicit operator System.Int16(Test.Class11 n) => throw null;\n static explicit Test.IInterface2.operator int(Test.Class11 n) => throw null;\n}\n\npublic class Class3\n{\n public object Item { get => throw null; set => throw null; }\n [System.Runtime.CompilerServices.IndexerName("MyItem")]\n public object this[string index] { get => throw null; set => throw null; }\n}\n\npublic class Class4\n{\n unsafe public void M(int* p) => throw null;\n}\n\npublic class Class5 : Test.IInterface1\n{\n public void M2() => throw null;\n}\n\npublic class Class6 where T: class, Test.IInterface1\n{\n public virtual void M1() where T: class, Test.IInterface1, new() => throw null;\n}\n\npublic class Class7 : Test.Class6\n{\n public override void M1() where T: class => throw null;\n}\n\npublic class Class8\n{\n public static int @this = default;\n}\n\npublic class Class9\n{\npublic class Nested : Test.Class9\n{\n}\n\n\n public Test.Class9.Nested NestedInstance { get => throw null; }\n}\n\npublic enum Enum1 : int\n{\n None1 = 0,\n Some11 = 1,\n Some12 = 2,\n}\n\npublic enum Enum2 : int\n{\n None2 = 2,\n Some21 = 1,\n Some22 = 3,\n}\n\npublic enum Enum3 : int\n{\n None3 = 2,\n Some31 = 1,\n Some32 = 0,\n}\n\npublic enum Enum4 : int\n{\n None4 = 2,\n Some41 = 7,\n Some42 = 6,\n}\n\npublic enum EnumLong : long\n{\n None = 10,\n Some = 223372036854775807,\n}\n\npublic interface IInterface1\n{\n void M1() => throw null;\n void M2();\n}\n\npublic interface IInterface2 where T: Test.IInterface2\n{\n static abstract T operator *(T left, T right);\n static abstract T operator +(T left, T right);\n static virtual T operator -(T left, T right) => throw null;\n static virtual T operator /(T left, T right) => throw null;\n void M1();\n void M2();\n static abstract explicit operator System.Int16(T n);\n static abstract explicit operator int(T n);\n}\n\npublic interface IInterface3 where T: Test.IInterface3\n{\n static abstract T operator +(T left, T right);\n static virtual T operator -(T left, T right) => throw null;\n void M1();\n static abstract explicit operator System.Int16(T n);\n}\n\nunsafe public class MyUnsafeClass\n{\n unsafe public static void M1(delegate* f) => throw null;\n unsafe public static void M2(int*[] x) => throw null;\n unsafe public static System.Char* M3() => throw null;\n public static void M4(int x) => throw null;\n}\n\n}\n\n\n | diff --git a/csharp/ql/test/query-tests/Stubs/All/AllStubs.qlref b/csharp/ql/test/query-tests/Stubs/All/AllStubs.qlref deleted file mode 100644 index 0f7425d26b5b..000000000000 --- a/csharp/ql/test/query-tests/Stubs/All/AllStubs.qlref +++ /dev/null @@ -1 +0,0 @@ -Stubs/AllStubsFromSource.ql diff --git a/csharp/ql/test/query-tests/Stubs/All/Test.cs b/csharp/ql/test/query-tests/Stubs/All/Test.cs deleted file mode 100644 index 7e3f96bb0004..000000000000 --- a/csharp/ql/test/query-tests/Stubs/All/Test.cs +++ /dev/null @@ -1,249 +0,0 @@ -using System; - -namespace Test -{ - public class Class1 - { - public struct Struct1 - { - public ValueTuple t1; - public (int, int) t2; - - public int i; - public const int j = 42; - - public void Method(Struct1 s = new Struct1()) => throw null; - } - - public interface Interface1 - { - void Method1(); - } - - internal protected interface Interface2 - { - void Method2(); - int this[int i] { get; } - } - - private protected interface Interface3 - { - void Method3(); - } - - public class Class11 : Interface1, Interface2, Interface3 - { - public Class11(int i) => throw null; - - public void Method1() => throw null; - - void Interface2.Method2() => throw null; - - int Interface2.this[int i] => throw null; - - void Interface3.Method3() => throw null; - } - - public delegate void Delegate1(T i, int j); - - public event Delegate1 Event1 { add { } remove { } } - - public class Class12 : Class11 - { - public Class12(int i, float j) : base(1) => throw null; - } - - public class GenericType - { - public class X { } - } - - public GenericType.X Prop { get; } - - public abstract class Class13 - { - protected internal virtual void M() => throw null; - public virtual void M1() where T : Class13 => throw null; - public abstract void M2(); - } - - public abstract class Class14 : Class13 - { - protected internal override void M() => throw null; - public override void M1() => throw null; - public abstract override void M2(); - } - - } - - internal class Class2 - { - public void M() => throw null; - } - - public class Class3 - { - public object Item { get; set; } - [System.Runtime.CompilerServices.IndexerName("MyItem")] - public object this[string index] { get { return null; } set { } } - } - - public class Class4 - { - unsafe public void M(int* p) => throw null; - } - - public interface IInterface1 - { - void M1() => throw null; - void M2(); - } - - public class Class5 : IInterface1 - { - public void M2() => throw null; - } - - public class Class6 where T : class, IInterface1 - { - public Class6(int i) => throw null; - - public virtual void M1() where T : class, IInterface1, new() => throw null; - } - - public class Class7 : Class6 - { - public Class7(int i) : base(i) => throw null; - - public override void M1() where T : class => throw null; - } - - public class Class8 - { - public const int @this = 10; - } - - public class Class9 - { - private Class9(int i) => throw null; - - public class Nested : Class9 - { - internal Nested(int i) : base(i) => throw null; - } - - public Class9.Nested NestedInstance { get; } = new Class9.Nested(1); - } - - public class Class10 - { - unsafe public void M1(delegate* unmanaged f) => throw null; - } - - public interface IInterface2 where T : IInterface2 - { - static abstract T operator +(T left, T right); - static virtual T operator -(T left, T right) => throw null; - static abstract T operator *(T left, T right); - static virtual T operator /(T left, T right) => throw null; - static abstract explicit operator short(T n); - static abstract explicit operator int(T n); - void M1(); - void M2(); - } - - public interface IInterface3 where T : IInterface3 - { - static abstract T operator +(T left, T right); - static virtual T operator -(T left, T right) => throw null; - static abstract explicit operator short(T n); - void M1(); - } - - public class Class11 : IInterface2, IInterface3 - { - public static Class11 operator +(Class11 left, Class11 right) => throw null; - public static Class11 operator -(Class11 left, Class11 right) => throw null; - static Class11 IInterface2.operator *(Class11 left, Class11 right) => throw null; - static Class11 IInterface2.operator /(Class11 left, Class11 right) => throw null; - public void M1() => throw null; - void IInterface2.M2() => throw null; - public static explicit operator short(Class11 n) => 0; - static explicit IInterface2.operator int(Class11 n) => 0; - } - - public unsafe class MyUnsafeClass - { - public static void M1(delegate* f) => throw null; - public static void M2(int*[] x) => throw null; - public static char* M3() => throw null; - public static void M4(int x) => throw null; - } - - public enum Enum1 - { - None1, - Some11, - Some12 - } - - public enum Enum2 - { - None2 = 2, - Some21 = 1, - Some22 = 3 - } - - public enum Enum3 - { - Some32, - Some31, - None3 - } - - public enum Enum4 - { - Some41 = 7, - None4 = 2, - Some42 = 6 - } - - public enum EnumLong : long - { - Some = 223372036854775807, - None = 10 - } -} - -namespace A1 -{ - namespace B1 - { - - } - - public class C1 { } -} - -namespace A2 -{ - namespace B2 - { - public class C2 { } - } -} - -namespace A3 -{ - public class C3 { } -} - -namespace A4 -{ - namespace B4 - { - public class D4 { } - } - - public class C4 { } -} \ No newline at end of file diff --git a/csharp/ql/test/query-tests/Stubs/Minimal/MinimalStubsFromSource.expected b/csharp/ql/test/query-tests/Stubs/Minimal/MinimalStubsFromSource.expected deleted file mode 100644 index dc42176a7cb2..000000000000 --- a/csharp/ql/test/query-tests/Stubs/Minimal/MinimalStubsFromSource.expected +++ /dev/null @@ -1 +0,0 @@ -| // This file contains auto-generated code.\n// Generated from `System.Collections, Version=7.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`.\n\nnamespace System\n{\nnamespace Collections\n{\nnamespace Generic\n{\npublic class Stack : System.Collections.Generic.IEnumerable, System.Collections.Generic.IReadOnlyCollection, System.Collections.ICollection, System.Collections.IEnumerable\n{\n void System.Collections.ICollection.CopyTo(System.Array array, int arrayIndex) => throw null;\n public int Count { get => throw null; }\n System.Collections.Generic.IEnumerator System.Collections.Generic.IEnumerable.GetEnumerator() => throw null;\n System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() => throw null;\n bool System.Collections.ICollection.IsSynchronized { get => throw null; }\n public T Peek() => throw null;\n object System.Collections.ICollection.SyncRoot { get => throw null; }\n}\n\n}\n}\n}\n\n\n// This file contains auto-generated code.\n// Generated from `System.Collections.NonGeneric, Version=7.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`.\n\nnamespace System\n{\nnamespace Collections\n{\npublic class SortedList : System.Collections.ICollection, System.Collections.IDictionary, System.Collections.IEnumerable, System.ICloneable\n{\n public virtual void Add(object key, object value) => throw null;\n public virtual void Clear() => throw null;\n public virtual object Clone() => throw null;\n public virtual bool Contains(object key) => throw null;\n public virtual void CopyTo(System.Array array, int arrayIndex) => throw null;\n public virtual int Count { get => throw null; }\n public virtual object GetByIndex(int index) => throw null;\n public virtual System.Collections.IDictionaryEnumerator GetEnumerator() => throw null;\n System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() => throw null;\n public virtual bool IsFixedSize { get => throw null; }\n public virtual bool IsReadOnly { get => throw null; }\n public virtual bool IsSynchronized { get => throw null; }\n public virtual object this[object key] { get => throw null; set => throw null; }\n public virtual System.Collections.ICollection Keys { get => throw null; }\n public virtual void Remove(object key) => throw null;\n public virtual object SyncRoot { get => throw null; }\n public virtual System.Collections.ICollection Values { get => throw null; }\n}\n\n}\n}\n\n\n// This file contains auto-generated code.\n// Generated from `System.Collections.Specialized, Version=7.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`.\n\nnamespace System\n{\nnamespace Collections\n{\nnamespace Specialized\n{\npublic abstract class NameObjectCollectionBase : System.Collections.ICollection, System.Collections.IEnumerable, System.Runtime.Serialization.IDeserializationCallback, System.Runtime.Serialization.ISerializable\n{\n void System.Collections.ICollection.CopyTo(System.Array array, int index) => throw null;\n public virtual int Count { get => throw null; }\n public virtual System.Collections.IEnumerator GetEnumerator() => throw null;\n public virtual void GetObjectData(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) => throw null;\n bool System.Collections.ICollection.IsSynchronized { get => throw null; }\n public virtual void OnDeserialization(object sender) => throw null;\n object System.Collections.ICollection.SyncRoot { get => throw null; }\n}\n\npublic class NameValueCollection : System.Collections.Specialized.NameObjectCollectionBase\n{\n public string this[string name] { get => throw null; set => throw null; }\n}\n\n}\n}\n}\n\n\n// This file contains auto-generated code.\n// Generated from `System.ComponentModel.TypeConverter, Version=7.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`.\n\nnamespace System\n{\nnamespace ComponentModel\n{\npublic class ComponentConverter : System.ComponentModel.ReferenceConverter\n{\n}\n\npublic class DefaultEventAttribute : System.Attribute\n{\n public DefaultEventAttribute(string name) => throw null;\n public override bool Equals(object obj) => throw null;\n public override int GetHashCode() => throw null;\n}\n\npublic class DefaultPropertyAttribute : System.Attribute\n{\n public DefaultPropertyAttribute(string name) => throw null;\n public override bool Equals(object obj) => throw null;\n public override int GetHashCode() => throw null;\n}\n\npublic class ReferenceConverter : System.ComponentModel.TypeConverter\n{\n}\n\npublic class TypeConverter\n{\n}\n\n}\nnamespace Timers\n{\npublic class TimersDescriptionAttribute\n{\n public TimersDescriptionAttribute(string description) => throw null;\n internal TimersDescriptionAttribute(string description, string unused) => throw null;\n}\n\n}\n}\n\n\n// This file contains auto-generated code.\n// Generated from `System.Linq, Version=7.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`.\n\nnamespace System\n{\nnamespace Linq\n{\npublic static class Enumerable\n{\n public static System.Collections.Generic.IEnumerable Select(this System.Collections.Generic.IEnumerable source, System.Func selector) => throw null;\n}\n\n}\n}\n\n\n// This file contains auto-generated code.\n// Generated from `System.Linq.Expressions, Version=7.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`.\n\nnamespace System\n{\nnamespace Linq\n{\npublic interface IQueryable : System.Collections.IEnumerable\n{\n}\n\n}\nnamespace Runtime\n{\nnamespace CompilerServices\n{\npublic class CallSite\n{\n internal CallSite(System.Runtime.CompilerServices.CallSiteBinder binder) => throw null;\n}\n\npublic class CallSite : System.Runtime.CompilerServices.CallSite where T: class\n{\n private CallSite() : base(default(System.Runtime.CompilerServices.CallSiteBinder)) => throw null;\n private CallSite(System.Runtime.CompilerServices.CallSiteBinder binder) : base(default(System.Runtime.CompilerServices.CallSiteBinder)) => throw null;\n}\n\npublic abstract class CallSiteBinder\n{\n}\n\n}\n}\n}\n\n\n// This file contains auto-generated code.\n// Generated from `System.Linq.Parallel, Version=7.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`.\n\nnamespace System\n{\nnamespace Linq\n{\npublic static class ParallelEnumerable\n{\n public static System.Linq.ParallelQuery AsParallel(this System.Collections.IEnumerable source) => throw null;\n}\n\npublic class ParallelQuery : System.Collections.IEnumerable\n{\n System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() => throw null;\n internal ParallelQuery(System.Linq.Parallel.QuerySettings specifiedSettings) => throw null;\n}\n\nnamespace Parallel\n{\ninternal struct QuerySettings\n{\n}\n\n}\n}\n}\n\n\n// This file contains auto-generated code.\n// Generated from `System.Linq.Queryable, Version=7.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`.\n\nnamespace System\n{\nnamespace Linq\n{\npublic static class Queryable\n{\n public static System.Linq.IQueryable AsQueryable(this System.Collections.IEnumerable source) => throw null;\n}\n\n}\n}\n\n\n// This file contains auto-generated code.\n// Generated from `System.ObjectModel, Version=7.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`.\n\nnamespace System\n{\nnamespace ComponentModel\n{\npublic class TypeConverterAttribute : System.Attribute\n{\n public override bool Equals(object obj) => throw null;\n public override int GetHashCode() => throw null;\n public TypeConverterAttribute() => throw null;\n public TypeConverterAttribute(System.Type type) => throw null;\n public TypeConverterAttribute(string typeName) => throw null;\n}\n\npublic class TypeDescriptionProviderAttribute : System.Attribute\n{\n public TypeDescriptionProviderAttribute(System.Type type) => throw null;\n public TypeDescriptionProviderAttribute(string typeName) => throw null;\n}\n\n}\nnamespace Windows\n{\nnamespace Markup\n{\npublic class ValueSerializerAttribute : System.Attribute\n{\n public ValueSerializerAttribute(System.Type valueSerializerType) => throw null;\n public ValueSerializerAttribute(string valueSerializerTypeName) => throw null;\n}\n\n}\n}\n}\n\n\n// This file contains auto-generated code.\n// Generated from `System.Private.Uri, Version=7.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`.\n\nnamespace System\n{\npublic class Uri : System.Runtime.Serialization.ISerializable\n{\n public override bool Equals(object comparand) => throw null;\n public override int GetHashCode() => throw null;\n void System.Runtime.Serialization.ISerializable.GetObjectData(System.Runtime.Serialization.SerializationInfo serializationInfo, System.Runtime.Serialization.StreamingContext streamingContext) => throw null;\n public override string ToString() => throw null;\n}\n\n}\n\n\n// This file contains auto-generated code.\n// Generated from `System.Runtime.Serialization.Primitives, Version=7.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`.\n\nnamespace System\n{\nnamespace Runtime\n{\nnamespace Serialization\n{\npublic class DataContractAttribute : System.Attribute\n{\n public DataContractAttribute() => throw null;\n}\n\npublic class DataMemberAttribute : System.Attribute\n{\n public DataMemberAttribute() => throw null;\n}\n\n}\n}\n}\n\n\n// This file contains auto-generated code.\n// Generated from `System.Text.RegularExpressions, Version=7.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`.\n\nnamespace System\n{\nnamespace Text\n{\nnamespace RegularExpressions\n{\npublic class Capture\n{\n internal Capture(string text, int index, int length) => throw null;\n public override string ToString() => throw null;\n}\n\npublic class GeneratedRegexAttribute : System.Attribute\n{\n public GeneratedRegexAttribute(string pattern) => throw null;\n public GeneratedRegexAttribute(string pattern, System.Text.RegularExpressions.RegexOptions options) => throw null;\n public GeneratedRegexAttribute(string pattern, System.Text.RegularExpressions.RegexOptions options, int matchTimeoutMilliseconds) => throw null;\n public GeneratedRegexAttribute(string pattern, System.Text.RegularExpressions.RegexOptions options, int matchTimeoutMilliseconds, string cultureName) => throw null;\n public GeneratedRegexAttribute(string pattern, System.Text.RegularExpressions.RegexOptions options, string cultureName) => throw null;\n}\n\npublic class Group : System.Text.RegularExpressions.Capture\n{\n internal Group(string text, int[] caps, int capcount, string name) : base(default(string), default(int), default(int)) => throw null;\n}\n\npublic class Match : System.Text.RegularExpressions.Group\n{\n internal Match(System.Text.RegularExpressions.Regex regex, int capcount, string text, int textLength) : base(default(string), default(int[]), default(int), default(string)) => throw null;\n}\n\npublic class Regex : System.Runtime.Serialization.ISerializable\n{\n void System.Runtime.Serialization.ISerializable.GetObjectData(System.Runtime.Serialization.SerializationInfo si, System.Runtime.Serialization.StreamingContext context) => throw null;\n public System.Text.RegularExpressions.Match Match(string input) => throw null;\n public static System.Text.RegularExpressions.Match Match(string input, string pattern) => throw null;\n public static System.Text.RegularExpressions.Match Match(string input, string pattern, System.Text.RegularExpressions.RegexOptions options, System.TimeSpan matchTimeout) => throw null;\n public Regex(string pattern) => throw null;\n public Regex(string pattern, System.Text.RegularExpressions.RegexOptions options, System.TimeSpan matchTimeout) => throw null;\n public string Replace(string input, string replacement) => throw null;\n public override string ToString() => throw null;\n}\n\n[System.Flags]\npublic enum RegexOptions : int\n{\n IgnoreCase = 1,\n}\n\n}\n}\n}\n\n\n// This file contains auto-generated code.\n// Generated from `System.Web, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null`.\n\nnamespace System\n{\nnamespace Web\n{\npublic class HtmlString : System.Web.IHtmlString\n{\n}\n\npublic class HttpContextBase\n{\n public virtual System.Web.HttpRequestBase Request { get => throw null; }\n}\n\npublic class HttpCookie\n{\n}\n\npublic abstract class HttpCookieCollection : System.Collections.Specialized.NameObjectCollectionBase\n{\n}\n\npublic class HttpRequest\n{\n}\n\npublic class HttpRequestBase\n{\n public virtual System.Collections.Specialized.NameValueCollection QueryString { get => throw null; }\n}\n\npublic class HttpResponse\n{\n}\n\npublic class HttpResponseBase\n{\n}\n\npublic class HttpServerUtility\n{\n}\n\npublic interface IHtmlString\n{\n}\n\npublic interface IHttpHandler\n{\n}\n\npublic interface IServiceProvider\n{\n}\n\npublic class UnvalidatedRequestValues\n{\n}\n\npublic class UnvalidatedRequestValuesBase\n{\n}\n\nnamespace Mvc\n{\npublic class ActionMethodSelectorAttribute : System.Attribute\n{\n}\n\npublic class ActionResult\n{\n}\n\npublic class ControllerContext\n{\n}\n\npublic class FilterAttribute : System.Attribute\n{\n}\n\npublic class GlobalFilterCollection\n{\n}\n\ninternal interface IFilterProvider\n{\n}\n\npublic interface IViewDataContainer\n{\n}\n\npublic class ViewContext : System.Web.Mvc.ControllerContext\n{\n}\n\npublic class ViewResult : System.Web.Mvc.ViewResultBase\n{\n}\n\npublic class ViewResultBase : System.Web.Mvc.ActionResult\n{\n}\n\n}\nnamespace Routing\n{\npublic class RequestContext\n{\n}\n\npublic class Route\n{\n}\n\npublic class RouteCollection\n{\n}\n\npublic class RouteTable\n{\n}\n\n}\nnamespace Script\n{\nnamespace Serialization\n{\npublic abstract class JavaScriptTypeResolver\n{\n}\n\n}\n}\nnamespace Security\n{\npublic class MembershipUser\n{\n}\n\n}\nnamespace SessionState\n{\npublic class HttpSessionState\n{\n}\n\n}\nnamespace UI\n{\npublic class Control\n{\n}\n\nnamespace WebControls\n{\npublic class WebControl : System.Web.UI.Control\n{\n}\n\n}\n}\n}\n}\n\n\n | diff --git a/csharp/ql/test/query-tests/Stubs/Minimal/MinimalStubsFromSource.qlref b/csharp/ql/test/query-tests/Stubs/Minimal/MinimalStubsFromSource.qlref deleted file mode 100644 index 53cbcd647b7a..000000000000 --- a/csharp/ql/test/query-tests/Stubs/Minimal/MinimalStubsFromSource.qlref +++ /dev/null @@ -1 +0,0 @@ -Stubs/MinimalStubsFromSource.ql diff --git a/csharp/ql/test/query-tests/Stubs/Minimal/Test.cs b/csharp/ql/test/query-tests/Stubs/Minimal/Test.cs deleted file mode 100644 index b3f4aca07c1e..000000000000 --- a/csharp/ql/test/query-tests/Stubs/Minimal/Test.cs +++ /dev/null @@ -1,123 +0,0 @@ -using System; -using System.IO; -using System.Text; -using System.Collections; -using System.Collections.Generic; -using System.Collections.Specialized; -using System.Linq; -using System.Runtime.Serialization; -using System.Threading.Tasks; -using System.Web; -using System.Web.UI.WebControls; -using System.Text.RegularExpressions; - -public class RegexHandler -{ - private static readonly string JAVA_CLASS_REGEX = "^(([a-z])+.)+[A-Z]([a-z])+$"; - - public void ProcessRequest() - { - string userInput = ""; - - // BAD: - // Artificial regexes - new Regex("^([a-z]+)+$").Match(userInput); - new Regex("^([a-z]*)*$").Replace(userInput, ""); - // Known exponential blowup regex for e-mail address validation - // Problematic part is: ([a-zA-Z0-9]+))* - new Regex("^([a-zA-Z0-9])(([\\-.]|[_]+)?([a-zA-Z0-9]+))*(@){1}[a-z0-9]+[.]{1}(([a-z]{2,3})|([a-z]{2,3}[.]{1}[a-z]{2,3}))$").Match(userInput); - // Known exponential blowup regex for Java class name validation - // Problematic part is: (([a-z])+.)+ - new Regex(JAVA_CLASS_REGEX).Match(userInput); - // Static use - Regex.Match(userInput, JAVA_CLASS_REGEX); - // GOOD: - new Regex("^(([a-b]+[c-z]+)+$").Match(userInput); - new Regex("^([a-z]+)+$", RegexOptions.IgnoreCase, TimeSpan.FromSeconds(1)).Match(userInput); - Regex.Match(userInput, JAVA_CLASS_REGEX, RegexOptions.IgnoreCase, TimeSpan.FromSeconds(1)); - // Known possible FP. - new Regex("^[a-z0-9]+([_.-][a-z0-9]+)*$").Match(userInput); - } -} - -// The only purpose of this class is to make sure the extractor extracts the -// relevant library methods -public class LibraryTypeDataFlow -{ - void M() - { - int i; - int.Parse(""); - int.TryParse("", out i); - - bool b; - bool.Parse(""); - bool.TryParse("", out b); - - Uri uri = null; - uri.ToString(); - - StringReader sr = new StringReader(""); - - string s = new string(new[] { 'a' }); - string.Join("", "", "", ""); - - StringBuilder sb = new StringBuilder(""); - - Lazy l = new Lazy(() => 42); - - IEnumerable ie = null; - ie.GetEnumerator(); - ie.AsParallel(); - ie.AsQueryable(); - IEnumerable ieint = null; - ieint.Select(x => x); - List list = null; - list.Find(x => x > 0); - Stack stack = null; - stack.Peek(); - ArrayList al = null; - ArrayList.FixedSize(al); - SortedList sl = null; - sl.GetByIndex(0); - - Convert.ToInt32("0"); - - DataContract dc = null; - s = dc.AString; - - KeyValuePair kvp = new KeyValuePair(0, ""); - - IEnumerator ienum = null; - object o = ienum.Current; - - IEnumerator ienumint = null; - i = ienumint.Current; - - var task = new Task(() => { }); - Task.WhenAll(null, null); - Task.WhenAny(null, null); - Task.Factory.ContinueWhenAll((Task[])null, (Func)null); - - var task2 = new Task(() => 42); - Task.Factory.ContinueWhenAny(new Task[] { task2 }, t => t.Result.ToString()); - - Encoding.Unicode.GetString(Encoding.Unicode.GetBytes("")); - - Path.Combine("", ""); - Path.GetDirectoryName(""); - Path.GetExtension(""); - Path.GetFileName(""); - Path.GetFileNameWithoutExtension(""); - Path.GetPathRoot(""); - HttpContextBase context = null; - string name = context.Request.QueryString["name"]; - } - - [DataContract] - public class DataContract - { - [DataMember] - public string AString { get; set; } - } -} diff --git a/csharp/ql/test/query-tests/Stubs/Minimal/options b/csharp/ql/test/query-tests/Stubs/Minimal/options deleted file mode 100644 index 52687b5cf455..000000000000 --- a/csharp/ql/test/query-tests/Stubs/Minimal/options +++ /dev/null @@ -1 +0,0 @@ -semmle-extractor-options: /r:System.Text.RegularExpressions.dll /r:System.Collections.Specialized.dll /r:System.Net.dll /r:System.Web.dll /r:System.Net.HttpListener.dll /r:System.Collections.Specialized.dll /r:System.Private.Uri.dll /r:System.Runtime.Extensions.dll /r:System.Linq.Parallel.dll /r:System.Collections.Concurrent.dll /r:System.Linq.Expressions.dll /r:System.Collections.dll /r:System.Linq.Queryable.dll /r:System.Linq.dll /r:System.Collections.NonGeneric.dll /r:System.ObjectModel.dll /r:System.ComponentModel.TypeConverter.dll /r:System.IO.Compression.dll /r:System.IO.Pipes.dll /r:System.Net.Primitives.dll /r:System.Net.Security.dll /r:System.Security.Cryptography.Primitives.dll /r:System.Text.RegularExpressions.dll ${testdir}/../../../resources/stubs/System.Web.cs /r:System.Runtime.Serialization.Primitives.dll diff --git a/csharp/ql/test/query-tests/Stubs/References/Test.cs b/csharp/ql/test/query-tests/Stubs/References/Test.cs deleted file mode 100644 index e73d69497d2e..000000000000 --- a/csharp/ql/test/query-tests/Stubs/References/Test.cs +++ /dev/null @@ -1,6 +0,0 @@ -namespace Test -{ - public class Class1 - { - } -} diff --git a/csharp/ql/test/query-tests/Stubs/References/files.expected b/csharp/ql/test/query-tests/Stubs/References/files.expected deleted file mode 100644 index 2a197bd49aed..000000000000 --- a/csharp/ql/test/query-tests/Stubs/References/files.expected +++ /dev/null @@ -1 +0,0 @@ -| Test.cs:0:0:0:0 | Test.cs | diff --git a/csharp/ql/test/query-tests/Stubs/References/files.ql b/csharp/ql/test/query-tests/Stubs/References/files.ql deleted file mode 100644 index bea5557a25f1..000000000000 --- a/csharp/ql/test/query-tests/Stubs/References/files.ql +++ /dev/null @@ -1,5 +0,0 @@ -import csharp - -from File f -where f.fromSource() -select f diff --git a/csharp/ql/test/query-tests/Stubs/References/options b/csharp/ql/test/query-tests/Stubs/References/options deleted file mode 100644 index d469ae7afb88..000000000000 --- a/csharp/ql/test/query-tests/Stubs/References/options +++ /dev/null @@ -1,3 +0,0 @@ -semmle-extractor-options: --load-sources-from-project:../../../resources/stubs/_frameworks/Microsoft.AspNetCore.App/Microsoft.AspNetCore.App.csproj -semmle-extractor-options: /nostdlib -semmle-extractor-options: /noconfig diff --git a/csharp/ql/test/resources/stubs/_frameworks/Microsoft.AspNetCore.App/Microsoft.AspNetCore.Authorization.cs b/csharp/ql/test/resources/stubs/_frameworks/Microsoft.AspNetCore.App/Microsoft.AspNetCore.Authorization.cs index 616385358b97..da6e78c128b4 100644 --- a/csharp/ql/test/resources/stubs/_frameworks/Microsoft.AspNetCore.App/Microsoft.AspNetCore.Authorization.cs +++ b/csharp/ql/test/resources/stubs/_frameworks/Microsoft.AspNetCore.App/Microsoft.AspNetCore.Authorization.cs @@ -6,6 +6,7 @@ namespace AspNetCore { namespace Authorization { + [System.AttributeUsage((System.AttributeTargets)68, AllowMultiple = false, Inherited = true)] public class AllowAnonymousAttribute : System.Attribute, Microsoft.AspNetCore.Authorization.IAllowAnonymous { public AllowAnonymousAttribute() => throw null; @@ -120,6 +121,7 @@ public static partial class AuthorizationServiceExtensions public static System.Threading.Tasks.Task AuthorizeAsync(this Microsoft.AspNetCore.Authorization.IAuthorizationService service, System.Security.Claims.ClaimsPrincipal user, Microsoft.AspNetCore.Authorization.AuthorizationPolicy policy) => throw null; public static System.Threading.Tasks.Task AuthorizeAsync(this Microsoft.AspNetCore.Authorization.IAuthorizationService service, System.Security.Claims.ClaimsPrincipal user, string policyName) => throw null; } + [System.AttributeUsage((System.AttributeTargets)68, AllowMultiple = true, Inherited = true)] public class AuthorizeAttribute : System.Attribute, Microsoft.AspNetCore.Authorization.IAuthorizeData { public string AuthenticationSchemes { get => throw null; set { } } diff --git a/csharp/ql/test/resources/stubs/_frameworks/Microsoft.AspNetCore.App/Microsoft.AspNetCore.Components.Web.cs b/csharp/ql/test/resources/stubs/_frameworks/Microsoft.AspNetCore.App/Microsoft.AspNetCore.Components.Web.cs index 042e1a767545..b8b7c67eb2ae 100644 --- a/csharp/ql/test/resources/stubs/_frameworks/Microsoft.AspNetCore.App/Microsoft.AspNetCore.Components.Web.cs +++ b/csharp/ql/test/resources/stubs/_frameworks/Microsoft.AspNetCore.App/Microsoft.AspNetCore.Components.Web.cs @@ -6,6 +6,7 @@ namespace AspNetCore { namespace Components { + [System.AttributeUsage((System.AttributeTargets)4, AllowMultiple = true, Inherited = true)] public sealed class BindInputElementAttribute : System.Attribute { public string ChangeAttribute { get => throw null; } diff --git a/csharp/ql/test/resources/stubs/_frameworks/Microsoft.AspNetCore.App/Microsoft.AspNetCore.Components.cs b/csharp/ql/test/resources/stubs/_frameworks/Microsoft.AspNetCore.App/Microsoft.AspNetCore.Components.cs index 5015bd3a9f98..518725e9c7d5 100644 --- a/csharp/ql/test/resources/stubs/_frameworks/Microsoft.AspNetCore.App/Microsoft.AspNetCore.Components.cs +++ b/csharp/ql/test/resources/stubs/_frameworks/Microsoft.AspNetCore.App/Microsoft.AspNetCore.Components.cs @@ -73,6 +73,7 @@ public static class BindConverter public static bool TryConvertToTimeOnly(object obj, System.Globalization.CultureInfo culture, out System.TimeOnly value) => throw null; public static bool TryConvertToTimeOnly(object obj, System.Globalization.CultureInfo culture, string format, out System.TimeOnly value) => throw null; } + [System.AttributeUsage((System.AttributeTargets)4, AllowMultiple = true, Inherited = true)] public sealed class BindElementAttribute : System.Attribute { public string ChangeAttribute { get => throw null; } @@ -81,11 +82,13 @@ public sealed class BindElementAttribute : System.Attribute public string Suffix { get => throw null; } public string ValueAttribute { get => throw null; } } + [System.AttributeUsage((System.AttributeTargets)128, AllowMultiple = false, Inherited = true)] public sealed class CascadingParameterAttribute : System.Attribute { public CascadingParameterAttribute() => throw null; public string Name { get => throw null; set { } } } + [System.AttributeUsage((System.AttributeTargets)4, AllowMultiple = true, Inherited = false)] public sealed class CascadingTypeParameterAttribute : System.Attribute { public CascadingTypeParameterAttribute(string name) => throw null; @@ -161,6 +164,7 @@ public class DynamicComponent : Microsoft.AspNetCore.Components.IComponent public System.Threading.Tasks.Task SetParametersAsync(Microsoft.AspNetCore.Components.ParameterView parameters) => throw null; public System.Type Type { get => throw null; set { } } } + [System.AttributeUsage((System.AttributeTargets)128, AllowMultiple = false)] public sealed class EditorRequiredAttribute : System.Attribute { public EditorRequiredAttribute() => throw null; @@ -300,6 +304,7 @@ public struct EventCallbackWorkItem public static readonly Microsoft.AspNetCore.Components.EventCallbackWorkItem Empty; public System.Threading.Tasks.Task InvokeAsync(object arg) => throw null; } + [System.AttributeUsage((System.AttributeTargets)4, AllowMultiple = true, Inherited = true)] public sealed class EventHandlerAttribute : System.Attribute { public string AttributeName { get => throw null; } @@ -336,6 +341,7 @@ public class ComponentStatePersistenceManager public Microsoft.AspNetCore.Components.PersistentComponentState State { get => throw null; } } } + [System.AttributeUsage((System.AttributeTargets)128, AllowMultiple = false, Inherited = true)] public sealed class InjectAttribute : System.Attribute { public InjectAttribute() => throw null; @@ -345,6 +351,7 @@ public interface IPersistentComponentStateStore System.Threading.Tasks.Task> GetPersistedStateAsync(); System.Threading.Tasks.Task PersistStateAsync(System.Collections.Generic.IReadOnlyDictionary state); } + [System.AttributeUsage((System.AttributeTargets)4, AllowMultiple = false, Inherited = true)] public sealed class LayoutAttribute : System.Attribute { public LayoutAttribute(System.Type layoutType) => throw null; @@ -447,6 +454,7 @@ public abstract class OwningComponentBase : Microsoft.AspNetCore.Compo protected OwningComponentBase() => throw null; protected TService Service { get => throw null; } } + [System.AttributeUsage((System.AttributeTargets)128, AllowMultiple = false, Inherited = true)] public sealed class ParameterAttribute : System.Attribute { public bool CaptureUnmatchedValues { get => throw null; set { } } @@ -647,6 +655,7 @@ public enum RenderTreeFrameType : short Markup = 8, } } + [System.AttributeUsage((System.AttributeTargets)4, AllowMultiple = true, Inherited = false)] public sealed class RouteAttribute : System.Attribute { public RouteAttribute(string template) => throw null; @@ -714,6 +723,7 @@ public class Router : Microsoft.AspNetCore.Components.IComponent, System.IDispos public System.Threading.Tasks.Task SetParametersAsync(Microsoft.AspNetCore.Components.ParameterView parameters) => throw null; } } + [System.AttributeUsage((System.AttributeTargets)128, AllowMultiple = false, Inherited = true)] public sealed class SupplyParameterFromQueryAttribute : System.Attribute { public SupplyParameterFromQueryAttribute() => throw null; diff --git a/csharp/ql/test/resources/stubs/_frameworks/Microsoft.AspNetCore.App/Microsoft.AspNetCore.Cors.cs b/csharp/ql/test/resources/stubs/_frameworks/Microsoft.AspNetCore.App/Microsoft.AspNetCore.Cors.cs index ccee0b3f9915..11e0b379bbb6 100644 --- a/csharp/ql/test/resources/stubs/_frameworks/Microsoft.AspNetCore.App/Microsoft.AspNetCore.Cors.cs +++ b/csharp/ql/test/resources/stubs/_frameworks/Microsoft.AspNetCore.App/Microsoft.AspNetCore.Cors.cs @@ -25,10 +25,12 @@ public class CorsPolicyMetadata : Microsoft.AspNetCore.Cors.Infrastructure.ICors public CorsPolicyMetadata(Microsoft.AspNetCore.Cors.Infrastructure.CorsPolicy policy) => throw null; public Microsoft.AspNetCore.Cors.Infrastructure.CorsPolicy Policy { get => throw null; } } + [System.AttributeUsage((System.AttributeTargets)68, AllowMultiple = false, Inherited = false)] public class DisableCorsAttribute : System.Attribute, Microsoft.AspNetCore.Cors.Infrastructure.ICorsMetadata, Microsoft.AspNetCore.Cors.Infrastructure.IDisableCorsAttribute { public DisableCorsAttribute() => throw null; } + [System.AttributeUsage((System.AttributeTargets)68, AllowMultiple = false, Inherited = true)] public class EnableCorsAttribute : System.Attribute, Microsoft.AspNetCore.Cors.Infrastructure.ICorsMetadata, Microsoft.AspNetCore.Cors.Infrastructure.IEnableCorsAttribute { public EnableCorsAttribute() => throw null; diff --git a/csharp/ql/test/resources/stubs/_frameworks/Microsoft.AspNetCore.App/Microsoft.AspNetCore.Hosting.Abstractions.cs b/csharp/ql/test/resources/stubs/_frameworks/Microsoft.AspNetCore.App/Microsoft.AspNetCore.Hosting.Abstractions.cs index e03088e509dd..ccc28330ad79 100644 --- a/csharp/ql/test/resources/stubs/_frameworks/Microsoft.AspNetCore.App/Microsoft.AspNetCore.Hosting.Abstractions.cs +++ b/csharp/ql/test/resources/stubs/_frameworks/Microsoft.AspNetCore.App/Microsoft.AspNetCore.Hosting.Abstractions.cs @@ -34,6 +34,7 @@ public static partial class HostingEnvironmentExtensions public static bool IsProduction(this Microsoft.AspNetCore.Hosting.IHostingEnvironment hostingEnvironment) => throw null; public static bool IsStaging(this Microsoft.AspNetCore.Hosting.IHostingEnvironment hostingEnvironment) => throw null; } + [System.AttributeUsage((System.AttributeTargets)1, Inherited = false, AllowMultiple = true)] public sealed class HostingStartupAttribute : System.Attribute { public HostingStartupAttribute(System.Type hostingStartupType) => throw null; diff --git a/csharp/ql/test/resources/stubs/_frameworks/Microsoft.AspNetCore.App/Microsoft.AspNetCore.Http.Abstractions.cs b/csharp/ql/test/resources/stubs/_frameworks/Microsoft.AspNetCore.App/Microsoft.AspNetCore.Http.Abstractions.cs index 392bccee3da1..9b767d8e4732 100644 --- a/csharp/ql/test/resources/stubs/_frameworks/Microsoft.AspNetCore.App/Microsoft.AspNetCore.Http.Abstractions.cs +++ b/csharp/ql/test/resources/stubs/_frameworks/Microsoft.AspNetCore.App/Microsoft.AspNetCore.Http.Abstractions.cs @@ -105,6 +105,7 @@ public interface ICorsMetadata } namespace Http { + [System.AttributeUsage((System.AttributeTargets)2048, Inherited = false, AllowMultiple = false)] public sealed class AsParametersAttribute : System.Attribute { public AsParametersAttribute() => throw null; diff --git a/csharp/ql/test/resources/stubs/_frameworks/Microsoft.AspNetCore.App/Microsoft.AspNetCore.Http.Extensions.cs b/csharp/ql/test/resources/stubs/_frameworks/Microsoft.AspNetCore.App/Microsoft.AspNetCore.Http.Extensions.cs index b6f38080c296..51d392fd4711 100644 --- a/csharp/ql/test/resources/stubs/_frameworks/Microsoft.AspNetCore.App/Microsoft.AspNetCore.Http.Extensions.cs +++ b/csharp/ql/test/resources/stubs/_frameworks/Microsoft.AspNetCore.App/Microsoft.AspNetCore.Http.Extensions.cs @@ -6,11 +6,13 @@ namespace AspNetCore { namespace Http { + [System.AttributeUsage((System.AttributeTargets)64, Inherited = false, AllowMultiple = false)] public sealed class EndpointDescriptionAttribute : System.Attribute, Microsoft.AspNetCore.Http.Metadata.IEndpointDescriptionMetadata { public EndpointDescriptionAttribute(string description) => throw null; public string Description { get => throw null; } } + [System.AttributeUsage((System.AttributeTargets)64, Inherited = false, AllowMultiple = false)] public sealed class EndpointSummaryAttribute : System.Attribute, Microsoft.AspNetCore.Http.Metadata.IEndpointSummaryMetadata { public EndpointSummaryAttribute(string summary) => throw null; @@ -195,6 +197,7 @@ public static partial class SessionExtensions public static void SetInt32(this Microsoft.AspNetCore.Http.ISession session, string key, int value) => throw null; public static void SetString(this Microsoft.AspNetCore.Http.ISession session, string key, string value) => throw null; } + [System.AttributeUsage((System.AttributeTargets)4164, Inherited = false, AllowMultiple = false)] public sealed class TagsAttribute : System.Attribute, Microsoft.AspNetCore.Http.Metadata.ITagsMetadata { public TagsAttribute(params string[] tags) => throw null; diff --git a/csharp/ql/test/resources/stubs/_frameworks/Microsoft.AspNetCore.App/Microsoft.AspNetCore.Mvc.Core.cs b/csharp/ql/test/resources/stubs/_frameworks/Microsoft.AspNetCore.App/Microsoft.AspNetCore.Mvc.Core.cs index 2b69a8d7dd77..8f413e6dcdad 100644 --- a/csharp/ql/test/resources/stubs/_frameworks/Microsoft.AspNetCore.App/Microsoft.AspNetCore.Mvc.Core.cs +++ b/csharp/ql/test/resources/stubs/_frameworks/Microsoft.AspNetCore.App/Microsoft.AspNetCore.Mvc.Core.cs @@ -67,6 +67,7 @@ public class AcceptedResult : Microsoft.AspNetCore.Mvc.ObjectResult public string Location { get => throw null; set { } } public override void OnFormatting(Microsoft.AspNetCore.Mvc.ActionContext context) => throw null; } + [System.AttributeUsage((System.AttributeTargets)64, AllowMultiple = true, Inherited = true)] public sealed class AcceptVerbsAttribute : System.Attribute, Microsoft.AspNetCore.Mvc.Routing.IActionHttpMethodProvider, Microsoft.AspNetCore.Mvc.Routing.IRouteTemplateProvider { public AcceptVerbsAttribute(string method) => throw null; @@ -80,6 +81,7 @@ public sealed class AcceptVerbsAttribute : System.Attribute, Microsoft.AspNetCor } namespace ActionConstraints { + [System.AttributeUsage((System.AttributeTargets)64, AllowMultiple = false, Inherited = true)] public abstract class ActionMethodSelectorAttribute : System.Attribute, Microsoft.AspNetCore.Mvc.ActionConstraints.IActionConstraint, Microsoft.AspNetCore.Mvc.ActionConstraints.IActionConstraintMetadata { public bool Accept(Microsoft.AspNetCore.Mvc.ActionConstraints.ActionConstraintContext context) => throw null; @@ -96,10 +98,12 @@ public class HttpMethodActionConstraint : Microsoft.AspNetCore.Mvc.ActionConstra public int Order { get => throw null; } } } + [System.AttributeUsage((System.AttributeTargets)128, AllowMultiple = false, Inherited = true)] public class ActionContextAttribute : System.Attribute { public ActionContextAttribute() => throw null; } + [System.AttributeUsage((System.AttributeTargets)64, AllowMultiple = false, Inherited = true)] public sealed class ActionNameAttribute : System.Attribute { public ActionNameAttribute(string name) => throw null; @@ -138,15 +142,18 @@ public class ApiBehaviorOptions : System.Collections.Generic.IEnumerable throw null; set { } } public bool SuppressModelStateInvalidFilter { get => throw null; set { } } } + [System.AttributeUsage((System.AttributeTargets)5, AllowMultiple = false, Inherited = true)] public class ApiControllerAttribute : Microsoft.AspNetCore.Mvc.ControllerAttribute, Microsoft.AspNetCore.Mvc.Infrastructure.IApiBehaviorMetadata, Microsoft.AspNetCore.Mvc.Filters.IFilterMetadata { public ApiControllerAttribute() => throw null; } + [System.AttributeUsage((System.AttributeTargets)64, AllowMultiple = false, Inherited = true)] public sealed class ApiConventionMethodAttribute : System.Attribute { public System.Type ConventionType { get => throw null; } public ApiConventionMethodAttribute(System.Type conventionType, string methodName) => throw null; } + [System.AttributeUsage((System.AttributeTargets)5, AllowMultiple = true, Inherited = true)] public sealed class ApiConventionTypeAttribute : System.Attribute { public System.Type ConventionType { get => throw null; } @@ -159,6 +166,7 @@ public class ApiDescriptionActionData } namespace ApiExplorer { + [System.AttributeUsage((System.AttributeTargets)2112, AllowMultiple = false, Inherited = false)] public sealed class ApiConventionNameMatchAttribute : System.Attribute { public ApiConventionNameMatchAttribute(Microsoft.AspNetCore.Mvc.ApiExplorer.ApiConventionNameMatchBehavior matchBehavior) => throw null; @@ -176,6 +184,7 @@ public sealed class ApiConventionResult public ApiConventionResult(System.Collections.Generic.IReadOnlyList responseMetadataProviders) => throw null; public System.Collections.Generic.IReadOnlyList ResponseMetadataProviders { get => throw null; } } + [System.AttributeUsage((System.AttributeTargets)2048, AllowMultiple = false, Inherited = false)] public sealed class ApiConventionTypeMatchAttribute : System.Attribute { public ApiConventionTypeMatchAttribute(Microsoft.AspNetCore.Mvc.ApiExplorer.ApiConventionTypeMatchBehavior matchBehavior) => throw null; @@ -216,6 +225,7 @@ public interface IApiResponseTypeMetadataProvider System.Collections.Generic.IReadOnlyList GetSupportedContentTypes(string contentType, System.Type objectType); } } + [System.AttributeUsage((System.AttributeTargets)68, AllowMultiple = false, Inherited = true)] public class ApiExplorerSettingsAttribute : System.Attribute, Microsoft.AspNetCore.Mvc.ApiExplorer.IApiDescriptionGroupNameProvider, Microsoft.AspNetCore.Mvc.ApiExplorer.IApiDescriptionVisibilityProvider { public ApiExplorerSettingsAttribute() => throw null; @@ -442,6 +452,7 @@ public abstract class ApplicationPart protected ApplicationPart() => throw null; public abstract string Name { get; } } + [System.AttributeUsage((System.AttributeTargets)1, AllowMultiple = true)] public sealed class ApplicationPartAttribute : System.Attribute { public string AssemblyName { get => throw null; } @@ -494,12 +505,14 @@ public class NullApplicationPartFactory : Microsoft.AspNetCore.Mvc.ApplicationPa public NullApplicationPartFactory() => throw null; public override System.Collections.Generic.IEnumerable GetApplicationParts(System.Reflection.Assembly assembly) => throw null; } + [System.AttributeUsage((System.AttributeTargets)1, AllowMultiple = false)] public sealed class ProvideApplicationPartFactoryAttribute : System.Attribute { public ProvideApplicationPartFactoryAttribute(System.Type factoryType) => throw null; public ProvideApplicationPartFactoryAttribute(string factoryTypeName) => throw null; public System.Type GetFactoryType() => throw null; } + [System.AttributeUsage((System.AttributeTargets)1, AllowMultiple = true)] public sealed class RelatedAssemblyAttribute : System.Attribute { public string AssemblyFileName { get => throw null; } @@ -507,6 +520,7 @@ public sealed class RelatedAssemblyAttribute : System.Attribute public static System.Collections.Generic.IReadOnlyList GetRelatedAssemblies(System.Reflection.Assembly assembly, bool throwOnError) => throw null; } } + [System.AttributeUsage((System.AttributeTargets)68, AllowMultiple = false, Inherited = true)] public class AreaAttribute : Microsoft.AspNetCore.Mvc.Routing.RouteValueAttribute { public AreaAttribute(string areaName) : base(default(string), default(string)) => throw null; @@ -541,6 +555,7 @@ public class BadRequestResult : Microsoft.AspNetCore.Mvc.StatusCodeResult { public BadRequestResult() : base(default(int)) => throw null; } + [System.AttributeUsage((System.AttributeTargets)2052, AllowMultiple = false, Inherited = true)] public class BindAttribute : System.Attribute, Microsoft.AspNetCore.Mvc.ModelBinding.IModelNameProvider, Microsoft.AspNetCore.Mvc.ModelBinding.IPropertyFilterProvider { public BindAttribute(params string[] include) => throw null; @@ -549,11 +564,13 @@ public class BindAttribute : System.Attribute, Microsoft.AspNetCore.Mvc.ModelBin public string Prefix { get => throw null; set { } } public System.Func PropertyFilter { get => throw null; } } + [System.AttributeUsage((System.AttributeTargets)4, AllowMultiple = false, Inherited = true)] public class BindPropertiesAttribute : System.Attribute { public BindPropertiesAttribute() => throw null; public bool SupportsGet { get => throw null; set { } } } + [System.AttributeUsage((System.AttributeTargets)128, AllowMultiple = false, Inherited = true)] public class BindPropertyAttribute : System.Attribute, Microsoft.AspNetCore.Mvc.ModelBinding.IBinderTypeProviderMetadata, Microsoft.AspNetCore.Mvc.ModelBinding.IBindingSourceMetadata, Microsoft.AspNetCore.Mvc.ModelBinding.IModelNameProvider, Microsoft.AspNetCore.Mvc.ModelBinding.IRequestPredicateProvider { public System.Type BinderType { get => throw null; set { } } @@ -607,6 +624,7 @@ public class ConflictResult : Microsoft.AspNetCore.Mvc.StatusCodeResult { public ConflictResult() : base(default(int)) => throw null; } + [System.AttributeUsage((System.AttributeTargets)68, AllowMultiple = false, Inherited = true)] public class ConsumesAttribute : System.Attribute, Microsoft.AspNetCore.Http.Metadata.IAcceptsMetadata, Microsoft.AspNetCore.Mvc.ActionConstraints.IActionConstraint, Microsoft.AspNetCore.Mvc.ActionConstraints.IActionConstraintMetadata, Microsoft.AspNetCore.Mvc.ApiExplorer.IApiRequestMetadataProvider, Microsoft.AspNetCore.Mvc.Filters.IFilterMetadata, Microsoft.AspNetCore.Mvc.Filters.IResourceFilter { public bool Accept(Microsoft.AspNetCore.Mvc.ActionConstraints.ActionConstraintContext context) => throw null; @@ -630,6 +648,7 @@ public class ContentResult : Microsoft.AspNetCore.Mvc.ActionResult, Microsoft.As public override System.Threading.Tasks.Task ExecuteResultAsync(Microsoft.AspNetCore.Mvc.ActionContext context) => throw null; public int? StatusCode { get => throw null; set { } } } + [System.AttributeUsage((System.AttributeTargets)4, AllowMultiple = false, Inherited = true)] public class ControllerAttribute : System.Attribute { public ControllerAttribute() => throw null; @@ -817,6 +836,7 @@ public class ControllerContext : Microsoft.AspNetCore.Mvc.ActionContext public ControllerContext(Microsoft.AspNetCore.Mvc.ActionContext context) => throw null; public virtual System.Collections.Generic.IList ValueProviderFactories { get => throw null; set { } } } + [System.AttributeUsage((System.AttributeTargets)128, AllowMultiple = false, Inherited = true)] public class ControllerContextAttribute : System.Attribute { public ControllerContextAttribute() => throw null; @@ -1237,6 +1257,7 @@ public struct Enumerator : System.IDisposable, System.Collections.Generic.IEnume protected abstract System.Collections.Generic.KeyValuePair this[int index] { get; } } } + [System.AttributeUsage((System.AttributeTargets)68, AllowMultiple = false, Inherited = true)] public class DisableRequestSizeLimitAttribute : System.Attribute, Microsoft.AspNetCore.Mvc.Filters.IFilterFactory, Microsoft.AspNetCore.Mvc.Filters.IFilterMetadata, Microsoft.AspNetCore.Mvc.Filters.IOrderedFilter, Microsoft.AspNetCore.Http.Metadata.IRequestSizeLimitMetadata { public Microsoft.AspNetCore.Mvc.Filters.IFilterMetadata CreateInstance(System.IServiceProvider serviceProvider) => throw null; @@ -1275,6 +1296,7 @@ public class FileStreamResult : Microsoft.AspNetCore.Mvc.FileResult } namespace Filters { + [System.AttributeUsage((System.AttributeTargets)68, AllowMultiple = true, Inherited = true)] public abstract class ActionFilterAttribute : System.Attribute, Microsoft.AspNetCore.Mvc.Filters.IActionFilter, Microsoft.AspNetCore.Mvc.Filters.IAsyncActionFilter, Microsoft.AspNetCore.Mvc.Filters.IAsyncResultFilter, Microsoft.AspNetCore.Mvc.Filters.IFilterMetadata, Microsoft.AspNetCore.Mvc.Filters.IOrderedFilter, Microsoft.AspNetCore.Mvc.Filters.IResultFilter { protected ActionFilterAttribute() => throw null; @@ -1286,6 +1308,7 @@ public abstract class ActionFilterAttribute : System.Attribute, Microsoft.AspNet public virtual System.Threading.Tasks.Task OnResultExecutionAsync(Microsoft.AspNetCore.Mvc.Filters.ResultExecutingContext context, Microsoft.AspNetCore.Mvc.Filters.ResultExecutionDelegate next) => throw null; public int Order { get => throw null; set { } } } + [System.AttributeUsage((System.AttributeTargets)68, AllowMultiple = true, Inherited = true)] public abstract class ExceptionFilterAttribute : System.Attribute, Microsoft.AspNetCore.Mvc.Filters.IAsyncExceptionFilter, Microsoft.AspNetCore.Mvc.Filters.IExceptionFilter, Microsoft.AspNetCore.Mvc.Filters.IFilterMetadata, Microsoft.AspNetCore.Mvc.Filters.IOrderedFilter { protected ExceptionFilterAttribute() => throw null; @@ -1313,6 +1336,7 @@ public static class FilterScope public static readonly int Global; public static readonly int Last; } + [System.AttributeUsage((System.AttributeTargets)68, AllowMultiple = true, Inherited = true)] public abstract class ResultFilterAttribute : System.Attribute, Microsoft.AspNetCore.Mvc.Filters.IAsyncResultFilter, Microsoft.AspNetCore.Mvc.Filters.IFilterMetadata, Microsoft.AspNetCore.Mvc.Filters.IOrderedFilter, Microsoft.AspNetCore.Mvc.Filters.IResultFilter { protected ResultFilterAttribute() => throw null; @@ -1334,6 +1358,7 @@ public class ForbidResult : Microsoft.AspNetCore.Mvc.ActionResult public override System.Threading.Tasks.Task ExecuteResultAsync(Microsoft.AspNetCore.Mvc.ActionContext context) => throw null; public Microsoft.AspNetCore.Authentication.AuthenticationProperties Properties { get => throw null; set { } } } + [System.AttributeUsage((System.AttributeTargets)68, AllowMultiple = false, Inherited = true)] public class FormatFilterAttribute : System.Attribute, Microsoft.AspNetCore.Mvc.Filters.IFilterFactory, Microsoft.AspNetCore.Mvc.Filters.IFilterMetadata { public Microsoft.AspNetCore.Mvc.Filters.IFilterMetadata CreateInstance(System.IServiceProvider serviceProvider) => throw null; @@ -1471,6 +1496,7 @@ public abstract class TextOutputFormatter : Microsoft.AspNetCore.Mvc.Formatters. public abstract System.Threading.Tasks.Task WriteResponseBodyAsync(Microsoft.AspNetCore.Mvc.Formatters.OutputFormatterWriteContext context, System.Text.Encoding selectedEncoding); } } + [System.AttributeUsage((System.AttributeTargets)2176, AllowMultiple = false, Inherited = true)] public class FromBodyAttribute : System.Attribute, Microsoft.AspNetCore.Mvc.ModelBinding.IBindingSourceMetadata, Microsoft.AspNetCore.Http.Metadata.IFromBodyMetadata { bool Microsoft.AspNetCore.Http.Metadata.IFromBodyMetadata.AllowEmpty { get => throw null; } @@ -1478,30 +1504,35 @@ public class FromBodyAttribute : System.Attribute, Microsoft.AspNetCore.Mvc.Mode public FromBodyAttribute() => throw null; public Microsoft.AspNetCore.Mvc.ModelBinding.EmptyBodyBehavior EmptyBodyBehavior { get => throw null; set { } } } + [System.AttributeUsage((System.AttributeTargets)2176, AllowMultiple = false, Inherited = true)] public class FromFormAttribute : System.Attribute, Microsoft.AspNetCore.Mvc.ModelBinding.IBindingSourceMetadata, Microsoft.AspNetCore.Http.Metadata.IFromFormMetadata, Microsoft.AspNetCore.Mvc.ModelBinding.IModelNameProvider { public Microsoft.AspNetCore.Mvc.ModelBinding.BindingSource BindingSource { get => throw null; } public FromFormAttribute() => throw null; public string Name { get => throw null; set { } } } + [System.AttributeUsage((System.AttributeTargets)2176, AllowMultiple = false, Inherited = true)] public class FromHeaderAttribute : System.Attribute, Microsoft.AspNetCore.Mvc.ModelBinding.IBindingSourceMetadata, Microsoft.AspNetCore.Http.Metadata.IFromHeaderMetadata, Microsoft.AspNetCore.Mvc.ModelBinding.IModelNameProvider { public Microsoft.AspNetCore.Mvc.ModelBinding.BindingSource BindingSource { get => throw null; } public FromHeaderAttribute() => throw null; public string Name { get => throw null; set { } } } + [System.AttributeUsage((System.AttributeTargets)2176, AllowMultiple = false, Inherited = true)] public class FromQueryAttribute : System.Attribute, Microsoft.AspNetCore.Mvc.ModelBinding.IBindingSourceMetadata, Microsoft.AspNetCore.Http.Metadata.IFromQueryMetadata, Microsoft.AspNetCore.Mvc.ModelBinding.IModelNameProvider { public Microsoft.AspNetCore.Mvc.ModelBinding.BindingSource BindingSource { get => throw null; } public FromQueryAttribute() => throw null; public string Name { get => throw null; set { } } } + [System.AttributeUsage((System.AttributeTargets)2176, AllowMultiple = false, Inherited = true)] public class FromRouteAttribute : System.Attribute, Microsoft.AspNetCore.Mvc.ModelBinding.IBindingSourceMetadata, Microsoft.AspNetCore.Http.Metadata.IFromRouteMetadata, Microsoft.AspNetCore.Mvc.ModelBinding.IModelNameProvider { public Microsoft.AspNetCore.Mvc.ModelBinding.BindingSource BindingSource { get => throw null; } public FromRouteAttribute() => throw null; public string Name { get => throw null; set { } } } + [System.AttributeUsage((System.AttributeTargets)2176, AllowMultiple = false, Inherited = true)] public class FromServicesAttribute : System.Attribute, Microsoft.AspNetCore.Mvc.ModelBinding.IBindingSourceMetadata, Microsoft.AspNetCore.Http.Metadata.IFromServiceMetadata { public Microsoft.AspNetCore.Mvc.ModelBinding.BindingSource BindingSource { get => throw null; } @@ -1565,10 +1596,12 @@ public abstract class ActionDescriptorCollectionProvider : Microsoft.AspNetCore. protected ActionDescriptorCollectionProvider() => throw null; public abstract Microsoft.Extensions.Primitives.IChangeToken GetChangeToken(); } + [System.AttributeUsage((System.AttributeTargets)2176, AllowMultiple = false, Inherited = false)] public sealed class ActionResultObjectValueAttribute : System.Attribute { public ActionResultObjectValueAttribute() => throw null; } + [System.AttributeUsage((System.AttributeTargets)2048, AllowMultiple = false, Inherited = false)] public sealed class ActionResultStatusCodeAttribute : System.Attribute { public ActionResultStatusCodeAttribute() => throw null; @@ -1604,6 +1637,7 @@ public class DefaultOutputFormatterSelector : Microsoft.AspNetCore.Mvc.Infrastru public DefaultOutputFormatterSelector(Microsoft.Extensions.Options.IOptions options, Microsoft.Extensions.Logging.ILoggerFactory loggerFactory) => throw null; public override Microsoft.AspNetCore.Mvc.Formatters.IOutputFormatter SelectFormatter(Microsoft.AspNetCore.Mvc.Formatters.OutputFormatterCanWriteContext context, System.Collections.Generic.IList formatters, Microsoft.AspNetCore.Mvc.Formatters.MediaTypeCollection contentTypes) => throw null; } + [System.AttributeUsage((System.AttributeTargets)68, AllowMultiple = false, Inherited = true)] public sealed class DefaultStatusCodeAttribute : System.Attribute { public DefaultStatusCodeAttribute(int statusCode) => throw null; @@ -1813,6 +1847,7 @@ public class LocalRedirectResult : Microsoft.AspNetCore.Mvc.ActionResult public string Url { get => throw null; set { } } public Microsoft.AspNetCore.Mvc.IUrlHelper UrlHelper { get => throw null; set { } } } + [System.AttributeUsage((System.AttributeTargets)68, AllowMultiple = true, Inherited = true)] public class MiddlewareFilterAttribute : System.Attribute, Microsoft.AspNetCore.Mvc.Filters.IFilterFactory, Microsoft.AspNetCore.Mvc.Filters.IFilterMetadata, Microsoft.AspNetCore.Mvc.Filters.IOrderedFilter { public System.Type ConfigurationType { get => throw null; } @@ -1821,6 +1856,7 @@ public class MiddlewareFilterAttribute : System.Attribute, Microsoft.AspNetCore. public bool IsReusable { get => throw null; } public int Order { get => throw null; set { } } } + [System.AttributeUsage((System.AttributeTargets)2204, AllowMultiple = false, Inherited = true)] public class ModelBinderAttribute : System.Attribute, Microsoft.AspNetCore.Mvc.ModelBinding.IBinderTypeProviderMetadata, Microsoft.AspNetCore.Mvc.ModelBinding.IBindingSourceMetadata, Microsoft.AspNetCore.Mvc.ModelBinding.IModelNameProvider { public System.Type BinderType { get => throw null; set { } } @@ -2065,6 +2101,7 @@ public enum BindingBehavior Never = 1, Required = 2, } + [System.AttributeUsage((System.AttributeTargets)2180, AllowMultiple = false, Inherited = true)] public class BindingBehaviorAttribute : System.Attribute { public Microsoft.AspNetCore.Mvc.ModelBinding.BindingBehavior Behavior { get => throw null; } @@ -2078,10 +2115,12 @@ public abstract class BindingSourceValueProvider : Microsoft.AspNetCore.Mvc.Mode public virtual Microsoft.AspNetCore.Mvc.ModelBinding.IValueProvider Filter(Microsoft.AspNetCore.Mvc.ModelBinding.BindingSource bindingSource) => throw null; public abstract Microsoft.AspNetCore.Mvc.ModelBinding.ValueProviderResult GetValue(string key); } + [System.AttributeUsage((System.AttributeTargets)2180, AllowMultiple = false, Inherited = true)] public sealed class BindNeverAttribute : Microsoft.AspNetCore.Mvc.ModelBinding.BindingBehaviorAttribute { public BindNeverAttribute() : base(default(Microsoft.AspNetCore.Mvc.ModelBinding.BindingBehavior)) => throw null; } + [System.AttributeUsage((System.AttributeTargets)2180, AllowMultiple = false, Inherited = true)] public sealed class BindRequiredAttribute : Microsoft.AspNetCore.Mvc.ModelBinding.BindingBehaviorAttribute { public BindRequiredAttribute() : base(default(Microsoft.AspNetCore.Mvc.ModelBinding.BindingBehavior)) => throw null; @@ -2583,6 +2622,7 @@ public static partial class ModelValidatorProviderExtensions public static void RemoveType(this System.Collections.Generic.IList list) where TModelValidatorProvider : Microsoft.AspNetCore.Mvc.ModelBinding.Validation.IModelValidatorProvider => throw null; public static void RemoveType(this System.Collections.Generic.IList list, System.Type type) => throw null; } + [System.AttributeUsage((System.AttributeTargets)2180, AllowMultiple = false, Inherited = true)] public sealed class ValidateNeverAttribute : System.Attribute, Microsoft.AspNetCore.Mvc.ModelBinding.Validation.IPropertyValidationFilter { public ValidateNeverAttribute() => throw null; @@ -2633,6 +2673,7 @@ public static partial class ValueProviderFactoryExtensions public static void RemoveType(this System.Collections.Generic.IList list, System.Type type) => throw null; } } + [System.AttributeUsage((System.AttributeTargets)4, AllowMultiple = false, Inherited = true)] public class ModelMetadataTypeAttribute : System.Attribute { public ModelMetadataTypeAttribute(System.Type type) => throw null; @@ -2676,14 +2717,17 @@ public class NoContentResult : Microsoft.AspNetCore.Mvc.StatusCodeResult { public NoContentResult() : base(default(int)) => throw null; } + [System.AttributeUsage((System.AttributeTargets)64, AllowMultiple = false, Inherited = true)] public sealed class NonActionAttribute : System.Attribute { public NonActionAttribute() => throw null; } + [System.AttributeUsage((System.AttributeTargets)4, AllowMultiple = false, Inherited = true)] public sealed class NonControllerAttribute : System.Attribute { public NonControllerAttribute() => throw null; } + [System.AttributeUsage((System.AttributeTargets)4, AllowMultiple = false, Inherited = true)] public class NonViewComponentAttribute : System.Attribute { public NonViewComponentAttribute() => throw null; @@ -2722,6 +2766,7 @@ public class PhysicalFileResult : Microsoft.AspNetCore.Mvc.FileResult public override System.Threading.Tasks.Task ExecuteResultAsync(Microsoft.AspNetCore.Mvc.ActionContext context) => throw null; public string FileName { get => throw null; set { } } } + [System.AttributeUsage((System.AttributeTargets)68, AllowMultiple = false, Inherited = true)] public class ProducesAttribute : System.Attribute, Microsoft.AspNetCore.Mvc.ApiExplorer.IApiResponseMetadataProvider, Microsoft.AspNetCore.Mvc.Filters.IFilterMetadata, Microsoft.AspNetCore.Mvc.Filters.IOrderedFilter, Microsoft.AspNetCore.Mvc.Filters.IResultFilter { public Microsoft.AspNetCore.Mvc.Formatters.MediaTypeCollection ContentTypes { get => throw null; set { } } @@ -2734,6 +2779,7 @@ public class ProducesAttribute : System.Attribute, Microsoft.AspNetCore.Mvc.ApiE public int StatusCode { get => throw null; } public System.Type Type { get => throw null; set { } } } + [System.AttributeUsage((System.AttributeTargets)64, AllowMultiple = false, Inherited = true)] public sealed class ProducesDefaultResponseTypeAttribute : System.Attribute, Microsoft.AspNetCore.Mvc.ApiExplorer.IApiDefaultResponseMetadataProvider, Microsoft.AspNetCore.Mvc.ApiExplorer.IApiResponseMetadataProvider, Microsoft.AspNetCore.Mvc.Filters.IFilterMetadata { public ProducesDefaultResponseTypeAttribute() => throw null; @@ -2742,11 +2788,13 @@ public sealed class ProducesDefaultResponseTypeAttribute : System.Attribute, Mic public int StatusCode { get => throw null; } public System.Type Type { get => throw null; } } + [System.AttributeUsage((System.AttributeTargets)69, AllowMultiple = false, Inherited = true)] public sealed class ProducesErrorResponseTypeAttribute : System.Attribute { public ProducesErrorResponseTypeAttribute(System.Type type) => throw null; public System.Type Type { get => throw null; } } + [System.AttributeUsage((System.AttributeTargets)68, AllowMultiple = true, Inherited = true)] public class ProducesResponseTypeAttribute : System.Attribute, Microsoft.AspNetCore.Mvc.ApiExplorer.IApiResponseMetadataProvider, Microsoft.AspNetCore.Mvc.Filters.IFilterMetadata { public ProducesResponseTypeAttribute(int statusCode) => throw null; @@ -2823,6 +2871,7 @@ public class RedirectToRouteResult : Microsoft.AspNetCore.Mvc.ActionResult, Micr public Microsoft.AspNetCore.Routing.RouteValueDictionary RouteValues { get => throw null; set { } } public Microsoft.AspNetCore.Mvc.IUrlHelper UrlHelper { get => throw null; set { } } } + [System.AttributeUsage((System.AttributeTargets)68, AllowMultiple = false, Inherited = true)] public class RequestFormLimitsAttribute : System.Attribute, Microsoft.AspNetCore.Mvc.Filters.IFilterFactory, Microsoft.AspNetCore.Mvc.Filters.IFilterMetadata, Microsoft.AspNetCore.Mvc.Filters.IOrderedFilter { public bool BufferBody { get => throw null; set { } } @@ -2840,6 +2889,7 @@ public class RequestFormLimitsAttribute : System.Attribute, Microsoft.AspNetCore public int ValueCountLimit { get => throw null; set { } } public int ValueLengthLimit { get => throw null; set { } } } + [System.AttributeUsage((System.AttributeTargets)68, AllowMultiple = false, Inherited = true)] public class RequestSizeLimitAttribute : System.Attribute, Microsoft.AspNetCore.Mvc.Filters.IFilterFactory, Microsoft.AspNetCore.Mvc.Filters.IFilterMetadata, Microsoft.AspNetCore.Mvc.Filters.IOrderedFilter, Microsoft.AspNetCore.Http.Metadata.IRequestSizeLimitMetadata { public Microsoft.AspNetCore.Mvc.Filters.IFilterMetadata CreateInstance(System.IServiceProvider serviceProvider) => throw null; @@ -2848,6 +2898,7 @@ public class RequestSizeLimitAttribute : System.Attribute, Microsoft.AspNetCore. long? Microsoft.AspNetCore.Http.Metadata.IRequestSizeLimitMetadata.MaxRequestBodySize { get => throw null; } public int Order { get => throw null; set { } } } + [System.AttributeUsage((System.AttributeTargets)68, Inherited = true, AllowMultiple = false)] public class RequireHttpsAttribute : System.Attribute, Microsoft.AspNetCore.Mvc.Filters.IAuthorizationFilter, Microsoft.AspNetCore.Mvc.Filters.IFilterMetadata, Microsoft.AspNetCore.Mvc.Filters.IOrderedFilter { public RequireHttpsAttribute() => throw null; @@ -2856,6 +2907,7 @@ public class RequireHttpsAttribute : System.Attribute, Microsoft.AspNetCore.Mvc. public int Order { get => throw null; set { } } public bool Permanent { get => throw null; set { } } } + [System.AttributeUsage((System.AttributeTargets)68, AllowMultiple = false, Inherited = true)] public class ResponseCacheAttribute : System.Attribute, Microsoft.AspNetCore.Mvc.Filters.IFilterFactory, Microsoft.AspNetCore.Mvc.Filters.IFilterMetadata, Microsoft.AspNetCore.Mvc.Filters.IOrderedFilter { public string CacheProfileName { get => throw null; set { } } @@ -2876,6 +2928,7 @@ public enum ResponseCacheLocation Client = 1, None = 2, } + [System.AttributeUsage((System.AttributeTargets)68, AllowMultiple = true, Inherited = true)] public class RouteAttribute : System.Attribute, Microsoft.AspNetCore.Mvc.Routing.IRouteTemplateProvider { public RouteAttribute(string template) => throw null; @@ -2893,6 +2946,7 @@ public abstract class DynamicRouteValueTransformer public object State { get => throw null; set { } } public abstract System.Threading.Tasks.ValueTask TransformAsync(Microsoft.AspNetCore.Http.HttpContext httpContext, Microsoft.AspNetCore.Routing.RouteValueDictionary values); } + [System.AttributeUsage((System.AttributeTargets)64, AllowMultiple = true, Inherited = true)] public abstract class HttpMethodAttribute : System.Attribute, Microsoft.AspNetCore.Mvc.Routing.IActionHttpMethodProvider, Microsoft.AspNetCore.Mvc.Routing.IRouteTemplateProvider { public HttpMethodAttribute(System.Collections.Generic.IEnumerable httpMethods) => throw null; @@ -2927,6 +2981,7 @@ public class KnownRouteValueConstraint : Microsoft.AspNetCore.Routing.IParameter public KnownRouteValueConstraint(Microsoft.AspNetCore.Mvc.Infrastructure.IActionDescriptorCollectionProvider actionDescriptorCollectionProvider) => throw null; public bool Match(Microsoft.AspNetCore.Http.HttpContext httpContext, Microsoft.AspNetCore.Routing.IRouter route, string routeKey, Microsoft.AspNetCore.Routing.RouteValueDictionary values, Microsoft.AspNetCore.Routing.RouteDirection routeDirection) => throw null; } + [System.AttributeUsage((System.AttributeTargets)68, AllowMultiple = true, Inherited = true)] public abstract class RouteValueAttribute : System.Attribute, Microsoft.AspNetCore.Mvc.Routing.IRouteValueProvider { protected RouteValueAttribute(string routeKey, string routeValue) => throw null; @@ -2968,6 +3023,7 @@ public sealed class SerializableError : System.Collections.Generic.Dictionary throw null; public SerializableError(Microsoft.AspNetCore.Mvc.ModelBinding.ModelStateDictionary modelState) => throw null; } + [System.AttributeUsage((System.AttributeTargets)68, AllowMultiple = true, Inherited = true)] public class ServiceFilterAttribute : System.Attribute, Microsoft.AspNetCore.Mvc.Filters.IFilterFactory, Microsoft.AspNetCore.Mvc.Filters.IFilterMetadata, Microsoft.AspNetCore.Mvc.Filters.IOrderedFilter { public Microsoft.AspNetCore.Mvc.Filters.IFilterMetadata CreateInstance(System.IServiceProvider serviceProvider) => throw null; @@ -3007,6 +3063,7 @@ public class StatusCodeResult : Microsoft.AspNetCore.Mvc.ActionResult, Microsoft public int StatusCode { get => throw null; } int? Microsoft.AspNetCore.Mvc.Infrastructure.IStatusCodeActionResult.StatusCode { get => throw null; } } + [System.AttributeUsage((System.AttributeTargets)68, AllowMultiple = true, Inherited = true)] public class TypeFilterAttribute : System.Attribute, Microsoft.AspNetCore.Mvc.Filters.IFilterFactory, Microsoft.AspNetCore.Mvc.Filters.IFilterMetadata, Microsoft.AspNetCore.Mvc.Filters.IOrderedFilter { public object[] Arguments { get => throw null; set { } } diff --git a/csharp/ql/test/resources/stubs/_frameworks/Microsoft.AspNetCore.App/Microsoft.AspNetCore.Mvc.DataAnnotations.cs b/csharp/ql/test/resources/stubs/_frameworks/Microsoft.AspNetCore.App/Microsoft.AspNetCore.Mvc.DataAnnotations.cs index 0095fefebbf8..41e0d9290a84 100644 --- a/csharp/ql/test/resources/stubs/_frameworks/Microsoft.AspNetCore.App/Microsoft.AspNetCore.Mvc.DataAnnotations.cs +++ b/csharp/ql/test/resources/stubs/_frameworks/Microsoft.AspNetCore.App/Microsoft.AspNetCore.Mvc.DataAnnotations.cs @@ -53,6 +53,7 @@ public abstract class ValidationProviderAttribute : System.Attribute public abstract System.Collections.Generic.IEnumerable GetValidationAttributes(); } } + [System.AttributeUsage((System.AttributeTargets)132, AllowMultiple = false, Inherited = true)] public sealed class HiddenInputAttribute : System.Attribute { public HiddenInputAttribute() => throw null; diff --git a/csharp/ql/test/resources/stubs/_frameworks/Microsoft.AspNetCore.App/Microsoft.AspNetCore.Mvc.Razor.cs b/csharp/ql/test/resources/stubs/_frameworks/Microsoft.AspNetCore.App/Microsoft.AspNetCore.Mvc.Razor.cs index 6a400b960cc0..87d84d8ed604 100644 --- a/csharp/ql/test/resources/stubs/_frameworks/Microsoft.AspNetCore.App/Microsoft.AspNetCore.Mvc.Razor.cs +++ b/csharp/ql/test/resources/stubs/_frameworks/Microsoft.AspNetCore.App/Microsoft.AspNetCore.Mvc.Razor.cs @@ -79,6 +79,7 @@ public interface IViewCompilerProvider { Microsoft.AspNetCore.Mvc.Razor.Compilation.IViewCompiler GetCompiler(); } + [System.AttributeUsage((System.AttributeTargets)1, AllowMultiple = true)] public class RazorViewAttribute : System.Attribute { public RazorViewAttribute(string path, System.Type viewType) => throw null; @@ -107,6 +108,7 @@ public sealed class TagHelperMemoryCacheProvider } namespace Internal { + [System.AttributeUsage((System.AttributeTargets)128, AllowMultiple = false, Inherited = true)] public class RazorInjectAttribute : System.Attribute { public RazorInjectAttribute() => throw null; diff --git a/csharp/ql/test/resources/stubs/_frameworks/Microsoft.AspNetCore.App/Microsoft.AspNetCore.Mvc.RazorPages.cs b/csharp/ql/test/resources/stubs/_frameworks/Microsoft.AspNetCore.App/Microsoft.AspNetCore.Mvc.RazorPages.cs index cde917a0ddeb..7cc84bb8b970 100644 --- a/csharp/ql/test/resources/stubs/_frameworks/Microsoft.AspNetCore.App/Microsoft.AspNetCore.Mvc.RazorPages.cs +++ b/csharp/ql/test/resources/stubs/_frameworks/Microsoft.AspNetCore.App/Microsoft.AspNetCore.Mvc.RazorPages.cs @@ -400,6 +400,7 @@ public abstract class PageLoader : Microsoft.AspNetCore.Mvc.RazorPages.Infrastru public abstract System.Threading.Tasks.Task LoadAsync(Microsoft.AspNetCore.Mvc.RazorPages.PageActionDescriptor actionDescriptor); public virtual System.Threading.Tasks.Task LoadAsync(Microsoft.AspNetCore.Mvc.RazorPages.PageActionDescriptor actionDescriptor, Microsoft.AspNetCore.Http.EndpointMetadataCollection endpointMetadata) => throw null; } + [System.AttributeUsage((System.AttributeTargets)4, AllowMultiple = false, Inherited = true)] public class PageModelAttribute : System.Attribute { public PageModelAttribute() => throw null; @@ -464,6 +465,7 @@ public interface IPageModelFactoryProvider System.Action CreateModelDisposer(Microsoft.AspNetCore.Mvc.RazorPages.CompiledPageActionDescriptor descriptor); System.Func CreateModelFactory(Microsoft.AspNetCore.Mvc.RazorPages.CompiledPageActionDescriptor descriptor); } + [System.AttributeUsage((System.AttributeTargets)64, AllowMultiple = false, Inherited = true)] public class NonHandlerAttribute : System.Attribute { public NonHandlerAttribute() => throw null; @@ -604,6 +606,7 @@ public class PageContext : Microsoft.AspNetCore.Mvc.ActionContext public virtual Microsoft.AspNetCore.Mvc.ViewFeatures.ViewDataDictionary ViewData { get => throw null; set { } } public virtual System.Collections.Generic.IList> ViewStartFactories { get => throw null; set { } } } + [System.AttributeUsage((System.AttributeTargets)128, AllowMultiple = false, Inherited = true)] public class PageContextAttribute : System.Attribute { public PageContextAttribute() => throw null; diff --git a/csharp/ql/test/resources/stubs/_frameworks/Microsoft.AspNetCore.App/Microsoft.AspNetCore.Mvc.ViewFeatures.cs b/csharp/ql/test/resources/stubs/_frameworks/Microsoft.AspNetCore.App/Microsoft.AspNetCore.Mvc.ViewFeatures.cs index 64af1faa7eb7..4303910db3ac 100644 --- a/csharp/ql/test/resources/stubs/_frameworks/Microsoft.AspNetCore.App/Microsoft.AspNetCore.Mvc.ViewFeatures.cs +++ b/csharp/ql/test/resources/stubs/_frameworks/Microsoft.AspNetCore.App/Microsoft.AspNetCore.Mvc.ViewFeatures.cs @@ -6,6 +6,7 @@ namespace AspNetCore { namespace Mvc { + [System.AttributeUsage((System.AttributeTargets)68, AllowMultiple = false, Inherited = true)] public class AutoValidateAntiforgeryTokenAttribute : System.Attribute, Microsoft.AspNetCore.Mvc.Filters.IFilterFactory, Microsoft.AspNetCore.Mvc.Filters.IFilterMetadata, Microsoft.AspNetCore.Mvc.Filters.IOrderedFilter { public Microsoft.AspNetCore.Mvc.Filters.IFilterMetadata CreateInstance(System.IServiceProvider serviceProvider) => throw null; @@ -130,6 +131,7 @@ public sealed class ViewNotFoundEventData : Microsoft.AspNetCore.Mvc.Diagnostics public string ViewName { get => throw null; } } } + [System.AttributeUsage((System.AttributeTargets)68, AllowMultiple = false, Inherited = true)] public class IgnoreAntiforgeryTokenAttribute : System.Attribute, Microsoft.AspNetCore.Mvc.ViewFeatures.IAntiforgeryPolicy, Microsoft.AspNetCore.Mvc.Filters.IFilterMetadata, Microsoft.AspNetCore.Mvc.Filters.IOrderedFilter { public IgnoreAntiforgeryTokenAttribute() => throw null; @@ -165,6 +167,7 @@ public class MvcViewOptions : System.Collections.Generic.IEnumerable throw null; set { } } public System.Collections.Generic.IList ViewEngines { get => throw null; } } + [System.AttributeUsage((System.AttributeTargets)128, AllowMultiple = false, Inherited = true)] public class PageRemoteAttribute : Microsoft.AspNetCore.Mvc.RemoteAttributeBase { public PageRemoteAttribute() => throw null; @@ -184,6 +187,7 @@ public class PartialViewResult : Microsoft.AspNetCore.Mvc.ActionResult, Microsof public Microsoft.AspNetCore.Mvc.ViewEngines.IViewEngine ViewEngine { get => throw null; set { } } public string ViewName { get => throw null; set { } } } + [System.AttributeUsage((System.AttributeTargets)128, AllowMultiple = false, Inherited = true)] public class RemoteAttribute : Microsoft.AspNetCore.Mvc.RemoteAttributeBase { protected RemoteAttribute() => throw null; @@ -193,6 +197,7 @@ public class RemoteAttribute : Microsoft.AspNetCore.Mvc.RemoteAttributeBase protected override string GetUrl(Microsoft.AspNetCore.Mvc.ModelBinding.Validation.ClientModelValidationContext context) => throw null; protected string RouteName { get => throw null; set { } } } + [System.AttributeUsage((System.AttributeTargets)128, AllowMultiple = false, Inherited = true)] public abstract class RemoteAttributeBase : System.ComponentModel.DataAnnotations.ValidationAttribute, Microsoft.AspNetCore.Mvc.ModelBinding.Validation.IClientModelValidator { public string AdditionalFields { get => throw null; set { } } @@ -608,17 +613,20 @@ public class ViewContext : Microsoft.AspNetCore.Mvc.ActionContext public System.IO.TextWriter Writer { get => throw null; set { } } } } + [System.AttributeUsage((System.AttributeTargets)68, AllowMultiple = false, Inherited = true)] public class SkipStatusCodePagesAttribute : System.Attribute, Microsoft.AspNetCore.Mvc.Filters.IFilterMetadata, Microsoft.AspNetCore.Mvc.Filters.IResourceFilter, Microsoft.AspNetCore.Http.Metadata.ISkipStatusCodePagesMetadata { public SkipStatusCodePagesAttribute() => throw null; public void OnResourceExecuted(Microsoft.AspNetCore.Mvc.Filters.ResourceExecutedContext context) => throw null; public void OnResourceExecuting(Microsoft.AspNetCore.Mvc.Filters.ResourceExecutingContext context) => throw null; } + [System.AttributeUsage((System.AttributeTargets)128, Inherited = true, AllowMultiple = false)] public sealed class TempDataAttribute : System.Attribute { public TempDataAttribute() => throw null; public string Key { get => throw null; set { } } } + [System.AttributeUsage((System.AttributeTargets)68, AllowMultiple = false, Inherited = true)] public class ValidateAntiForgeryTokenAttribute : System.Attribute, Microsoft.AspNetCore.Mvc.Filters.IFilterFactory, Microsoft.AspNetCore.Mvc.Filters.IFilterMetadata, Microsoft.AspNetCore.Mvc.Filters.IOrderedFilter { public Microsoft.AspNetCore.Mvc.Filters.IFilterMetadata CreateInstance(System.IServiceProvider serviceProvider) => throw null; @@ -648,6 +656,7 @@ public abstract class ViewComponent public Microsoft.AspNetCore.Mvc.ViewFeatures.ViewDataDictionary ViewData { get => throw null; } public Microsoft.AspNetCore.Mvc.ViewEngines.ICompositeViewEngine ViewEngine { get => throw null; set { } } } + [System.AttributeUsage((System.AttributeTargets)4, AllowMultiple = false, Inherited = true)] public class ViewComponentAttribute : System.Attribute { public ViewComponentAttribute() => throw null; @@ -762,6 +771,7 @@ public class ViewComponentContext public Microsoft.AspNetCore.Mvc.ViewFeatures.ViewDataDictionary ViewData { get => throw null; } public System.IO.TextWriter Writer { get => throw null; } } + [System.AttributeUsage((System.AttributeTargets)128, AllowMultiple = false, Inherited = true)] public class ViewComponentContextAttribute : System.Attribute { public ViewComponentContextAttribute() => throw null; @@ -811,6 +821,7 @@ public class ViewViewComponentResult : Microsoft.AspNetCore.Mvc.IViewComponentRe public string ViewName { get => throw null; set { } } } } + [System.AttributeUsage((System.AttributeTargets)128, Inherited = true, AllowMultiple = false)] public sealed class ViewDataAttribute : System.Attribute { public ViewDataAttribute() => throw null; @@ -1212,6 +1223,7 @@ public class PartialViewResultExecutor : Microsoft.AspNetCore.Mvc.ViewFeatures.V public virtual Microsoft.AspNetCore.Mvc.ViewEngines.ViewEngineResult FindView(Microsoft.AspNetCore.Mvc.ActionContext actionContext, Microsoft.AspNetCore.Mvc.PartialViewResult viewResult) => throw null; protected Microsoft.Extensions.Logging.ILogger Logger { get => throw null; } } + [System.AttributeUsage((System.AttributeTargets)68, AllowMultiple = false, Inherited = true)] public class SaveTempDataAttribute : System.Attribute, Microsoft.AspNetCore.Mvc.Filters.IFilterFactory, Microsoft.AspNetCore.Mvc.Filters.IFilterMetadata, Microsoft.AspNetCore.Mvc.Filters.IOrderedFilter { public Microsoft.AspNetCore.Mvc.Filters.IFilterMetadata CreateInstance(System.IServiceProvider serviceProvider) => throw null; @@ -1288,6 +1300,7 @@ public class ViewComponentResultExecutor : Microsoft.AspNetCore.Mvc.Infrastructu public ViewComponentResultExecutor(Microsoft.Extensions.Options.IOptions mvcHelperOptions, Microsoft.Extensions.Logging.ILoggerFactory loggerFactory, System.Text.Encodings.Web.HtmlEncoder htmlEncoder, Microsoft.AspNetCore.Mvc.ModelBinding.IModelMetadataProvider modelMetadataProvider, Microsoft.AspNetCore.Mvc.ViewFeatures.ITempDataDictionaryFactory tempDataDictionaryFactory, Microsoft.AspNetCore.Mvc.Infrastructure.IHttpResponseStreamWriterFactory writerFactory) => throw null; public virtual System.Threading.Tasks.Task ExecuteAsync(Microsoft.AspNetCore.Mvc.ActionContext context, Microsoft.AspNetCore.Mvc.ViewComponentResult result) => throw null; } + [System.AttributeUsage((System.AttributeTargets)128, AllowMultiple = false, Inherited = true)] public class ViewContextAttribute : System.Attribute { public ViewContextAttribute() => throw null; @@ -1334,6 +1347,7 @@ public class ViewDataDictionary : Microsoft.AspNetCore.Mvc.ViewFeatures. public ViewDataDictionary(Microsoft.AspNetCore.Mvc.ViewFeatures.ViewDataDictionary source, object model) : base(default(Microsoft.AspNetCore.Mvc.ViewFeatures.ViewDataDictionary)) => throw null; public TModel Model { get => throw null; set { } } } + [System.AttributeUsage((System.AttributeTargets)128, AllowMultiple = false, Inherited = true)] public class ViewDataDictionaryAttribute : System.Attribute { public ViewDataDictionaryAttribute() => throw null; diff --git a/csharp/ql/test/resources/stubs/_frameworks/Microsoft.AspNetCore.App/Microsoft.AspNetCore.OutputCaching.cs b/csharp/ql/test/resources/stubs/_frameworks/Microsoft.AspNetCore.App/Microsoft.AspNetCore.OutputCaching.cs index 0ad5295bbef6..d0928b92469f 100644 --- a/csharp/ql/test/resources/stubs/_frameworks/Microsoft.AspNetCore.App/Microsoft.AspNetCore.OutputCaching.cs +++ b/csharp/ql/test/resources/stubs/_frameworks/Microsoft.AspNetCore.App/Microsoft.AspNetCore.OutputCaching.cs @@ -39,6 +39,7 @@ public interface IOutputCacheStore System.Threading.Tasks.ValueTask GetAsync(string key, System.Threading.CancellationToken cancellationToken); System.Threading.Tasks.ValueTask SetAsync(string key, byte[] value, string[] tags, System.TimeSpan validFor, System.Threading.CancellationToken cancellationToken); } + [System.AttributeUsage((System.AttributeTargets)68, AllowMultiple = false, Inherited = true)] public sealed class OutputCacheAttribute : System.Attribute { public OutputCacheAttribute() => throw null; diff --git a/csharp/ql/test/resources/stubs/_frameworks/Microsoft.AspNetCore.App/Microsoft.AspNetCore.RateLimiting.cs b/csharp/ql/test/resources/stubs/_frameworks/Microsoft.AspNetCore.App/Microsoft.AspNetCore.RateLimiting.cs index 6fa8fb2c1156..f12f92bec5a5 100644 --- a/csharp/ql/test/resources/stubs/_frameworks/Microsoft.AspNetCore.App/Microsoft.AspNetCore.RateLimiting.cs +++ b/csharp/ql/test/resources/stubs/_frameworks/Microsoft.AspNetCore.App/Microsoft.AspNetCore.RateLimiting.cs @@ -24,10 +24,12 @@ public static partial class RateLimiterServiceCollectionExtensions } namespace RateLimiting { + [System.AttributeUsage((System.AttributeTargets)68, AllowMultiple = false, Inherited = true)] public sealed class DisableRateLimitingAttribute : System.Attribute { public DisableRateLimitingAttribute() => throw null; } + [System.AttributeUsage((System.AttributeTargets)68, AllowMultiple = false, Inherited = true)] public sealed class EnableRateLimitingAttribute : System.Attribute { public EnableRateLimitingAttribute(string policyName) => throw null; diff --git a/csharp/ql/test/resources/stubs/_frameworks/Microsoft.AspNetCore.App/Microsoft.AspNetCore.Razor.Runtime.cs b/csharp/ql/test/resources/stubs/_frameworks/Microsoft.AspNetCore.App/Microsoft.AspNetCore.Razor.Runtime.cs index 58ade22f1eb5..fcb7e1de4f1e 100644 --- a/csharp/ql/test/resources/stubs/_frameworks/Microsoft.AspNetCore.App/Microsoft.AspNetCore.Razor.Runtime.cs +++ b/csharp/ql/test/resources/stubs/_frameworks/Microsoft.AspNetCore.App/Microsoft.AspNetCore.Razor.Runtime.cs @@ -22,6 +22,7 @@ public abstract class RazorCompiledItem public abstract System.Collections.Generic.IReadOnlyList Metadata { get; } public abstract System.Type Type { get; } } + [System.AttributeUsage((System.AttributeTargets)5, AllowMultiple = true, Inherited = false)] public sealed class RazorCompiledItemAttribute : System.Attribute { public RazorCompiledItemAttribute(System.Type type, string kind, string identifier) => throw null; @@ -40,28 +41,33 @@ public class RazorCompiledItemLoader protected System.Collections.Generic.IEnumerable LoadAttributes(System.Reflection.Assembly assembly) => throw null; public virtual System.Collections.Generic.IReadOnlyList LoadItems(System.Reflection.Assembly assembly) => throw null; } + [System.AttributeUsage((System.AttributeTargets)4, AllowMultiple = true, Inherited = true)] public sealed class RazorCompiledItemMetadataAttribute : System.Attribute { public RazorCompiledItemMetadataAttribute(string key, string value) => throw null; public string Key { get => throw null; } public string Value { get => throw null; } } + [System.AttributeUsage((System.AttributeTargets)1, AllowMultiple = false, Inherited = false)] public sealed class RazorConfigurationNameAttribute : System.Attribute { public string ConfigurationName { get => throw null; } public RazorConfigurationNameAttribute(string configurationName) => throw null; } + [System.AttributeUsage((System.AttributeTargets)1, AllowMultiple = true, Inherited = false)] public sealed class RazorExtensionAssemblyNameAttribute : System.Attribute { public string AssemblyName { get => throw null; } public RazorExtensionAssemblyNameAttribute(string extensionName, string assemblyName) => throw null; public string ExtensionName { get => throw null; } } + [System.AttributeUsage((System.AttributeTargets)1, AllowMultiple = false, Inherited = false)] public sealed class RazorLanguageVersionAttribute : System.Attribute { public RazorLanguageVersionAttribute(string languageVersion) => throw null; public string LanguageVersion { get => throw null; } } + [System.AttributeUsage((System.AttributeTargets)4, AllowMultiple = true, Inherited = true)] public sealed class RazorSourceChecksumAttribute : System.Attribute, Microsoft.AspNetCore.Razor.Hosting.IRazorSourceChecksumMetadata { public string Checksum { get => throw null; } diff --git a/csharp/ql/test/resources/stubs/_frameworks/Microsoft.AspNetCore.App/Microsoft.AspNetCore.Razor.cs b/csharp/ql/test/resources/stubs/_frameworks/Microsoft.AspNetCore.App/Microsoft.AspNetCore.Razor.cs index 1765573540a3..0629742d0105 100644 --- a/csharp/ql/test/resources/stubs/_frameworks/Microsoft.AspNetCore.App/Microsoft.AspNetCore.Razor.cs +++ b/csharp/ql/test/resources/stubs/_frameworks/Microsoft.AspNetCore.App/Microsoft.AspNetCore.Razor.cs @@ -24,6 +24,7 @@ public class DefaultTagHelperContent : Microsoft.AspNetCore.Razor.TagHelpers.Tag public override void Reinitialize() => throw null; public override void WriteTo(System.IO.TextWriter writer, System.Text.Encodings.Web.HtmlEncoder encoder) => throw null; } + [System.AttributeUsage((System.AttributeTargets)128, AllowMultiple = false, Inherited = false)] public sealed class HtmlAttributeNameAttribute : System.Attribute { public HtmlAttributeNameAttribute() => throw null; @@ -32,6 +33,7 @@ public sealed class HtmlAttributeNameAttribute : System.Attribute public bool DictionaryAttributePrefixSet { get => throw null; } public string Name { get => throw null; } } + [System.AttributeUsage((System.AttributeTargets)128, AllowMultiple = false, Inherited = false)] public sealed class HtmlAttributeNotBoundAttribute : System.Attribute { public HtmlAttributeNotBoundAttribute() => throw null; @@ -43,6 +45,7 @@ public enum HtmlAttributeValueStyle NoQuotes = 2, Minimized = 3, } + [System.AttributeUsage((System.AttributeTargets)4, AllowMultiple = true, Inherited = false)] public sealed class HtmlTargetElementAttribute : System.Attribute { public string Attributes { get => throw null; set { } } @@ -73,6 +76,7 @@ public sealed class NullHtmlEncoder : System.Text.Encodings.Web.HtmlEncoder public override unsafe bool TryEncodeUnicodeScalar(int unicodeScalar, char* buffer, int bufferLength, out int numberOfCharactersWritten) => throw null; public override bool WillEncode(int unicodeScalar) => throw null; } + [System.AttributeUsage((System.AttributeTargets)4, AllowMultiple = false, Inherited = false)] public sealed class OutputElementHintAttribute : System.Attribute { public OutputElementHintAttribute(string outputElement) => throw null; @@ -89,6 +93,7 @@ public abstract class ReadOnlyTagHelperAttributeList : System.Collections.Object public bool TryGetAttribute(string name, out Microsoft.AspNetCore.Razor.TagHelpers.TagHelperAttribute attribute) => throw null; public bool TryGetAttributes(string name, out System.Collections.Generic.IReadOnlyList attributes) => throw null; } + [System.AttributeUsage((System.AttributeTargets)4, Inherited = false, AllowMultiple = false)] public sealed class RestrictChildrenAttribute : System.Attribute { public System.Collections.Generic.IEnumerable ChildTags { get => throw null; } diff --git a/csharp/ql/test/resources/stubs/_frameworks/Microsoft.AspNetCore.App/Microsoft.AspNetCore.Routing.cs b/csharp/ql/test/resources/stubs/_frameworks/Microsoft.AspNetCore.App/Microsoft.AspNetCore.Routing.cs index 9e3cda66696e..c3508dbbf217 100644 --- a/csharp/ql/test/resources/stubs/_frameworks/Microsoft.AspNetCore.App/Microsoft.AspNetCore.Routing.cs +++ b/csharp/ql/test/resources/stubs/_frameworks/Microsoft.AspNetCore.App/Microsoft.AspNetCore.Routing.cs @@ -291,11 +291,13 @@ public abstract class EndpointDataSource public abstract Microsoft.Extensions.Primitives.IChangeToken GetChangeToken(); public virtual System.Collections.Generic.IReadOnlyList GetGroupedEndpoints(Microsoft.AspNetCore.Routing.RouteGroupContext context) => throw null; } + [System.AttributeUsage((System.AttributeTargets)4164, Inherited = false, AllowMultiple = false)] public sealed class EndpointGroupNameAttribute : System.Attribute, Microsoft.AspNetCore.Routing.IEndpointGroupNameMetadata { public EndpointGroupNameAttribute(string endpointGroupName) => throw null; public string EndpointGroupName { get => throw null; } } + [System.AttributeUsage((System.AttributeTargets)4160, Inherited = false, AllowMultiple = false)] public sealed class EndpointNameAttribute : System.Attribute, Microsoft.AspNetCore.Routing.IEndpointNameMetadata { public EndpointNameAttribute(string endpointName) => throw null; @@ -306,11 +308,13 @@ public class EndpointNameMetadata : Microsoft.AspNetCore.Routing.IEndpointNameMe public EndpointNameMetadata(string endpointName) => throw null; public string EndpointName { get => throw null; } } + [System.AttributeUsage((System.AttributeTargets)4164, AllowMultiple = false, Inherited = true)] public sealed class ExcludeFromDescriptionAttribute : System.Attribute, Microsoft.AspNetCore.Routing.IExcludeFromDescriptionMetadata { public ExcludeFromDescriptionAttribute() => throw null; public bool ExcludeFromDescription { get => throw null; } } + [System.AttributeUsage((System.AttributeTargets)68, AllowMultiple = false, Inherited = false)] public sealed class HostAttribute : System.Attribute, Microsoft.AspNetCore.Routing.IHostMetadata { public HostAttribute(string host) => throw null; diff --git a/csharp/ql/test/resources/stubs/_frameworks/Microsoft.AspNetCore.App/Microsoft.AspNetCore.SignalR.Core.cs b/csharp/ql/test/resources/stubs/_frameworks/Microsoft.AspNetCore.App/Microsoft.AspNetCore.SignalR.Core.cs index 0691c592da0d..c3d969fc67e6 100644 --- a/csharp/ql/test/resources/stubs/_frameworks/Microsoft.AspNetCore.App/Microsoft.AspNetCore.SignalR.Core.cs +++ b/csharp/ql/test/resources/stubs/_frameworks/Microsoft.AspNetCore.App/Microsoft.AspNetCore.SignalR.Core.cs @@ -240,6 +240,7 @@ public class HubMetadata public HubMetadata(System.Type hubType) => throw null; public System.Type HubType { get => throw null; } } + [System.AttributeUsage((System.AttributeTargets)64, AllowMultiple = false, Inherited = true)] public class HubMethodNameAttribute : System.Attribute { public HubMethodNameAttribute(string name) => throw null; diff --git a/csharp/ql/test/resources/stubs/_frameworks/Microsoft.AspNetCore.App/Microsoft.Extensions.Configuration.Abstractions.cs b/csharp/ql/test/resources/stubs/_frameworks/Microsoft.AspNetCore.App/Microsoft.Extensions.Configuration.Abstractions.cs index 02189892cd27..c3f84b43f886 100644 --- a/csharp/ql/test/resources/stubs/_frameworks/Microsoft.AspNetCore.App/Microsoft.Extensions.Configuration.Abstractions.cs +++ b/csharp/ql/test/resources/stubs/_frameworks/Microsoft.AspNetCore.App/Microsoft.Extensions.Configuration.Abstractions.cs @@ -23,6 +23,7 @@ public static partial class ConfigurationExtensions public static string GetConnectionString(this Microsoft.Extensions.Configuration.IConfiguration configuration, string name) => throw null; public static Microsoft.Extensions.Configuration.IConfigurationSection GetRequiredSection(this Microsoft.Extensions.Configuration.IConfiguration configuration, string key) => throw null; } + [System.AttributeUsage((System.AttributeTargets)128)] public sealed class ConfigurationKeyNameAttribute : System.Attribute { public ConfigurationKeyNameAttribute(string name) => throw null; diff --git a/csharp/ql/test/resources/stubs/_frameworks/Microsoft.AspNetCore.App/Microsoft.Extensions.Configuration.UserSecrets.cs b/csharp/ql/test/resources/stubs/_frameworks/Microsoft.AspNetCore.App/Microsoft.Extensions.Configuration.UserSecrets.cs index 6dca2bc59e37..6c89808ea0d9 100644 --- a/csharp/ql/test/resources/stubs/_frameworks/Microsoft.AspNetCore.App/Microsoft.Extensions.Configuration.UserSecrets.cs +++ b/csharp/ql/test/resources/stubs/_frameworks/Microsoft.AspNetCore.App/Microsoft.Extensions.Configuration.UserSecrets.cs @@ -13,6 +13,7 @@ public class PathHelper public PathHelper() => throw null; public static string GetSecretsPathFromSecretsId(string userSecretsId) => throw null; } + [System.AttributeUsage((System.AttributeTargets)1, Inherited = false, AllowMultiple = false)] public class UserSecretsIdAttribute : System.Attribute { public UserSecretsIdAttribute(string userSecretId) => throw null; diff --git a/csharp/ql/test/resources/stubs/_frameworks/Microsoft.AspNetCore.App/Microsoft.Extensions.DependencyInjection.Abstractions.cs b/csharp/ql/test/resources/stubs/_frameworks/Microsoft.AspNetCore.App/Microsoft.Extensions.DependencyInjection.Abstractions.cs index 64878c372698..0a7ff9a9534e 100644 --- a/csharp/ql/test/resources/stubs/_frameworks/Microsoft.AspNetCore.App/Microsoft.Extensions.DependencyInjection.Abstractions.cs +++ b/csharp/ql/test/resources/stubs/_frameworks/Microsoft.AspNetCore.App/Microsoft.Extensions.DependencyInjection.Abstractions.cs @@ -14,6 +14,7 @@ public static class ActivatorUtilities public static object GetServiceOrCreateInstance(System.IServiceProvider provider, System.Type type) => throw null; public static T GetServiceOrCreateInstance(System.IServiceProvider provider) => throw null; } + [System.AttributeUsage((System.AttributeTargets)32767)] public class ActivatorUtilitiesConstructorAttribute : System.Attribute { public ActivatorUtilitiesConstructorAttribute() => throw null; diff --git a/csharp/ql/test/resources/stubs/_frameworks/Microsoft.AspNetCore.App/Microsoft.Extensions.Identity.Core.cs b/csharp/ql/test/resources/stubs/_frameworks/Microsoft.AspNetCore.App/Microsoft.Extensions.Identity.Core.cs index 4edd2e5e8c57..5bcf000eceaa 100644 --- a/csharp/ql/test/resources/stubs/_frameworks/Microsoft.AspNetCore.App/Microsoft.Extensions.Identity.Core.cs +++ b/csharp/ql/test/resources/stubs/_frameworks/Microsoft.AspNetCore.App/Microsoft.Extensions.Identity.Core.cs @@ -341,6 +341,7 @@ public enum PasswordVerificationResult Success = 1, SuccessRehashNeeded = 2, } + [System.AttributeUsage((System.AttributeTargets)128)] public class PersonalDataAttribute : System.Attribute { public PersonalDataAttribute() => throw null; diff --git a/csharp/ql/test/resources/stubs/_frameworks/Microsoft.AspNetCore.App/Microsoft.Extensions.Localization.cs b/csharp/ql/test/resources/stubs/_frameworks/Microsoft.AspNetCore.App/Microsoft.Extensions.Localization.cs index 99932b86e13b..95d2f0b7b596 100644 --- a/csharp/ql/test/resources/stubs/_frameworks/Microsoft.AspNetCore.App/Microsoft.Extensions.Localization.cs +++ b/csharp/ql/test/resources/stubs/_frameworks/Microsoft.AspNetCore.App/Microsoft.Extensions.Localization.cs @@ -23,6 +23,7 @@ public class LocalizationOptions public LocalizationOptions() => throw null; public string ResourcesPath { get => throw null; set { } } } + [System.AttributeUsage((System.AttributeTargets)1, AllowMultiple = false, Inherited = false)] public class ResourceLocationAttribute : System.Attribute { public ResourceLocationAttribute(string resourceLocation) => throw null; @@ -55,6 +56,7 @@ public class ResourceNamesCache : Microsoft.Extensions.Localization.IResourceNam public ResourceNamesCache() => throw null; public System.Collections.Generic.IList GetOrAdd(string name, System.Func> valueFactory) => throw null; } + [System.AttributeUsage((System.AttributeTargets)1, AllowMultiple = false, Inherited = false)] public class RootNamespaceAttribute : System.Attribute { public RootNamespaceAttribute(string rootNamespace) => throw null; diff --git a/csharp/ql/test/resources/stubs/_frameworks/Microsoft.AspNetCore.App/Microsoft.Extensions.Logging.Abstractions.cs b/csharp/ql/test/resources/stubs/_frameworks/Microsoft.AspNetCore.App/Microsoft.Extensions.Logging.Abstractions.cs index 0436b1d8d7e0..d71f41ff5c3f 100644 --- a/csharp/ql/test/resources/stubs/_frameworks/Microsoft.AspNetCore.App/Microsoft.Extensions.Logging.Abstractions.cs +++ b/csharp/ql/test/resources/stubs/_frameworks/Microsoft.AspNetCore.App/Microsoft.Extensions.Logging.Abstractions.cs @@ -167,6 +167,7 @@ public static class LoggerMessage public static System.Func DefineScope(string formatString) => throw null; public static System.Func DefineScope(string formatString) => throw null; } + [System.AttributeUsage((System.AttributeTargets)64)] public sealed class LoggerMessageAttribute : System.Attribute { public LoggerMessageAttribute() => throw null; diff --git a/csharp/ql/test/resources/stubs/_frameworks/Microsoft.AspNetCore.App/Microsoft.Extensions.Logging.cs b/csharp/ql/test/resources/stubs/_frameworks/Microsoft.AspNetCore.App/Microsoft.Extensions.Logging.cs index f3bb0065fe13..9250f1e5fc4b 100644 --- a/csharp/ql/test/resources/stubs/_frameworks/Microsoft.AspNetCore.App/Microsoft.Extensions.Logging.cs +++ b/csharp/ql/test/resources/stubs/_frameworks/Microsoft.AspNetCore.App/Microsoft.Extensions.Logging.cs @@ -93,6 +93,7 @@ public static partial class LoggingBuilderExtensions public static Microsoft.Extensions.Logging.ILoggingBuilder Configure(this Microsoft.Extensions.Logging.ILoggingBuilder builder, System.Action action) => throw null; public static Microsoft.Extensions.Logging.ILoggingBuilder SetMinimumLevel(this Microsoft.Extensions.Logging.ILoggingBuilder builder, Microsoft.Extensions.Logging.LogLevel level) => throw null; } + [System.AttributeUsage((System.AttributeTargets)4, AllowMultiple = false, Inherited = false)] public class ProviderAliasAttribute : System.Attribute { public string Alias { get => throw null; } diff --git a/csharp/ql/test/resources/stubs/_frameworks/Microsoft.AspNetCore.App/Microsoft.JSInterop.cs b/csharp/ql/test/resources/stubs/_frameworks/Microsoft.AspNetCore.App/Microsoft.JSInterop.cs index da3135522512..01954004a7ef 100644 --- a/csharp/ql/test/resources/stubs/_frameworks/Microsoft.AspNetCore.App/Microsoft.JSInterop.cs +++ b/csharp/ql/test/resources/stubs/_frameworks/Microsoft.AspNetCore.App/Microsoft.JSInterop.cs @@ -145,6 +145,7 @@ public static partial class JSInProcessRuntimeExtensions { public static void InvokeVoid(this Microsoft.JSInterop.IJSInProcessRuntime jsRuntime, string identifier, params object[] args) => throw null; } + [System.AttributeUsage((System.AttributeTargets)64, AllowMultiple = true)] public sealed class JSInvokableAttribute : System.Attribute { public JSInvokableAttribute() => throw null; diff --git a/csharp/ql/test/resources/stubs/_frameworks/Microsoft.NETCore.App/Microsoft.VisualBasic.Core.cs b/csharp/ql/test/resources/stubs/_frameworks/Microsoft.NETCore.App/Microsoft.VisualBasic.Core.cs index 862067e580e6..d3630da337fd 100644 --- a/csharp/ql/test/resources/stubs/_frameworks/Microsoft.NETCore.App/Microsoft.VisualBasic.Core.cs +++ b/csharp/ql/test/resources/stubs/_frameworks/Microsoft.NETCore.App/Microsoft.VisualBasic.Core.cs @@ -49,6 +49,7 @@ public sealed class Collection : System.Collections.ICollection, System.Collecti public object this[object Index] { get => throw null; } public object this[string Key] { get => throw null; } } + [System.AttributeUsage((System.AttributeTargets)4, Inherited = false, AllowMultiple = false)] public sealed class ComClassAttribute : System.Attribute { public string ClassID { get => throw null; } @@ -158,6 +159,7 @@ public sealed class DecimalType public static decimal FromString(string Value, System.Globalization.NumberFormatInfo NumberFormat) => throw null; public static decimal Parse(string Value, System.Globalization.NumberFormatInfo NumberFormat) => throw null; } + [System.AttributeUsage((System.AttributeTargets)4, AllowMultiple = false, Inherited = false)] public sealed class DesignerGeneratedAttribute : System.Attribute { public DesignerGeneratedAttribute() => throw null; @@ -290,10 +292,12 @@ public sealed class Operators public static object SubtractObject(object Left, object Right) => throw null; public static object XorObject(object Left, object Right) => throw null; } + [System.AttributeUsage((System.AttributeTargets)2048, Inherited = false, AllowMultiple = false)] public sealed class OptionCompareAttribute : System.Attribute { public OptionCompareAttribute() => throw null; } + [System.AttributeUsage((System.AttributeTargets)4, Inherited = false, AllowMultiple = false)] public sealed class OptionTextAttribute : System.Attribute { public OptionTextAttribute() => throw null; @@ -318,6 +322,7 @@ public sealed class SingleType public static float FromString(string Value) => throw null; public static float FromString(string Value, System.Globalization.NumberFormatInfo NumberFormat) => throw null; } + [System.AttributeUsage((System.AttributeTargets)4, Inherited = false, AllowMultiple = false)] public sealed class StandardModuleAttribute : System.Attribute { public StandardModuleAttribute() => throw null; @@ -870,6 +875,7 @@ public enum FirstWeekOfYear FirstFourDays = 2, FirstFullWeek = 3, } + [System.AttributeUsage((System.AttributeTargets)4, AllowMultiple = false, Inherited = false)] public sealed class HideModuleNameAttribute : System.Attribute { public HideModuleNameAttribute() => throw null; @@ -950,6 +956,7 @@ public enum MsgBoxStyle MsgBoxRight = 524288, MsgBoxRtlReading = 1048576, } + [System.AttributeUsage((System.AttributeTargets)4, AllowMultiple = false, Inherited = false)] public sealed class MyGroupCollectionAttribute : System.Attribute { public string CreateMethod { get => throw null; } @@ -1078,6 +1085,7 @@ public enum VariantType UserDefinedType = 36, Array = 8192, } + [System.AttributeUsage((System.AttributeTargets)256, Inherited = false, AllowMultiple = false)] public sealed class VBFixedArrayAttribute : System.Attribute { public int[] Bounds { get => throw null; } @@ -1085,6 +1093,7 @@ public sealed class VBFixedArrayAttribute : System.Attribute public VBFixedArrayAttribute(int UpperBound1, int UpperBound2) => throw null; public int Length { get => throw null; } } + [System.AttributeUsage((System.AttributeTargets)256, Inherited = false, AllowMultiple = false)] public sealed class VBFixedStringAttribute : System.Attribute { public VBFixedStringAttribute(int Length) => throw null; diff --git a/csharp/ql/test/resources/stubs/_frameworks/Microsoft.NETCore.App/System.ComponentModel.Annotations.cs b/csharp/ql/test/resources/stubs/_frameworks/Microsoft.NETCore.App/System.ComponentModel.Annotations.cs index 300ca5dcd914..45282a5ea2d0 100644 --- a/csharp/ql/test/resources/stubs/_frameworks/Microsoft.NETCore.App/System.ComponentModel.Annotations.cs +++ b/csharp/ql/test/resources/stubs/_frameworks/Microsoft.NETCore.App/System.ComponentModel.Annotations.cs @@ -12,6 +12,7 @@ public class AssociatedMetadataTypeTypeDescriptionProvider : System.ComponentMod public AssociatedMetadataTypeTypeDescriptionProvider(System.Type type, System.Type associatedMetadataType) => throw null; public override System.ComponentModel.ICustomTypeDescriptor GetTypeDescriptor(System.Type objectType, object instance) => throw null; } + [System.AttributeUsage((System.AttributeTargets)384, AllowMultiple = false, Inherited = true)] public sealed class AssociationAttribute : System.Attribute { public AssociationAttribute(string name, string thisKey, string otherKey) => throw null; @@ -22,6 +23,7 @@ public sealed class AssociationAttribute : System.Attribute public string ThisKey { get => throw null; } public System.Collections.Generic.IEnumerable ThisKeyMembers { get => throw null; } } + [System.AttributeUsage((System.AttributeTargets)128, AllowMultiple = false)] public class CompareAttribute : System.ComponentModel.DataAnnotations.ValidationAttribute { public CompareAttribute(string otherProperty) => throw null; @@ -31,15 +33,18 @@ public class CompareAttribute : System.ComponentModel.DataAnnotations.Validation public string OtherPropertyDisplayName { get => throw null; } public override bool RequiresValidationContext { get => throw null; } } + [System.AttributeUsage((System.AttributeTargets)384, AllowMultiple = false, Inherited = true)] public sealed class ConcurrencyCheckAttribute : System.Attribute { public ConcurrencyCheckAttribute() => throw null; } + [System.AttributeUsage((System.AttributeTargets)2432, AllowMultiple = false)] public sealed class CreditCardAttribute : System.ComponentModel.DataAnnotations.DataTypeAttribute { public CreditCardAttribute() : base(default(System.ComponentModel.DataAnnotations.DataType)) => throw null; public override bool IsValid(object value) => throw null; } + [System.AttributeUsage((System.AttributeTargets)2500, AllowMultiple = true)] public sealed class CustomValidationAttribute : System.ComponentModel.DataAnnotations.ValidationAttribute { public CustomValidationAttribute(System.Type validatorType, string method) => throw null; @@ -68,6 +73,7 @@ public enum DataType PostalCode = 15, Upload = 16, } + [System.AttributeUsage((System.AttributeTargets)2496, AllowMultiple = false)] public class DataTypeAttribute : System.ComponentModel.DataAnnotations.ValidationAttribute { public DataTypeAttribute(System.ComponentModel.DataAnnotations.DataType dataType) => throw null; @@ -78,6 +84,7 @@ public class DataTypeAttribute : System.ComponentModel.DataAnnotations.Validatio public virtual string GetDataTypeName() => throw null; public override bool IsValid(object value) => throw null; } + [System.AttributeUsage((System.AttributeTargets)2500, AllowMultiple = false)] public sealed class DisplayAttribute : System.Attribute { public bool AutoGenerateField { get => throw null; set { } } @@ -99,6 +106,7 @@ public sealed class DisplayAttribute : System.Attribute public System.Type ResourceType { get => throw null; set { } } public string ShortName { get => throw null; set { } } } + [System.AttributeUsage((System.AttributeTargets)4, Inherited = true, AllowMultiple = false)] public class DisplayColumnAttribute : System.Attribute { public DisplayColumnAttribute(string displayColumn) => throw null; @@ -108,6 +116,7 @@ public class DisplayColumnAttribute : System.Attribute public string SortColumn { get => throw null; } public bool SortDescending { get => throw null; } } + [System.AttributeUsage((System.AttributeTargets)384, AllowMultiple = false)] public class DisplayFormatAttribute : System.Attribute { public bool ApplyFormatInEditMode { get => throw null; set { } } @@ -119,23 +128,27 @@ public class DisplayFormatAttribute : System.Attribute public string NullDisplayText { get => throw null; set { } } public System.Type NullDisplayTextResourceType { get => throw null; set { } } } + [System.AttributeUsage((System.AttributeTargets)384, AllowMultiple = false, Inherited = true)] public sealed class EditableAttribute : System.Attribute { public bool AllowEdit { get => throw null; } public bool AllowInitialValue { get => throw null; set { } } public EditableAttribute(bool allowEdit) => throw null; } + [System.AttributeUsage((System.AttributeTargets)2432, AllowMultiple = false)] public sealed class EmailAddressAttribute : System.ComponentModel.DataAnnotations.DataTypeAttribute { public EmailAddressAttribute() : base(default(System.ComponentModel.DataAnnotations.DataType)) => throw null; public override bool IsValid(object value) => throw null; } + [System.AttributeUsage((System.AttributeTargets)2496, AllowMultiple = false)] public sealed class EnumDataTypeAttribute : System.ComponentModel.DataAnnotations.DataTypeAttribute { public EnumDataTypeAttribute(System.Type enumType) : base(default(System.ComponentModel.DataAnnotations.DataType)) => throw null; public System.Type EnumType { get => throw null; } public override bool IsValid(object value) => throw null; } + [System.AttributeUsage((System.AttributeTargets)2432, AllowMultiple = false)] public sealed class FileExtensionsAttribute : System.ComponentModel.DataAnnotations.DataTypeAttribute { public FileExtensionsAttribute() : base(default(System.ComponentModel.DataAnnotations.DataType)) => throw null; @@ -143,6 +156,7 @@ public sealed class FileExtensionsAttribute : System.ComponentModel.DataAnnotati public override string FormatErrorMessage(string name) => throw null; public override bool IsValid(object value) => throw null; } + [System.AttributeUsage((System.AttributeTargets)384, AllowMultiple = false)] public sealed class FilterUIHintAttribute : System.Attribute { public System.Collections.Generic.IDictionary ControlParameters { get => throw null; } @@ -158,10 +172,12 @@ public interface IValidatableObject { System.Collections.Generic.IEnumerable Validate(System.ComponentModel.DataAnnotations.ValidationContext validationContext); } + [System.AttributeUsage((System.AttributeTargets)384, AllowMultiple = false, Inherited = true)] public sealed class KeyAttribute : System.Attribute { public KeyAttribute() => throw null; } + [System.AttributeUsage((System.AttributeTargets)2432, AllowMultiple = false)] public class MaxLengthAttribute : System.ComponentModel.DataAnnotations.ValidationAttribute { public MaxLengthAttribute() => throw null; @@ -170,11 +186,13 @@ public class MaxLengthAttribute : System.ComponentModel.DataAnnotations.Validati public override bool IsValid(object value) => throw null; public int Length { get => throw null; } } + [System.AttributeUsage((System.AttributeTargets)4, AllowMultiple = false)] public sealed class MetadataTypeAttribute : System.Attribute { public MetadataTypeAttribute(System.Type metadataClassType) => throw null; public System.Type MetadataClassType { get => throw null; } } + [System.AttributeUsage((System.AttributeTargets)2432, AllowMultiple = false)] public class MinLengthAttribute : System.ComponentModel.DataAnnotations.ValidationAttribute { public MinLengthAttribute(int length) => throw null; @@ -182,11 +200,13 @@ public class MinLengthAttribute : System.ComponentModel.DataAnnotations.Validati public override bool IsValid(object value) => throw null; public int Length { get => throw null; } } + [System.AttributeUsage((System.AttributeTargets)2432, AllowMultiple = false)] public sealed class PhoneAttribute : System.ComponentModel.DataAnnotations.DataTypeAttribute { public PhoneAttribute() : base(default(System.ComponentModel.DataAnnotations.DataType)) => throw null; public override bool IsValid(object value) => throw null; } + [System.AttributeUsage((System.AttributeTargets)2432, AllowMultiple = false)] public class RangeAttribute : System.ComponentModel.DataAnnotations.ValidationAttribute { public bool ConvertValueInInvariantCulture { get => throw null; set { } } @@ -200,6 +220,7 @@ public class RangeAttribute : System.ComponentModel.DataAnnotations.ValidationAt public System.Type OperandType { get => throw null; } public bool ParseLimitsInInvariantCulture { get => throw null; set { } } } + [System.AttributeUsage((System.AttributeTargets)2432, AllowMultiple = false)] public class RegularExpressionAttribute : System.ComponentModel.DataAnnotations.ValidationAttribute { public RegularExpressionAttribute(string pattern) => throw null; @@ -209,12 +230,14 @@ public class RegularExpressionAttribute : System.ComponentModel.DataAnnotations. public int MatchTimeoutInMilliseconds { get => throw null; set { } } public string Pattern { get => throw null; } } + [System.AttributeUsage((System.AttributeTargets)2432, AllowMultiple = false)] public class RequiredAttribute : System.ComponentModel.DataAnnotations.ValidationAttribute { public bool AllowEmptyStrings { get => throw null; set { } } public RequiredAttribute() => throw null; public override bool IsValid(object value) => throw null; } + [System.AttributeUsage((System.AttributeTargets)384, AllowMultiple = false)] public class ScaffoldColumnAttribute : System.Attribute { public ScaffoldColumnAttribute(bool scaffold) => throw null; @@ -222,6 +245,7 @@ public class ScaffoldColumnAttribute : System.Attribute } namespace Schema { + [System.AttributeUsage((System.AttributeTargets)384, AllowMultiple = false)] public class ColumnAttribute : System.Attribute { public ColumnAttribute() => throw null; @@ -230,10 +254,12 @@ public class ColumnAttribute : System.Attribute public int Order { get => throw null; set { } } public string TypeName { get => throw null; set { } } } + [System.AttributeUsage((System.AttributeTargets)4, AllowMultiple = false)] public class ComplexTypeAttribute : System.Attribute { public ComplexTypeAttribute() => throw null; } + [System.AttributeUsage((System.AttributeTargets)384, AllowMultiple = false)] public class DatabaseGeneratedAttribute : System.Attribute { public DatabaseGeneratedAttribute(System.ComponentModel.DataAnnotations.Schema.DatabaseGeneratedOption databaseGeneratedOption) => throw null; @@ -245,20 +271,24 @@ public enum DatabaseGeneratedOption Identity = 1, Computed = 2, } + [System.AttributeUsage((System.AttributeTargets)384, AllowMultiple = false)] public class ForeignKeyAttribute : System.Attribute { public ForeignKeyAttribute(string name) => throw null; public string Name { get => throw null; } } + [System.AttributeUsage((System.AttributeTargets)384, AllowMultiple = false)] public class InversePropertyAttribute : System.Attribute { public InversePropertyAttribute(string property) => throw null; public string Property { get => throw null; } } + [System.AttributeUsage((System.AttributeTargets)388, AllowMultiple = false)] public class NotMappedAttribute : System.Attribute { public NotMappedAttribute() => throw null; } + [System.AttributeUsage((System.AttributeTargets)4, AllowMultiple = false)] public class TableAttribute : System.Attribute { public TableAttribute(string name) => throw null; @@ -266,6 +296,7 @@ public class TableAttribute : System.Attribute public string Schema { get => throw null; set { } } } } + [System.AttributeUsage((System.AttributeTargets)2432, AllowMultiple = false)] public class StringLengthAttribute : System.ComponentModel.DataAnnotations.ValidationAttribute { public StringLengthAttribute(int maximumLength) => throw null; @@ -274,10 +305,12 @@ public class StringLengthAttribute : System.ComponentModel.DataAnnotations.Valid public int MaximumLength { get => throw null; } public int MinimumLength { get => throw null; set { } } } + [System.AttributeUsage((System.AttributeTargets)384, AllowMultiple = false, Inherited = true)] public sealed class TimestampAttribute : System.Attribute { public TimestampAttribute() => throw null; } + [System.AttributeUsage((System.AttributeTargets)384, AllowMultiple = true)] public class UIHintAttribute : System.Attribute { public System.Collections.Generic.IDictionary ControlParameters { get => throw null; } @@ -289,6 +322,7 @@ public class UIHintAttribute : System.Attribute public string PresentationLayer { get => throw null; } public string UIHint { get => throw null; } } + [System.AttributeUsage((System.AttributeTargets)2432, AllowMultiple = false)] public sealed class UrlAttribute : System.ComponentModel.DataAnnotations.DataTypeAttribute { public UrlAttribute() : base(default(System.ComponentModel.DataAnnotations.DataType)) => throw null; diff --git a/csharp/ql/test/resources/stubs/_frameworks/Microsoft.NETCore.App/System.ComponentModel.Primitives.cs b/csharp/ql/test/resources/stubs/_frameworks/Microsoft.NETCore.App/System.ComponentModel.Primitives.cs index d2dbcebce752..3eb2b7b62a0e 100644 --- a/csharp/ql/test/resources/stubs/_frameworks/Microsoft.NETCore.App/System.ComponentModel.Primitives.cs +++ b/csharp/ql/test/resources/stubs/_frameworks/Microsoft.NETCore.App/System.ComponentModel.Primitives.cs @@ -4,6 +4,7 @@ namespace System { namespace ComponentModel { + [System.AttributeUsage((System.AttributeTargets)32767)] public sealed class BrowsableAttribute : System.Attribute { public bool Browsable { get => throw null; } @@ -15,6 +16,7 @@ public sealed class BrowsableAttribute : System.Attribute public static readonly System.ComponentModel.BrowsableAttribute No; public static readonly System.ComponentModel.BrowsableAttribute Yes; } + [System.AttributeUsage((System.AttributeTargets)32767)] public class CategoryAttribute : System.Attribute { public static System.ComponentModel.CategoryAttribute Action { get => throw null; } @@ -60,6 +62,7 @@ public class ComponentCollection : System.Collections.ReadOnlyCollectionBase public virtual System.ComponentModel.IComponent this[int index] { get => throw null; } public virtual System.ComponentModel.IComponent this[string name] { get => throw null; } } + [System.AttributeUsage((System.AttributeTargets)32767)] public class DescriptionAttribute : System.Attribute { public DescriptionAttribute() => throw null; @@ -75,6 +78,7 @@ namespace Design { namespace Serialization { + [System.AttributeUsage((System.AttributeTargets)1028, AllowMultiple = true, Inherited = true)] public sealed class DesignerSerializerAttribute : System.Attribute { public DesignerSerializerAttribute(string serializerTypeName, string baseSerializerTypeName) => throw null; @@ -86,6 +90,7 @@ public sealed class DesignerSerializerAttribute : System.Attribute } } } + [System.AttributeUsage((System.AttributeTargets)1028, AllowMultiple = true, Inherited = true)] public sealed class DesignerAttribute : System.Attribute { public DesignerAttribute(string designerTypeName) => throw null; @@ -99,6 +104,7 @@ public sealed class DesignerAttribute : System.Attribute public override int GetHashCode() => throw null; public override object TypeId { get => throw null; } } + [System.AttributeUsage((System.AttributeTargets)4, AllowMultiple = false, Inherited = true)] public sealed class DesignerCategoryAttribute : System.Attribute { public string Category { get => throw null; } @@ -119,6 +125,7 @@ public enum DesignerSerializationVisibility Visible = 1, Content = 2, } + [System.AttributeUsage((System.AttributeTargets)960)] public sealed class DesignerSerializationVisibilityAttribute : System.Attribute { public static readonly System.ComponentModel.DesignerSerializationVisibilityAttribute Content; @@ -131,6 +138,7 @@ public sealed class DesignerSerializationVisibilityAttribute : System.Attribute public System.ComponentModel.DesignerSerializationVisibility Visibility { get => throw null; } public static readonly System.ComponentModel.DesignerSerializationVisibilityAttribute Visible; } + [System.AttributeUsage((System.AttributeTargets)32767)] public sealed class DesignOnlyAttribute : System.Attribute { public DesignOnlyAttribute(bool isDesignOnly) => throw null; @@ -142,6 +150,7 @@ public sealed class DesignOnlyAttribute : System.Attribute public static readonly System.ComponentModel.DesignOnlyAttribute No; public static readonly System.ComponentModel.DesignOnlyAttribute Yes; } + [System.AttributeUsage((System.AttributeTargets)708)] public class DisplayNameAttribute : System.Attribute { public DisplayNameAttribute() => throw null; @@ -153,6 +162,7 @@ public class DisplayNameAttribute : System.Attribute public override int GetHashCode() => throw null; public override bool IsDefaultAttribute() => throw null; } + [System.AttributeUsage((System.AttributeTargets)32767, AllowMultiple = true, Inherited = true)] public sealed class EditorAttribute : System.Attribute { public EditorAttribute() => throw null; @@ -186,6 +196,7 @@ public interface IContainer : System.IDisposable System.ComponentModel.ComponentCollection Components { get; } void Remove(System.ComponentModel.IComponent component); } + [System.AttributeUsage((System.AttributeTargets)32767)] public sealed class ImmutableObjectAttribute : System.Attribute { public ImmutableObjectAttribute(bool immutable) => throw null; @@ -197,6 +208,7 @@ public sealed class ImmutableObjectAttribute : System.Attribute public static readonly System.ComponentModel.ImmutableObjectAttribute No; public static readonly System.ComponentModel.ImmutableObjectAttribute Yes; } + [System.AttributeUsage((System.AttributeTargets)4)] public sealed class InitializationEventAttribute : System.Attribute { public InitializationEventAttribute(string eventName) => throw null; @@ -236,6 +248,7 @@ public interface ISynchronizeInvoke object Invoke(System.Delegate method, object[] args); bool InvokeRequired { get; } } + [System.AttributeUsage((System.AttributeTargets)32767)] public sealed class LocalizableAttribute : System.Attribute { public LocalizableAttribute(bool isLocalizable) => throw null; @@ -247,6 +260,7 @@ public sealed class LocalizableAttribute : System.Attribute public static readonly System.ComponentModel.LocalizableAttribute No; public static readonly System.ComponentModel.LocalizableAttribute Yes; } + [System.AttributeUsage((System.AttributeTargets)32767)] public sealed class MergablePropertyAttribute : System.Attribute { public bool AllowMerge { get => throw null; } @@ -258,6 +272,7 @@ public sealed class MergablePropertyAttribute : System.Attribute public static readonly System.ComponentModel.MergablePropertyAttribute No; public static readonly System.ComponentModel.MergablePropertyAttribute Yes; } + [System.AttributeUsage((System.AttributeTargets)128)] public sealed class NotifyParentPropertyAttribute : System.Attribute { public NotifyParentPropertyAttribute(bool notifyParent) => throw null; @@ -269,6 +284,7 @@ public sealed class NotifyParentPropertyAttribute : System.Attribute public bool NotifyParent { get => throw null; } public static readonly System.ComponentModel.NotifyParentPropertyAttribute Yes; } + [System.AttributeUsage((System.AttributeTargets)32767)] public sealed class ParenthesizePropertyNameAttribute : System.Attribute { public ParenthesizePropertyNameAttribute() => throw null; @@ -279,6 +295,7 @@ public sealed class ParenthesizePropertyNameAttribute : System.Attribute public override bool IsDefaultAttribute() => throw null; public bool NeedParenthesis { get => throw null; } } + [System.AttributeUsage((System.AttributeTargets)32767)] public sealed class ReadOnlyAttribute : System.Attribute { public ReadOnlyAttribute(bool isReadOnly) => throw null; @@ -296,6 +313,7 @@ public enum RefreshProperties All = 1, Repaint = 2, } + [System.AttributeUsage((System.AttributeTargets)32767)] public sealed class RefreshPropertiesAttribute : System.Attribute { public static readonly System.ComponentModel.RefreshPropertiesAttribute All; diff --git a/csharp/ql/test/resources/stubs/_frameworks/Microsoft.NETCore.App/System.ComponentModel.TypeConverter.cs b/csharp/ql/test/resources/stubs/_frameworks/Microsoft.NETCore.App/System.ComponentModel.TypeConverter.cs index 17f4792760b1..0b7773473eb2 100644 --- a/csharp/ql/test/resources/stubs/_frameworks/Microsoft.NETCore.App/System.ComponentModel.TypeConverter.cs +++ b/csharp/ql/test/resources/stubs/_frameworks/Microsoft.NETCore.App/System.ComponentModel.TypeConverter.cs @@ -11,6 +11,7 @@ public class AddingNewEventArgs : System.EventArgs public object NewObject { get => throw null; set { } } } public delegate void AddingNewEventHandler(object sender, System.ComponentModel.AddingNewEventArgs e); + [System.AttributeUsage((System.AttributeTargets)32767)] public sealed class AmbientValueAttribute : System.Attribute { public AmbientValueAttribute(bool value) => throw null; @@ -57,6 +58,7 @@ public class AttributeCollection : System.Collections.ICollection, System.Collec public virtual System.Attribute this[int index] { get => throw null; } public virtual System.Attribute this[System.Type attributeType] { get => throw null; } } + [System.AttributeUsage((System.AttributeTargets)128)] public class AttributeProviderAttribute : System.Attribute { public AttributeProviderAttribute(string typeName) => throw null; @@ -72,6 +74,7 @@ public abstract class BaseNumberConverter : System.ComponentModel.TypeConverter public override object ConvertFrom(System.ComponentModel.ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value) => throw null; public override object ConvertTo(System.ComponentModel.ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value, System.Type destinationType) => throw null; } + [System.AttributeUsage((System.AttributeTargets)32767)] public sealed class BindableAttribute : System.Attribute { public bool Bindable { get => throw null; } @@ -186,6 +189,7 @@ public class CollectionConverter : System.ComponentModel.TypeConverter public CollectionConverter() => throw null; public override System.ComponentModel.PropertyDescriptorCollection GetProperties(System.ComponentModel.ITypeDescriptorContext context, object value, System.Attribute[] attributes) => throw null; } + [System.AttributeUsage((System.AttributeTargets)4)] public sealed class ComplexBindingPropertiesAttribute : System.Attribute { public ComplexBindingPropertiesAttribute() => throw null; @@ -264,6 +268,7 @@ public abstract class CustomTypeDescriptor : System.ComponentModel.ICustomTypeDe public virtual System.ComponentModel.PropertyDescriptorCollection GetProperties(System.Attribute[] attributes) => throw null; public virtual object GetPropertyOwner(System.ComponentModel.PropertyDescriptor pd) => throw null; } + [System.AttributeUsage((System.AttributeTargets)4)] public sealed class DataObjectAttribute : System.Attribute { public DataObjectAttribute() => throw null; @@ -276,6 +281,7 @@ public sealed class DataObjectAttribute : System.Attribute public override bool IsDefaultAttribute() => throw null; public static readonly System.ComponentModel.DataObjectAttribute NonDataObject; } + [System.AttributeUsage((System.AttributeTargets)128)] public sealed class DataObjectFieldAttribute : System.Attribute { public DataObjectFieldAttribute(bool primaryKey) => throw null; @@ -289,6 +295,7 @@ public sealed class DataObjectFieldAttribute : System.Attribute public int Length { get => throw null; } public bool PrimaryKey { get => throw null; } } + [System.AttributeUsage((System.AttributeTargets)64)] public sealed class DataObjectMethodAttribute : System.Attribute { public DataObjectMethodAttribute(System.ComponentModel.DataObjectMethodType methodType) => throw null; @@ -337,6 +344,7 @@ public class DecimalConverter : System.ComponentModel.BaseNumberConverter public override object ConvertTo(System.ComponentModel.ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value, System.Type destinationType) => throw null; public DecimalConverter() => throw null; } + [System.AttributeUsage((System.AttributeTargets)4)] public sealed class DefaultBindingPropertyAttribute : System.Attribute { public DefaultBindingPropertyAttribute() => throw null; @@ -346,6 +354,7 @@ public sealed class DefaultBindingPropertyAttribute : System.Attribute public override int GetHashCode() => throw null; public string Name { get => throw null; } } + [System.AttributeUsage((System.AttributeTargets)4)] public sealed class DefaultEventAttribute : System.Attribute { public DefaultEventAttribute(string name) => throw null; @@ -354,6 +363,7 @@ public sealed class DefaultEventAttribute : System.Attribute public override int GetHashCode() => throw null; public string Name { get => throw null; } } + [System.AttributeUsage((System.AttributeTargets)4)] public sealed class DefaultPropertyAttribute : System.Attribute { public DefaultPropertyAttribute(string name) => throw null; @@ -536,6 +546,7 @@ public enum HelpContextType Selection = 2, ToolWindowSelection = 3, } + [System.AttributeUsage((System.AttributeTargets)32767, AllowMultiple = false, Inherited = false)] public sealed class HelpKeywordAttribute : System.Attribute { public HelpKeywordAttribute() => throw null; @@ -805,6 +816,7 @@ public sealed class ContextStack public object this[int level] { get => throw null; } public object this[System.Type type] { get => throw null; } } + [System.AttributeUsage((System.AttributeTargets)4, Inherited = false)] public sealed class DefaultSerializationProviderAttribute : System.Attribute { public DefaultSerializationProviderAttribute(string providerTypeName) => throw null; @@ -904,6 +916,7 @@ public class ResolveNameEventArgs : System.EventArgs public object Value { get => throw null; set { } } } public delegate void ResolveNameEventHandler(object sender, System.ComponentModel.Design.Serialization.ResolveNameEventArgs e); + [System.AttributeUsage((System.AttributeTargets)1028, AllowMultiple = true, Inherited = true)] public sealed class RootDesignerSerializerAttribute : System.Attribute { public RootDesignerSerializerAttribute(string serializerTypeName, string baseSerializerTypeName, bool reloadable) => throw null; @@ -1024,6 +1037,7 @@ public enum ViewTechnology Default = 2, } } + [System.AttributeUsage((System.AttributeTargets)1028)] public sealed class DesignTimeVisibleAttribute : System.Attribute { public DesignTimeVisibleAttribute() => throw null; @@ -1111,6 +1125,7 @@ public class ExpandableObjectConverter : System.ComponentModel.TypeConverter public override System.ComponentModel.PropertyDescriptorCollection GetProperties(System.ComponentModel.ITypeDescriptorContext context, object value, System.Attribute[] attributes) => throw null; public override bool GetPropertiesSupported(System.ComponentModel.ITypeDescriptorContext context) => throw null; } + [System.AttributeUsage((System.AttributeTargets)32767)] public sealed class ExtenderProvidedPropertyAttribute : System.Attribute { public ExtenderProvidedPropertyAttribute() => throw null; @@ -1230,6 +1245,7 @@ public interface INestedSite : System.IServiceProvider, System.ComponentModel.IS { string FullName { get; } } + [System.AttributeUsage((System.AttributeTargets)896)] public sealed class InheritanceAttribute : System.Attribute { public InheritanceAttribute() => throw null; @@ -1250,6 +1266,7 @@ public enum InheritanceLevel InheritedReadOnly = 2, NotInherited = 3, } + [System.AttributeUsage((System.AttributeTargets)4)] public class InstallerTypeAttribute : System.Attribute { public InstallerTypeAttribute(string typeName) => throw null; @@ -1345,6 +1362,7 @@ public abstract class LicenseProvider protected LicenseProvider() => throw null; public abstract System.ComponentModel.License GetLicense(System.ComponentModel.LicenseContext context, System.Type type, object instance, bool allowExceptions); } + [System.AttributeUsage((System.AttributeTargets)4, AllowMultiple = false, Inherited = false)] public sealed class LicenseProviderAttribute : System.Attribute { public LicenseProviderAttribute() => throw null; @@ -1368,6 +1386,7 @@ public class LicFileLicenseProvider : System.ComponentModel.LicenseProvider public override System.ComponentModel.License GetLicense(System.ComponentModel.LicenseContext context, System.Type type, object instance, bool allowExceptions) => throw null; protected virtual bool IsKeyValid(string key, System.Type type) => throw null; } + [System.AttributeUsage((System.AttributeTargets)32767)] public sealed class ListBindableAttribute : System.Attribute { public ListBindableAttribute(bool listBindable) => throw null; @@ -1435,6 +1454,7 @@ public enum ListSortDirection Ascending = 0, Descending = 1, } + [System.AttributeUsage((System.AttributeTargets)4)] public sealed class LookupBindingPropertiesAttribute : System.Attribute { public LookupBindingPropertiesAttribute() => throw null; @@ -1621,6 +1641,7 @@ public class NullableConverter : System.ComponentModel.TypeConverter public System.Type UnderlyingType { get => throw null; } public System.ComponentModel.TypeConverter UnderlyingTypeConverter { get => throw null; } } + [System.AttributeUsage((System.AttributeTargets)32767)] public sealed class PasswordPropertyTextAttribute : System.Attribute { public PasswordPropertyTextAttribute() => throw null; @@ -1715,6 +1736,7 @@ public class PropertyDescriptorCollection : System.Collections.ICollection, Syst public virtual System.ComponentModel.PropertyDescriptor this[string name] { get => throw null; } System.Collections.ICollection System.Collections.IDictionary.Values { get => throw null; } } + [System.AttributeUsage((System.AttributeTargets)32767)] public class PropertyTabAttribute : System.Attribute { public PropertyTabAttribute() => throw null; @@ -1738,6 +1760,7 @@ public enum PropertyTabScope Document = 2, Component = 3, } + [System.AttributeUsage((System.AttributeTargets)4, AllowMultiple = true)] public sealed class ProvidePropertyAttribute : System.Attribute { public ProvidePropertyAttribute(string propertyName, string receiverTypeName) => throw null; @@ -1748,6 +1771,7 @@ public sealed class ProvidePropertyAttribute : System.Attribute public string ReceiverTypeName { get => throw null; } public override object TypeId { get => throw null; } } + [System.AttributeUsage((System.AttributeTargets)128)] public class RecommendedAsConfigurableAttribute : System.Attribute { public RecommendedAsConfigurableAttribute(bool recommendedAsConfigurable) => throw null; @@ -1778,6 +1802,7 @@ public class RefreshEventArgs : System.EventArgs public System.Type TypeChanged { get => throw null; } } public delegate void RefreshEventHandler(System.ComponentModel.RefreshEventArgs e); + [System.AttributeUsage((System.AttributeTargets)4)] public class RunInstallerAttribute : System.Attribute { public RunInstallerAttribute(bool runInstaller) => throw null; @@ -1793,6 +1818,7 @@ public class SByteConverter : System.ComponentModel.BaseNumberConverter { public SByteConverter() => throw null; } + [System.AttributeUsage((System.AttributeTargets)128)] public sealed class SettingsBindableAttribute : System.Attribute { public bool Bindable { get => throw null; } @@ -1834,6 +1860,7 @@ public class TimeSpanConverter : System.ComponentModel.TypeConverter public override object ConvertTo(System.ComponentModel.ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value, System.Type destinationType) => throw null; public TimeSpanConverter() => throw null; } + [System.AttributeUsage((System.AttributeTargets)32767)] public class ToolboxItemAttribute : System.Attribute { public ToolboxItemAttribute(bool defaultType) => throw null; @@ -1847,6 +1874,7 @@ public class ToolboxItemAttribute : System.Attribute public System.Type ToolboxItemType { get => throw null; } public string ToolboxItemTypeName { get => throw null; } } + [System.AttributeUsage((System.AttributeTargets)4, AllowMultiple = true, Inherited = true)] public sealed class ToolboxItemFilterAttribute : System.Attribute { public ToolboxItemFilterAttribute(string filterString) => throw null; @@ -2167,6 +2195,7 @@ public class Timer : System.ComponentModel.Component, System.ComponentModel.ISup public void Stop() => throw null; public System.ComponentModel.ISynchronizeInvoke SynchronizingObject { get => throw null; set { } } } + [System.AttributeUsage((System.AttributeTargets)32767)] public class TimersDescriptionAttribute : System.ComponentModel.DescriptionAttribute { public TimersDescriptionAttribute(string description) => throw null; diff --git a/csharp/ql/test/resources/stubs/_frameworks/Microsoft.NETCore.App/System.Data.Common.cs b/csharp/ql/test/resources/stubs/_frameworks/Microsoft.NETCore.App/System.Data.Common.cs index 976ccb3a69f8..e9df8ea54f1f 100644 --- a/csharp/ql/test/resources/stubs/_frameworks/Microsoft.NETCore.App/System.Data.Common.cs +++ b/csharp/ql/test/resources/stubs/_frameworks/Microsoft.NETCore.App/System.Data.Common.cs @@ -747,6 +747,7 @@ public abstract class DbProviderFactory public virtual System.Data.Common.DbParameter CreateParameter() => throw null; protected DbProviderFactory() => throw null; } + [System.AttributeUsage((System.AttributeTargets)128, AllowMultiple = false, Inherited = true)] public sealed class DbProviderSpecificTypePropertyAttribute : System.Attribute { public DbProviderSpecificTypePropertyAttribute(bool isProviderSpecificTypeProperty) => throw null; @@ -1344,6 +1345,7 @@ public enum DataSetDateTime UnspecifiedLocal = 3, Utc = 4, } + [System.AttributeUsage((System.AttributeTargets)32767)] public class DataSysDescriptionAttribute : System.ComponentModel.DescriptionAttribute { public DataSysDescriptionAttribute(string description) => throw null; diff --git a/csharp/ql/test/resources/stubs/_frameworks/Microsoft.NETCore.App/System.Diagnostics.Contracts.cs b/csharp/ql/test/resources/stubs/_frameworks/Microsoft.NETCore.App/System.Diagnostics.Contracts.cs index 5f4667d35df5..68695d594be5 100644 --- a/csharp/ql/test/resources/stubs/_frameworks/Microsoft.NETCore.App/System.Diagnostics.Contracts.cs +++ b/csharp/ql/test/resources/stubs/_frameworks/Microsoft.NETCore.App/System.Diagnostics.Contracts.cs @@ -32,19 +32,23 @@ public static class Contract public static T Result() => throw null; public static T ValueAtReturn(out T value) => throw null; } + [System.AttributeUsage((System.AttributeTargets)64, AllowMultiple = false)] public sealed class ContractAbbreviatorAttribute : System.Attribute { public ContractAbbreviatorAttribute() => throw null; } + [System.AttributeUsage((System.AttributeTargets)64, AllowMultiple = false)] public sealed class ContractArgumentValidatorAttribute : System.Attribute { public ContractArgumentValidatorAttribute() => throw null; } + [System.AttributeUsage((System.AttributeTargets)5124, AllowMultiple = false, Inherited = false)] public sealed class ContractClassAttribute : System.Attribute { public ContractClassAttribute(System.Type typeContainingContracts) => throw null; public System.Type TypeContainingContracts { get => throw null; } } + [System.AttributeUsage((System.AttributeTargets)4, AllowMultiple = false, Inherited = false)] public sealed class ContractClassForAttribute : System.Attribute { public ContractClassForAttribute(System.Type typeContractsAreFor) => throw null; @@ -71,10 +75,12 @@ public enum ContractFailureKind Assert = 4, Assume = 5, } + [System.AttributeUsage((System.AttributeTargets)64, AllowMultiple = false, Inherited = false)] public sealed class ContractInvariantMethodAttribute : System.Attribute { public ContractInvariantMethodAttribute() => throw null; } + [System.AttributeUsage((System.AttributeTargets)32767, AllowMultiple = true, Inherited = false)] public sealed class ContractOptionAttribute : System.Attribute { public string Category { get => throw null; } @@ -84,24 +90,29 @@ public sealed class ContractOptionAttribute : System.Attribute public string Setting { get => throw null; } public string Value { get => throw null; } } + [System.AttributeUsage((System.AttributeTargets)256)] public sealed class ContractPublicPropertyNameAttribute : System.Attribute { public ContractPublicPropertyNameAttribute(string name) => throw null; public string Name { get => throw null; } } + [System.AttributeUsage((System.AttributeTargets)1)] public sealed class ContractReferenceAssemblyAttribute : System.Attribute { public ContractReferenceAssemblyAttribute() => throw null; } + [System.AttributeUsage((System.AttributeTargets)192, AllowMultiple = false, Inherited = true)] public sealed class ContractRuntimeIgnoredAttribute : System.Attribute { public ContractRuntimeIgnoredAttribute() => throw null; } + [System.AttributeUsage((System.AttributeTargets)237)] public sealed class ContractVerificationAttribute : System.Attribute { public ContractVerificationAttribute(bool value) => throw null; public bool Value { get => throw null; } } + [System.AttributeUsage((System.AttributeTargets)6884, AllowMultiple = false, Inherited = true)] public sealed class PureAttribute : System.Attribute { public PureAttribute() => throw null; diff --git a/csharp/ql/test/resources/stubs/_frameworks/Microsoft.NETCore.App/System.Diagnostics.Process.cs b/csharp/ql/test/resources/stubs/_frameworks/Microsoft.NETCore.App/System.Diagnostics.Process.cs index 8e00f43bcf16..14cf6c198be3 100644 --- a/csharp/ql/test/resources/stubs/_frameworks/Microsoft.NETCore.App/System.Diagnostics.Process.cs +++ b/csharp/ql/test/resources/stubs/_frameworks/Microsoft.NETCore.App/System.Diagnostics.Process.cs @@ -24,6 +24,7 @@ public class DataReceivedEventArgs : System.EventArgs public string Data { get => throw null; } } public delegate void DataReceivedEventHandler(object sender, System.Diagnostics.DataReceivedEventArgs e); + [System.AttributeUsage((System.AttributeTargets)32767)] public class MonitoringDescriptionAttribute : System.ComponentModel.DescriptionAttribute { public MonitoringDescriptionAttribute(string description) => throw null; diff --git a/csharp/ql/test/resources/stubs/_frameworks/Microsoft.NETCore.App/System.Diagnostics.TraceSource.cs b/csharp/ql/test/resources/stubs/_frameworks/Microsoft.NETCore.App/System.Diagnostics.TraceSource.cs index cd0bc6024967..a6a1a0d53035 100644 --- a/csharp/ql/test/resources/stubs/_frameworks/Microsoft.NETCore.App/System.Diagnostics.TraceSource.cs +++ b/csharp/ql/test/resources/stubs/_frameworks/Microsoft.NETCore.App/System.Diagnostics.TraceSource.cs @@ -88,6 +88,7 @@ public abstract class Switch protected int SwitchSetting { get => throw null; set { } } public string Value { get => throw null; set { } } } + [System.AttributeUsage((System.AttributeTargets)741)] public sealed class SwitchAttribute : System.Attribute { public SwitchAttribute(string switchName, System.Type switchType) => throw null; @@ -96,6 +97,7 @@ public sealed class SwitchAttribute : System.Attribute public string SwitchName { get => throw null; set { } } public System.Type SwitchType { get => throw null; set { } } } + [System.AttributeUsage((System.AttributeTargets)4)] public sealed class SwitchLevelAttribute : System.Attribute { public SwitchLevelAttribute(System.Type switchLevelType) => throw null; diff --git a/csharp/ql/test/resources/stubs/_frameworks/Microsoft.NETCore.App/System.Diagnostics.Tracing.cs b/csharp/ql/test/resources/stubs/_frameworks/Microsoft.NETCore.App/System.Diagnostics.Tracing.cs index 25bdb670c506..fda5a8f585b9 100644 --- a/csharp/ql/test/resources/stubs/_frameworks/Microsoft.NETCore.App/System.Diagnostics.Tracing.cs +++ b/csharp/ql/test/resources/stubs/_frameworks/Microsoft.NETCore.App/System.Diagnostics.Tracing.cs @@ -23,6 +23,7 @@ public enum EventActivityOptions Recursive = 4, Detachable = 8, } + [System.AttributeUsage((System.AttributeTargets)64)] public sealed class EventAttribute : System.Attribute { public System.Diagnostics.Tracing.EventActivityOptions ActivityOptions { get => throw null; set { } } @@ -66,11 +67,13 @@ public class EventCounter : System.Diagnostics.Tracing.DiagnosticCounter public void WriteMetric(double value) => throw null; public void WriteMetric(float value) => throw null; } + [System.AttributeUsage((System.AttributeTargets)12, Inherited = false)] public class EventDataAttribute : System.Attribute { public EventDataAttribute() => throw null; public string Name { get => throw null; set { } } } + [System.AttributeUsage((System.AttributeTargets)128)] public class EventFieldAttribute : System.Attribute { public EventFieldAttribute() => throw null; @@ -92,6 +95,7 @@ public enum EventFieldTags { None = 0, } + [System.AttributeUsage((System.AttributeTargets)128)] public class EventIgnoreAttribute : System.Attribute { public EventIgnoreAttribute() => throw null; @@ -220,6 +224,7 @@ protected struct EventData protected void WriteEventWithRelatedActivityId(int eventId, System.Guid relatedActivityId, params object[] args) => throw null; protected unsafe void WriteEventWithRelatedActivityIdCore(int eventId, System.Guid* relatedActivityId, int eventDataCount, System.Diagnostics.Tracing.EventSource.EventData* data) => throw null; } + [System.AttributeUsage((System.AttributeTargets)4)] public sealed class EventSourceAttribute : System.Attribute { public EventSourceAttribute() => throw null; @@ -297,6 +302,7 @@ public class IncrementingPollingCounter : System.Diagnostics.Tracing.DiagnosticC public System.TimeSpan DisplayRateTimeScale { get => throw null; set { } } public override string ToString() => throw null; } + [System.AttributeUsage((System.AttributeTargets)64)] public sealed class NonEventAttribute : System.Attribute { public NonEventAttribute() => throw null; diff --git a/csharp/ql/test/resources/stubs/_frameworks/Microsoft.NETCore.App/System.Linq.Expressions.cs b/csharp/ql/test/resources/stubs/_frameworks/Microsoft.NETCore.App/System.Linq.Expressions.cs index 6360c3eee21a..bd99e1bc2083 100644 --- a/csharp/ql/test/resources/stubs/_frameworks/Microsoft.NETCore.App/System.Linq.Expressions.cs +++ b/csharp/ql/test/resources/stubs/_frameworks/Microsoft.NETCore.App/System.Linq.Expressions.cs @@ -1108,6 +1108,7 @@ public abstract class DebugInfoGenerator protected DebugInfoGenerator() => throw null; public abstract void MarkSequencePoint(System.Linq.Expressions.LambdaExpression method, int ilOffset, System.Linq.Expressions.DebugInfoExpression sequencePoint); } + [System.AttributeUsage((System.AttributeTargets)10636)] public sealed class DynamicAttribute : System.Attribute { public DynamicAttribute() => throw null; diff --git a/csharp/ql/test/resources/stubs/_frameworks/Microsoft.NETCore.App/System.ObjectModel.cs b/csharp/ql/test/resources/stubs/_frameworks/Microsoft.NETCore.App/System.ObjectModel.cs index 5435223d6353..20ae2c1ba0bc 100644 --- a/csharp/ql/test/resources/stubs/_frameworks/Microsoft.NETCore.App/System.ObjectModel.cs +++ b/csharp/ql/test/resources/stubs/_frameworks/Microsoft.NETCore.App/System.ObjectModel.cs @@ -123,6 +123,7 @@ public class PropertyChangingEventArgs : System.EventArgs public virtual string PropertyName { get => throw null; } } public delegate void PropertyChangingEventHandler(object sender, System.ComponentModel.PropertyChangingEventArgs e); + [System.AttributeUsage((System.AttributeTargets)32767)] public sealed class TypeConverterAttribute : System.Attribute { public string ConverterTypeName { get => throw null; } @@ -133,6 +134,7 @@ public sealed class TypeConverterAttribute : System.Attribute public override bool Equals(object obj) => throw null; public override int GetHashCode() => throw null; } + [System.AttributeUsage((System.AttributeTargets)4, Inherited = true)] public sealed class TypeDescriptionProviderAttribute : System.Attribute { public TypeDescriptionProviderAttribute(string typeName) => throw null; @@ -160,6 +162,7 @@ public interface ICommand } namespace Markup { + [System.AttributeUsage((System.AttributeTargets)1244, AllowMultiple = false, Inherited = true)] public sealed class ValueSerializerAttribute : System.Attribute { public ValueSerializerAttribute(string valueSerializerTypeName) => throw null; diff --git a/csharp/ql/test/resources/stubs/_frameworks/Microsoft.NETCore.App/System.Runtime.CompilerServices.VisualC.cs b/csharp/ql/test/resources/stubs/_frameworks/Microsoft.NETCore.App/System.Runtime.CompilerServices.VisualC.cs index a359bca22a8c..837618660d7d 100644 --- a/csharp/ql/test/resources/stubs/_frameworks/Microsoft.NETCore.App/System.Runtime.CompilerServices.VisualC.cs +++ b/csharp/ql/test/resources/stubs/_frameworks/Microsoft.NETCore.App/System.Runtime.CompilerServices.VisualC.cs @@ -9,10 +9,12 @@ namespace CompilerServices public static class CompilerMarshalOverride { } + [System.AttributeUsage((System.AttributeTargets)1, AllowMultiple = true)] public sealed class CppInlineNamespaceAttribute : System.Attribute { public CppInlineNamespaceAttribute(string dottedName) => throw null; } + [System.AttributeUsage((System.AttributeTargets)8)] public sealed class HasCopySemanticsAttribute : System.Attribute { public HasCopySemanticsAttribute() => throw null; @@ -47,15 +49,18 @@ public static class IsSignUnspecifiedByte public static class IsUdtReturn { } + [System.AttributeUsage((System.AttributeTargets)8, Inherited = true)] public sealed class NativeCppClassAttribute : System.Attribute { public NativeCppClassAttribute() => throw null; } + [System.AttributeUsage((System.AttributeTargets)1052, AllowMultiple = true, Inherited = false)] public sealed class RequiredAttributeAttribute : System.Attribute { public RequiredAttributeAttribute(System.Type requiredContract) => throw null; public System.Type RequiredContract { get => throw null; } } + [System.AttributeUsage((System.AttributeTargets)16)] public sealed class ScopelessEnumAttribute : System.Attribute { public ScopelessEnumAttribute() => throw null; diff --git a/csharp/ql/test/resources/stubs/_frameworks/Microsoft.NETCore.App/System.Runtime.InteropServices.JavaScript.cs b/csharp/ql/test/resources/stubs/_frameworks/Microsoft.NETCore.App/System.Runtime.InteropServices.JavaScript.cs index f731e562f02f..46b3eb282654 100644 --- a/csharp/ql/test/resources/stubs/_frameworks/Microsoft.NETCore.App/System.Runtime.InteropServices.JavaScript.cs +++ b/csharp/ql/test/resources/stubs/_frameworks/Microsoft.NETCore.App/System.Runtime.InteropServices.JavaScript.cs @@ -12,6 +12,7 @@ public sealed class JSException : System.Exception { public JSException(string msg) => throw null; } + [System.AttributeUsage((System.AttributeTargets)64, Inherited = false, AllowMultiple = false)] public sealed class JSExportAttribute : System.Attribute { public JSExportAttribute() => throw null; @@ -29,6 +30,7 @@ public static class JSHost public static System.Runtime.InteropServices.JavaScript.JSObject GlobalThis { get => throw null; } public static System.Threading.Tasks.Task ImportAsync(string moduleName, string moduleUrl, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) => throw null; } + [System.AttributeUsage((System.AttributeTargets)64, Inherited = false, AllowMultiple = false)] public sealed class JSImportAttribute : System.Attribute { public JSImportAttribute(string functionName) => throw null; @@ -36,6 +38,7 @@ public sealed class JSImportAttribute : System.Attribute public string FunctionName { get => throw null; } public string ModuleName { get => throw null; } } + [System.AttributeUsage((System.AttributeTargets)10240, Inherited = false, AllowMultiple = false)] public sealed class JSMarshalAsAttribute : System.Attribute where T : System.Runtime.InteropServices.JavaScript.JSType { public JSMarshalAsAttribute() => throw null; diff --git a/csharp/ql/test/resources/stubs/_frameworks/Microsoft.NETCore.App/System.Runtime.InteropServices.cs b/csharp/ql/test/resources/stubs/_frameworks/Microsoft.NETCore.App/System.Runtime.InteropServices.cs index 3b68230ef19f..31116a73a0bc 100644 --- a/csharp/ql/test/resources/stubs/_frameworks/Microsoft.NETCore.App/System.Runtime.InteropServices.cs +++ b/csharp/ql/test/resources/stubs/_frameworks/Microsoft.NETCore.App/System.Runtime.InteropServices.cs @@ -65,11 +65,13 @@ namespace Runtime { namespace CompilerServices { + [System.AttributeUsage((System.AttributeTargets)2304, Inherited = false)] public sealed class IDispatchConstantAttribute : System.Runtime.CompilerServices.CustomConstantAttribute { public IDispatchConstantAttribute() => throw null; public override object Value { get => throw null; } } + [System.AttributeUsage((System.AttributeTargets)2304, Inherited = false)] public sealed class IUnknownConstantAttribute : System.Runtime.CompilerServices.CustomConstantAttribute { public IUnknownConstantAttribute() => throw null; @@ -78,6 +80,7 @@ public sealed class IUnknownConstantAttribute : System.Runtime.CompilerServices. } namespace InteropServices { + [System.AttributeUsage((System.AttributeTargets)64, AllowMultiple = false, Inherited = false)] public sealed class AllowReversePInvokeCallsAttribute : System.Attribute { public AllowReversePInvokeCallsAttribute() => throw null; @@ -93,11 +96,13 @@ public struct ArrayWithOffset : System.IEquatable throw null; public static bool operator !=(System.Runtime.InteropServices.ArrayWithOffset a, System.Runtime.InteropServices.ArrayWithOffset b) => throw null; } + [System.AttributeUsage((System.AttributeTargets)1029, Inherited = false)] public sealed class AutomationProxyAttribute : System.Attribute { public AutomationProxyAttribute(bool val) => throw null; public bool Value { get => throw null; } } + [System.AttributeUsage((System.AttributeTargets)1037, Inherited = false)] public sealed class BestFitMappingAttribute : System.Attribute { public bool BestFitMapping { get => throw null; } @@ -118,6 +123,7 @@ public enum CallingConvention ThisCall = 4, FastCall = 5, } + [System.AttributeUsage((System.AttributeTargets)5, Inherited = false)] public sealed class ClassInterfaceAttribute : System.Attribute { public ClassInterfaceAttribute(short classInterfaceType) => throw null; @@ -140,6 +146,7 @@ public struct CLong : System.IEquatable public override string ToString() => throw null; public nint Value { get => throw null; } } + [System.AttributeUsage((System.AttributeTargets)1024, Inherited = false)] public sealed class CoClassAttribute : System.Attribute { public System.Type CoClass { get => throw null; } @@ -151,6 +158,7 @@ public static class CollectionsMarshal public static TValue GetValueRefOrAddDefault(System.Collections.Generic.Dictionary dictionary, TKey key, out bool exists) => throw null; public static TValue GetValueRefOrNullRef(System.Collections.Generic.Dictionary dictionary, TKey key) => throw null; } + [System.AttributeUsage((System.AttributeTargets)10624, Inherited = false)] public sealed class ComAliasNameAttribute : System.Attribute { public ComAliasNameAttribute(string alias) => throw null; @@ -176,6 +184,7 @@ public class ComAwareEventInfo : System.Reflection.EventInfo public override System.Type ReflectedType { get => throw null; } public override void RemoveEventHandler(object target, System.Delegate handler) => throw null; } + [System.AttributeUsage((System.AttributeTargets)1, Inherited = false)] public sealed class ComCompatibleVersionAttribute : System.Attribute { public int BuildNumber { get => throw null; } @@ -184,15 +193,18 @@ public sealed class ComCompatibleVersionAttribute : System.Attribute public int MinorVersion { get => throw null; } public int RevisionNumber { get => throw null; } } + [System.AttributeUsage((System.AttributeTargets)32767, Inherited = false)] public sealed class ComConversionLossAttribute : System.Attribute { public ComConversionLossAttribute() => throw null; } + [System.AttributeUsage((System.AttributeTargets)4, Inherited = false)] public sealed class ComDefaultInterfaceAttribute : System.Attribute { public ComDefaultInterfaceAttribute(System.Type defaultInterface) => throw null; public System.Type Value { get => throw null; } } + [System.AttributeUsage((System.AttributeTargets)1024, Inherited = false)] public sealed class ComEventInterfaceAttribute : System.Attribute { public ComEventInterfaceAttribute(System.Type SourceInterface, System.Type EventProvider) => throw null; @@ -213,6 +225,7 @@ public class COMException : System.Runtime.InteropServices.ExternalException public COMException(string message, int errorCode) => throw null; public override string ToString() => throw null; } + [System.AttributeUsage((System.AttributeTargets)1028, Inherited = false)] public sealed class ComImportAttribute : System.Attribute { public ComImportAttribute() => throw null; @@ -230,10 +243,12 @@ public enum ComMemberType PropGet = 1, PropSet = 2, } + [System.AttributeUsage((System.AttributeTargets)64, Inherited = false)] public sealed class ComRegisterFunctionAttribute : System.Attribute { public ComRegisterFunctionAttribute() => throw null; } + [System.AttributeUsage((System.AttributeTargets)4, Inherited = true)] public sealed class ComSourceInterfacesAttribute : System.Attribute { public ComSourceInterfacesAttribute(string sourceInterfaces) => throw null; @@ -843,6 +858,7 @@ public enum VARKIND VAR_DISPATCH = 3, } } + [System.AttributeUsage((System.AttributeTargets)64, Inherited = false)] public sealed class ComUnregisterFunctionAttribute : System.Attribute { public ComUnregisterFunctionAttribute() => throw null; @@ -914,16 +930,19 @@ public enum CustomQueryInterfaceResult NotHandled = 1, Failed = 2, } + [System.AttributeUsage((System.AttributeTargets)2, Inherited = false)] public sealed class DefaultCharSetAttribute : System.Attribute { public System.Runtime.InteropServices.CharSet CharSet { get => throw null; } public DefaultCharSetAttribute(System.Runtime.InteropServices.CharSet charSet) => throw null; } + [System.AttributeUsage((System.AttributeTargets)65, AllowMultiple = false)] public sealed class DefaultDllImportSearchPathsAttribute : System.Attribute { public DefaultDllImportSearchPathsAttribute(System.Runtime.InteropServices.DllImportSearchPath paths) => throw null; public System.Runtime.InteropServices.DllImportSearchPath Paths { get => throw null; } } + [System.AttributeUsage((System.AttributeTargets)2048)] public sealed class DefaultParameterValueAttribute : System.Attribute { public DefaultParameterValueAttribute(object value) => throw null; @@ -934,11 +953,13 @@ public sealed class DispatchWrapper public DispatchWrapper(object obj) => throw null; public object WrappedObject { get => throw null; } } + [System.AttributeUsage((System.AttributeTargets)960, Inherited = false)] public sealed class DispIdAttribute : System.Attribute { public DispIdAttribute(int dispId) => throw null; public int Value { get => throw null; } } + [System.AttributeUsage((System.AttributeTargets)64, Inherited = false)] public sealed class DllImportAttribute : System.Attribute { public bool BestFitMapping; @@ -964,6 +985,7 @@ public enum DllImportSearchPath System32 = 2048, SafeDirectories = 4096, } + [System.AttributeUsage((System.AttributeTargets)1024, AllowMultiple = false, Inherited = false)] public sealed class DynamicInterfaceCastableImplementationAttribute : System.Attribute { public DynamicInterfaceCastableImplementationAttribute() => throw null; @@ -975,6 +997,7 @@ public sealed class ErrorWrapper public ErrorWrapper(object errorCode) => throw null; public int ErrorCode { get => throw null; } } + [System.AttributeUsage((System.AttributeTargets)5149, Inherited = false)] public sealed class GuidAttribute : System.Attribute { public GuidAttribute(string guid) => throw null; @@ -1024,11 +1047,13 @@ public interface IDynamicInterfaceCastable System.RuntimeTypeHandle GetInterfaceImplementation(System.RuntimeTypeHandle interfaceType); bool IsInterfaceImplemented(System.RuntimeTypeHandle interfaceType, bool throwIfNotImplemented); } + [System.AttributeUsage((System.AttributeTargets)1, Inherited = false)] public sealed class ImportedFromTypeLibAttribute : System.Attribute { public ImportedFromTypeLibAttribute(string tlbFile) => throw null; public string Value { get => throw null; } } + [System.AttributeUsage((System.AttributeTargets)1024, Inherited = false)] public sealed class InterfaceTypeAttribute : System.Attribute { public InterfaceTypeAttribute(short interfaceType) => throw null; @@ -1049,11 +1074,13 @@ public class InvalidOleVariantTypeException : System.SystemException public InvalidOleVariantTypeException(string message) => throw null; public InvalidOleVariantTypeException(string message, System.Exception inner) => throw null; } + [System.AttributeUsage((System.AttributeTargets)64, Inherited = false)] public sealed class LCIDConversionAttribute : System.Attribute { public LCIDConversionAttribute(int lcid) => throw null; public int Value { get => throw null; } } + [System.AttributeUsage((System.AttributeTargets)64, AllowMultiple = false, Inherited = false)] public sealed class LibraryImportAttribute : System.Attribute { public LibraryImportAttribute(string libraryName) => throw null; @@ -1063,6 +1090,7 @@ public sealed class LibraryImportAttribute : System.Attribute public System.Runtime.InteropServices.StringMarshalling StringMarshalling { get => throw null; set { } } public System.Type StringMarshallingCustomType { get => throw null; set { } } } + [System.AttributeUsage((System.AttributeTargets)64, Inherited = false, AllowMultiple = false)] public sealed class ManagedToNativeComInteropStubAttribute : System.Attribute { public System.Type ClassType { get => throw null; } @@ -1235,6 +1263,7 @@ public static class Marshal public static void ZeroFreeGlobalAllocAnsi(nint s) => throw null; public static void ZeroFreeGlobalAllocUnicode(nint s) => throw null; } + [System.AttributeUsage((System.AttributeTargets)10496, Inherited = false)] public sealed class MarshalAsAttribute : System.Attribute { public System.Runtime.InteropServices.UnmanagedType ArraySubType; @@ -1306,6 +1335,7 @@ public struct ManagedToUnmanagedIn public unsafe ushort* ToUnmanaged() => throw null; } } + [System.AttributeUsage((System.AttributeTargets)10240, AllowMultiple = true)] public sealed class MarshalUsingAttribute : System.Attribute { public int ConstantElementCount { get => throw null; set { } } @@ -1625,11 +1655,13 @@ public enum MessageSendFunction public static void SetMessageSendPendingException(System.Exception exception) => throw null; public unsafe delegate delegate* unmanaged UnhandledExceptionPropagationHandler(System.Exception exception, System.RuntimeMethodHandle lastMethod, out nint context); } + [System.AttributeUsage((System.AttributeTargets)4, Inherited = true, AllowMultiple = false)] public sealed class ObjectiveCTrackedTypeAttribute : System.Attribute { public ObjectiveCTrackedTypeAttribute() => throw null; } } + [System.AttributeUsage((System.AttributeTargets)2048, Inherited = false)] public sealed class OptionalAttribute : System.Attribute { public OptionalAttribute() => throw null; @@ -1658,16 +1690,19 @@ public sealed class PosixSignalRegistration : System.IDisposable public static System.Runtime.InteropServices.PosixSignalRegistration Create(System.Runtime.InteropServices.PosixSignal signal, System.Action handler) => throw null; public void Dispose() => throw null; } + [System.AttributeUsage((System.AttributeTargets)64, Inherited = false)] public sealed class PreserveSigAttribute : System.Attribute { public PreserveSigAttribute() => throw null; } + [System.AttributeUsage((System.AttributeTargets)1, Inherited = false, AllowMultiple = true)] public sealed class PrimaryInteropAssemblyAttribute : System.Attribute { public PrimaryInteropAssemblyAttribute(int major, int minor) => throw null; public int MajorVersion { get => throw null; } public int MinorVersion { get => throw null; } } + [System.AttributeUsage((System.AttributeTargets)4, Inherited = false)] public sealed class ProgIdAttribute : System.Attribute { public ProgIdAttribute(string progId) => throw null; @@ -1714,6 +1749,7 @@ public enum StringMarshalling Utf8 = 1, Utf16 = 2, } + [System.AttributeUsage((System.AttributeTargets)5144, AllowMultiple = false, Inherited = false)] public sealed class TypeIdentifierAttribute : System.Attribute { public TypeIdentifierAttribute() => throw null; @@ -1721,6 +1757,7 @@ public sealed class TypeIdentifierAttribute : System.Attribute public string Identifier { get => throw null; } public string Scope { get => throw null; } } + [System.AttributeUsage((System.AttributeTargets)64, Inherited = false)] public sealed class TypeLibFuncAttribute : System.Attribute { public TypeLibFuncAttribute(short flags) => throw null; @@ -1744,11 +1781,13 @@ public enum TypeLibFuncFlags FReplaceable = 2048, FImmediateBind = 4096, } + [System.AttributeUsage((System.AttributeTargets)1024, Inherited = false)] public sealed class TypeLibImportClassAttribute : System.Attribute { public TypeLibImportClassAttribute(System.Type importClass) => throw null; public string Value { get => throw null; } } + [System.AttributeUsage((System.AttributeTargets)1052, Inherited = false)] public sealed class TypeLibTypeAttribute : System.Attribute { public TypeLibTypeAttribute(short flags) => throw null; @@ -1773,6 +1812,7 @@ public enum TypeLibTypeFlags FDispatchable = 4096, FReverseBind = 8192, } + [System.AttributeUsage((System.AttributeTargets)256, Inherited = false)] public sealed class TypeLibVarAttribute : System.Attribute { public TypeLibVarAttribute(short flags) => throw null; @@ -1796,6 +1836,7 @@ public enum TypeLibVarFlags FReplaceable = 2048, FImmediateBind = 4096, } + [System.AttributeUsage((System.AttributeTargets)1, Inherited = false)] public sealed class TypeLibVersionAttribute : System.Attribute { public TypeLibVersionAttribute(int major, int minor) => throw null; @@ -1807,17 +1848,20 @@ public sealed class UnknownWrapper public UnknownWrapper(object obj) => throw null; public object WrappedObject { get => throw null; } } + [System.AttributeUsage((System.AttributeTargets)64, AllowMultiple = false, Inherited = false)] public sealed class UnmanagedCallConvAttribute : System.Attribute { public System.Type[] CallConvs; public UnmanagedCallConvAttribute() => throw null; } + [System.AttributeUsage((System.AttributeTargets)64, Inherited = false)] public sealed class UnmanagedCallersOnlyAttribute : System.Attribute { public System.Type[] CallConvs; public UnmanagedCallersOnlyAttribute() => throw null; public string EntryPoint; } + [System.AttributeUsage((System.AttributeTargets)4096, AllowMultiple = false, Inherited = false)] public sealed class UnmanagedFunctionPointerAttribute : System.Attribute { public bool BestFitMapping; diff --git a/csharp/ql/test/resources/stubs/_frameworks/Microsoft.NETCore.App/System.Runtime.Loader.cs b/csharp/ql/test/resources/stubs/_frameworks/Microsoft.NETCore.App/System.Runtime.Loader.cs index eb7dc133afd7..02ba58c70c7b 100644 --- a/csharp/ql/test/resources/stubs/_frameworks/Microsoft.NETCore.App/System.Runtime.Loader.cs +++ b/csharp/ql/test/resources/stubs/_frameworks/Microsoft.NETCore.App/System.Runtime.Loader.cs @@ -10,6 +10,7 @@ public static partial class AssemblyExtensions { public static unsafe bool TryGetRawMetadata(this System.Reflection.Assembly assembly, out byte* blob, out int length) => throw null; } + [System.AttributeUsage((System.AttributeTargets)1, AllowMultiple = true)] public sealed class MetadataUpdateHandlerAttribute : System.Attribute { public MetadataUpdateHandlerAttribute(System.Type handlerType) => throw null; @@ -26,10 +27,12 @@ namespace Runtime { namespace CompilerServices { + [System.AttributeUsage((System.AttributeTargets)12, AllowMultiple = false)] public sealed class CreateNewOnMetadataUpdateAttribute : System.Attribute { public CreateNewOnMetadataUpdateAttribute() => throw null; } + [System.AttributeUsage((System.AttributeTargets)12, AllowMultiple = false, Inherited = false)] public class MetadataUpdateOriginalTypeAttribute : System.Attribute { public MetadataUpdateOriginalTypeAttribute(System.Type originalType) => throw null; diff --git a/csharp/ql/test/resources/stubs/_frameworks/Microsoft.NETCore.App/System.Runtime.Serialization.Primitives.cs b/csharp/ql/test/resources/stubs/_frameworks/Microsoft.NETCore.App/System.Runtime.Serialization.Primitives.cs index a03bf2aa7fca..5cb8f373c288 100644 --- a/csharp/ql/test/resources/stubs/_frameworks/Microsoft.NETCore.App/System.Runtime.Serialization.Primitives.cs +++ b/csharp/ql/test/resources/stubs/_frameworks/Microsoft.NETCore.App/System.Runtime.Serialization.Primitives.cs @@ -6,6 +6,7 @@ namespace Runtime { namespace Serialization { + [System.AttributeUsage((System.AttributeTargets)12, Inherited = false, AllowMultiple = false)] public sealed class CollectionDataContractAttribute : System.Attribute { public CollectionDataContractAttribute() => throw null; @@ -22,12 +23,14 @@ public sealed class CollectionDataContractAttribute : System.Attribute public string Namespace { get => throw null; set { } } public string ValueName { get => throw null; set { } } } + [System.AttributeUsage((System.AttributeTargets)3, Inherited = false, AllowMultiple = true)] public sealed class ContractNamespaceAttribute : System.Attribute { public string ClrNamespace { get => throw null; set { } } public string ContractNamespace { get => throw null; } public ContractNamespaceAttribute(string contractNamespace) => throw null; } + [System.AttributeUsage((System.AttributeTargets)28, Inherited = false, AllowMultiple = false)] public sealed class DataContractAttribute : System.Attribute { public DataContractAttribute() => throw null; @@ -38,6 +41,7 @@ public sealed class DataContractAttribute : System.Attribute public string Name { get => throw null; set { } } public string Namespace { get => throw null; set { } } } + [System.AttributeUsage((System.AttributeTargets)384, Inherited = false, AllowMultiple = false)] public sealed class DataMemberAttribute : System.Attribute { public DataMemberAttribute() => throw null; @@ -47,12 +51,14 @@ public sealed class DataMemberAttribute : System.Attribute public string Name { get => throw null; set { } } public int Order { get => throw null; set { } } } + [System.AttributeUsage((System.AttributeTargets)256, Inherited = false, AllowMultiple = false)] public sealed class EnumMemberAttribute : System.Attribute { public EnumMemberAttribute() => throw null; public bool IsValueSetExplicitly { get => throw null; } public string Value { get => throw null; set { } } } + [System.AttributeUsage((System.AttributeTargets)384, Inherited = false, AllowMultiple = false)] public sealed class IgnoreDataMemberAttribute : System.Attribute { public IgnoreDataMemberAttribute() => throw null; @@ -77,6 +83,7 @@ public interface ISerializationSurrogateProvider2 : System.Runtime.Serialization void GetKnownCustomDataTypes(System.Collections.ObjectModel.Collection customDataTypes); System.Type GetReferencedTypeOnImport(string typeName, string typeNamespace, object customData); } + [System.AttributeUsage((System.AttributeTargets)12, Inherited = true, AllowMultiple = true)] public sealed class KnownTypeAttribute : System.Attribute { public KnownTypeAttribute(string methodName) => throw null; diff --git a/csharp/ql/test/resources/stubs/_frameworks/Microsoft.NETCore.App/System.Runtime.cs b/csharp/ql/test/resources/stubs/_frameworks/Microsoft.NETCore.App/System.Runtime.cs index c1bd5c8846cf..d399e0ae98ed 100644 --- a/csharp/ql/test/resources/stubs/_frameworks/Microsoft.NETCore.App/System.Runtime.cs +++ b/csharp/ql/test/resources/stubs/_frameworks/Microsoft.NETCore.App/System.Runtime.cs @@ -446,6 +446,7 @@ public class AssemblyLoadEventArgs : System.EventArgs } public delegate void AssemblyLoadEventHandler(object sender, System.AssemblyLoadEventArgs args); public delegate void AsyncCallback(System.IAsyncResult ar); + [System.AttributeUsage((System.AttributeTargets)32767, Inherited = true, AllowMultiple = false)] public abstract class Attribute { protected Attribute() => throw null; @@ -507,6 +508,7 @@ public enum AttributeTargets GenericParameter = 16384, All = 32767, } + [System.AttributeUsage((System.AttributeTargets)4, Inherited = true)] public sealed class AttributeUsageAttribute : System.Attribute { public bool AllowMultiple { get => throw null; set { } } @@ -1018,6 +1020,7 @@ public sealed class CharEnumerator : System.ICloneable, System.IDisposable, Syst public bool MoveNext() => throw null; public void Reset() => throw null; } + [System.AttributeUsage((System.AttributeTargets)32767, Inherited = true, AllowMultiple = false)] public sealed class CLSCompliantAttribute : System.Attribute { public CLSCompliantAttribute(bool isCompliant) => throw null; @@ -1027,6 +1030,7 @@ namespace CodeDom { namespace Compiler { + [System.AttributeUsage((System.AttributeTargets)32767, Inherited = false, AllowMultiple = false)] public sealed class GeneratedCodeAttribute : System.Attribute { public GeneratedCodeAttribute(string tool, string version) => throw null; @@ -1537,6 +1541,7 @@ public sealed class ValueCollection : System.Collections.Generic.ICollection(T x, T y); namespace ComponentModel { + [System.AttributeUsage((System.AttributeTargets)32767)] public class DefaultValueAttribute : System.Attribute { public DefaultValueAttribute(bool value) => throw null; @@ -1559,6 +1564,7 @@ public class DefaultValueAttribute : System.Attribute protected void SetValue(object value) => throw null; public virtual object Value { get => throw null; } } + [System.AttributeUsage((System.AttributeTargets)6140)] public sealed class EditorBrowsableAttribute : System.Attribute { public EditorBrowsableAttribute() => throw null; @@ -1606,6 +1612,7 @@ public class ContextMarshalException : System.SystemException public ContextMarshalException(string message) => throw null; public ContextMarshalException(string message, System.Exception inner) => throw null; } + [System.AttributeUsage((System.AttributeTargets)256, Inherited = false)] public class ContextStaticAttribute : System.Attribute { public ContextStaticAttribute() => throw null; @@ -2488,29 +2495,35 @@ namespace Diagnostics { namespace CodeAnalysis { + [System.AttributeUsage((System.AttributeTargets)2432, Inherited = false)] public sealed class AllowNullAttribute : System.Attribute { public AllowNullAttribute() => throw null; } + [System.AttributeUsage((System.AttributeTargets)2048, Inherited = false)] public sealed class ConstantExpectedAttribute : System.Attribute { public ConstantExpectedAttribute() => throw null; public object Max { get => throw null; set { } } public object Min { get => throw null; set { } } } + [System.AttributeUsage((System.AttributeTargets)2432, Inherited = false)] public sealed class DisallowNullAttribute : System.Attribute { public DisallowNullAttribute() => throw null; } + [System.AttributeUsage((System.AttributeTargets)64, Inherited = false)] public sealed class DoesNotReturnAttribute : System.Attribute { public DoesNotReturnAttribute() => throw null; } + [System.AttributeUsage((System.AttributeTargets)2048, Inherited = false)] public sealed class DoesNotReturnIfAttribute : System.Attribute { public DoesNotReturnIfAttribute(bool parameterValue) => throw null; public bool ParameterValue { get => throw null; } } + [System.AttributeUsage((System.AttributeTargets)28108, Inherited = false)] public sealed class DynamicallyAccessedMembersAttribute : System.Attribute { public DynamicallyAccessedMembersAttribute(System.Diagnostics.CodeAnalysis.DynamicallyAccessedMemberTypes memberTypes) => throw null; @@ -2536,6 +2549,7 @@ public enum DynamicallyAccessedMemberTypes NonPublicEvents = 4096, Interfaces = 8192, } + [System.AttributeUsage((System.AttributeTargets)352, AllowMultiple = true, Inherited = false)] public sealed class DynamicDependencyAttribute : System.Attribute { public string AssemblyName { get => throw null; } @@ -2550,26 +2564,31 @@ public sealed class DynamicDependencyAttribute : System.Attribute public System.Type Type { get => throw null; } public string TypeName { get => throw null; } } + [System.AttributeUsage((System.AttributeTargets)749, Inherited = false, AllowMultiple = false)] public sealed class ExcludeFromCodeCoverageAttribute : System.Attribute { public ExcludeFromCodeCoverageAttribute() => throw null; public string Justification { get => throw null; set { } } } + [System.AttributeUsage((System.AttributeTargets)10624, Inherited = false)] public sealed class MaybeNullAttribute : System.Attribute { public MaybeNullAttribute() => throw null; } + [System.AttributeUsage((System.AttributeTargets)2048, Inherited = false)] public sealed class MaybeNullWhenAttribute : System.Attribute { public MaybeNullWhenAttribute(bool returnValue) => throw null; public bool ReturnValue { get => throw null; } } + [System.AttributeUsage((System.AttributeTargets)192, Inherited = false, AllowMultiple = true)] public sealed class MemberNotNullAttribute : System.Attribute { public MemberNotNullAttribute(string member) => throw null; public MemberNotNullAttribute(params string[] members) => throw null; public string[] Members { get => throw null; } } + [System.AttributeUsage((System.AttributeTargets)192, Inherited = false, AllowMultiple = true)] public sealed class MemberNotNullWhenAttribute : System.Attribute { public MemberNotNullWhenAttribute(bool returnValue, string member) => throw null; @@ -2577,20 +2596,24 @@ public sealed class MemberNotNullWhenAttribute : System.Attribute public string[] Members { get => throw null; } public bool ReturnValue { get => throw null; } } + [System.AttributeUsage((System.AttributeTargets)10624, Inherited = false)] public sealed class NotNullAttribute : System.Attribute { public NotNullAttribute() => throw null; } + [System.AttributeUsage((System.AttributeTargets)10368, AllowMultiple = true, Inherited = false)] public sealed class NotNullIfNotNullAttribute : System.Attribute { public NotNullIfNotNullAttribute(string parameterName) => throw null; public string ParameterName { get => throw null; } } + [System.AttributeUsage((System.AttributeTargets)2048, Inherited = false)] public sealed class NotNullWhenAttribute : System.Attribute { public NotNullWhenAttribute(bool returnValue) => throw null; public bool ReturnValue { get => throw null; } } + [System.AttributeUsage((System.AttributeTargets)736, Inherited = false, AllowMultiple = false)] public sealed class RequiresAssemblyFilesAttribute : System.Attribute { public RequiresAssemblyFilesAttribute() => throw null; @@ -2598,22 +2621,26 @@ public sealed class RequiresAssemblyFilesAttribute : System.Attribute public string Message { get => throw null; } public string Url { get => throw null; set { } } } + [System.AttributeUsage((System.AttributeTargets)100, Inherited = false)] public sealed class RequiresDynamicCodeAttribute : System.Attribute { public RequiresDynamicCodeAttribute(string message) => throw null; public string Message { get => throw null; } public string Url { get => throw null; set { } } } + [System.AttributeUsage((System.AttributeTargets)100, Inherited = false)] public sealed class RequiresUnreferencedCodeAttribute : System.Attribute { public RequiresUnreferencedCodeAttribute(string message) => throw null; public string Message { get => throw null; } public string Url { get => throw null; set { } } } + [System.AttributeUsage((System.AttributeTargets)32, AllowMultiple = false, Inherited = false)] public sealed class SetsRequiredMembersAttribute : System.Attribute { public SetsRequiredMembersAttribute() => throw null; } + [System.AttributeUsage((System.AttributeTargets)2432, AllowMultiple = false, Inherited = false)] public sealed class StringSyntaxAttribute : System.Attribute { public object[] Arguments { get => throw null; } @@ -2633,6 +2660,7 @@ public sealed class StringSyntaxAttribute : System.Attribute public const string Uri = default; public const string Xml = default; } + [System.AttributeUsage((System.AttributeTargets)32767, Inherited = false, AllowMultiple = true)] public sealed class SuppressMessageAttribute : System.Attribute { public string Category { get => throw null; } @@ -2643,6 +2671,7 @@ public sealed class SuppressMessageAttribute : System.Attribute public string Scope { get => throw null; set { } } public string Target { get => throw null; set { } } } + [System.AttributeUsage((System.AttributeTargets)32767, Inherited = false, AllowMultiple = true)] public sealed class UnconditionalSuppressMessageAttribute : System.Attribute { public string Category { get => throw null; } @@ -2653,11 +2682,13 @@ public sealed class UnconditionalSuppressMessageAttribute : System.Attribute public string Scope { get => throw null; set { } } public string Target { get => throw null; set { } } } + [System.AttributeUsage((System.AttributeTargets)2240, AllowMultiple = false, Inherited = false)] public sealed class UnscopedRefAttribute : System.Attribute { public UnscopedRefAttribute() => throw null; } } + [System.AttributeUsage((System.AttributeTargets)68, AllowMultiple = true)] public sealed class ConditionalAttribute : System.Attribute { public string ConditionString { get => throw null; } @@ -2732,6 +2763,7 @@ public struct WriteIfInterpolatedStringHandler public static void WriteLineIf(bool condition, string message) => throw null; public static void WriteLineIf(bool condition, string message, string category) => throw null; } + [System.AttributeUsage((System.AttributeTargets)3, AllowMultiple = false)] public sealed class DebuggableAttribute : System.Attribute { public DebuggableAttribute(bool isJITTrackingEnabled, bool isJITOptimizerDisabled) => throw null; @@ -2759,6 +2791,7 @@ public static class Debugger public static void Log(int level, string category, string message) => throw null; public static void NotifyOfCrossThreadDependency() => throw null; } + [System.AttributeUsage((System.AttributeTargets)384, AllowMultiple = false)] public sealed class DebuggerBrowsableAttribute : System.Attribute { public DebuggerBrowsableAttribute(System.Diagnostics.DebuggerBrowsableState state) => throw null; @@ -2770,6 +2803,7 @@ public enum DebuggerBrowsableState Collapsed = 2, RootHidden = 3, } + [System.AttributeUsage((System.AttributeTargets)4509, AllowMultiple = true)] public sealed class DebuggerDisplayAttribute : System.Attribute { public DebuggerDisplayAttribute(string value) => throw null; @@ -2779,22 +2813,27 @@ public sealed class DebuggerDisplayAttribute : System.Attribute public string Type { get => throw null; set { } } public string Value { get => throw null; } } + [System.AttributeUsage((System.AttributeTargets)224, Inherited = false)] public sealed class DebuggerHiddenAttribute : System.Attribute { public DebuggerHiddenAttribute() => throw null; } + [System.AttributeUsage((System.AttributeTargets)236, Inherited = false)] public sealed class DebuggerNonUserCodeAttribute : System.Attribute { public DebuggerNonUserCodeAttribute() => throw null; } + [System.AttributeUsage((System.AttributeTargets)96, Inherited = false)] public sealed class DebuggerStepperBoundaryAttribute : System.Attribute { public DebuggerStepperBoundaryAttribute() => throw null; } + [System.AttributeUsage((System.AttributeTargets)108, Inherited = false)] public sealed class DebuggerStepThroughAttribute : System.Attribute { public DebuggerStepThroughAttribute() => throw null; } + [System.AttributeUsage((System.AttributeTargets)13, AllowMultiple = true)] public sealed class DebuggerTypeProxyAttribute : System.Attribute { public DebuggerTypeProxyAttribute(string typeName) => throw null; @@ -2803,6 +2842,7 @@ public sealed class DebuggerTypeProxyAttribute : System.Attribute public System.Type Target { get => throw null; set { } } public string TargetTypeName { get => throw null; set { } } } + [System.AttributeUsage((System.AttributeTargets)13, AllowMultiple = true)] public sealed class DebuggerVisualizerAttribute : System.Attribute { public DebuggerVisualizerAttribute(string visualizerTypeName) => throw null; @@ -2817,6 +2857,7 @@ public sealed class DebuggerVisualizerAttribute : System.Attribute public string VisualizerObjectSourceTypeName { get => throw null; } public string VisualizerTypeName { get => throw null; } } + [System.AttributeUsage((System.AttributeTargets)108, Inherited = false)] public sealed class StackTraceHiddenAttribute : System.Attribute { public StackTraceHiddenAttribute() => throw null; @@ -3269,6 +3310,7 @@ public class FileStyleUriParser : System.UriParser { public FileStyleUriParser() => throw null; } + [System.AttributeUsage((System.AttributeTargets)16, Inherited = false)] public class FlagsAttribute : System.Attribute { public FlagsAttribute() => throw null; @@ -6528,6 +6570,7 @@ public enum LoaderOptimization MultiDomainHost = 3, DisallowBindings = 4, } + [System.AttributeUsage((System.AttributeTargets)64)] public sealed class LoaderOptimizationAttribute : System.Attribute { public LoaderOptimizationAttribute(byte value) => throw null; @@ -6808,6 +6851,7 @@ public struct ModuleHandle : System.IEquatable public System.RuntimeTypeHandle ResolveTypeHandle(int typeToken) => throw null; public System.RuntimeTypeHandle ResolveTypeHandle(int typeToken, System.RuntimeTypeHandle[] typeInstantiationContext, System.RuntimeTypeHandle[] methodInstantiationContext) => throw null; } + [System.AttributeUsage((System.AttributeTargets)64)] public sealed class MTAThreadAttribute : System.Attribute { public MTAThreadAttribute() => throw null; @@ -6858,6 +6902,7 @@ public class NewsStyleUriParser : System.UriParser { public NewsStyleUriParser() => throw null; } + [System.AttributeUsage((System.AttributeTargets)256, Inherited = false)] public sealed class NonSerializedAttribute : System.Attribute { public NonSerializedAttribute() => throw null; @@ -7259,6 +7304,7 @@ public class ObjectDisposedException : System.InvalidOperationException public static void ThrowIf(bool condition, object instance) => throw null; public static void ThrowIf(bool condition, System.Type type) => throw null; } + [System.AttributeUsage((System.AttributeTargets)6140, Inherited = false)] public sealed class ObsoleteAttribute : System.Attribute { public ObsoleteAttribute() => throw null; @@ -7325,6 +7371,7 @@ public class OverflowException : System.ArithmeticException public OverflowException(string message) => throw null; public OverflowException(string message, System.Exception innerException) => throw null; } + [System.AttributeUsage((System.AttributeTargets)2048, Inherited = true, AllowMultiple = false)] public sealed class ParamArrayAttribute : System.Attribute { public ParamArrayAttribute() => throw null; @@ -7531,17 +7578,20 @@ public abstract class Assembly : System.Reflection.ICustomAttributeProvider, Sys public override string ToString() => throw null; public static System.Reflection.Assembly UnsafeLoadFrom(string assemblyFile) => throw null; } + [System.AttributeUsage((System.AttributeTargets)1, Inherited = false)] public sealed class AssemblyAlgorithmIdAttribute : System.Attribute { public uint AlgorithmId { get => throw null; } public AssemblyAlgorithmIdAttribute(System.Configuration.Assemblies.AssemblyHashAlgorithm algorithmId) => throw null; public AssemblyAlgorithmIdAttribute(uint algorithmId) => throw null; } + [System.AttributeUsage((System.AttributeTargets)1, Inherited = false)] public sealed class AssemblyCompanyAttribute : System.Attribute { public string Company { get => throw null; } public AssemblyCompanyAttribute(string company) => throw null; } + [System.AttributeUsage((System.AttributeTargets)1, Inherited = false)] public sealed class AssemblyConfigurationAttribute : System.Attribute { public string Configuration { get => throw null; } @@ -7552,36 +7602,43 @@ public enum AssemblyContentType Default = 0, WindowsRuntime = 1, } + [System.AttributeUsage((System.AttributeTargets)1, Inherited = false)] public sealed class AssemblyCopyrightAttribute : System.Attribute { public string Copyright { get => throw null; } public AssemblyCopyrightAttribute(string copyright) => throw null; } + [System.AttributeUsage((System.AttributeTargets)1, Inherited = false)] public sealed class AssemblyCultureAttribute : System.Attribute { public AssemblyCultureAttribute(string culture) => throw null; public string Culture { get => throw null; } } + [System.AttributeUsage((System.AttributeTargets)1, Inherited = false)] public sealed class AssemblyDefaultAliasAttribute : System.Attribute { public AssemblyDefaultAliasAttribute(string defaultAlias) => throw null; public string DefaultAlias { get => throw null; } } + [System.AttributeUsage((System.AttributeTargets)1, Inherited = false)] public sealed class AssemblyDelaySignAttribute : System.Attribute { public AssemblyDelaySignAttribute(bool delaySign) => throw null; public bool DelaySign { get => throw null; } } + [System.AttributeUsage((System.AttributeTargets)1, Inherited = false)] public sealed class AssemblyDescriptionAttribute : System.Attribute { public AssemblyDescriptionAttribute(string description) => throw null; public string Description { get => throw null; } } + [System.AttributeUsage((System.AttributeTargets)1, Inherited = false)] public sealed class AssemblyFileVersionAttribute : System.Attribute { public AssemblyFileVersionAttribute(string version) => throw null; public string Version { get => throw null; } } + [System.AttributeUsage((System.AttributeTargets)1, Inherited = false)] public sealed class AssemblyFlagsAttribute : System.Attribute { public int AssemblyFlags { get => throw null; } @@ -7590,21 +7647,25 @@ public sealed class AssemblyFlagsAttribute : System.Attribute public AssemblyFlagsAttribute(uint flags) => throw null; public uint Flags { get => throw null; } } + [System.AttributeUsage((System.AttributeTargets)1, Inherited = false)] public sealed class AssemblyInformationalVersionAttribute : System.Attribute { public AssemblyInformationalVersionAttribute(string informationalVersion) => throw null; public string InformationalVersion { get => throw null; } } + [System.AttributeUsage((System.AttributeTargets)1, Inherited = false)] public sealed class AssemblyKeyFileAttribute : System.Attribute { public AssemblyKeyFileAttribute(string keyFile) => throw null; public string KeyFile { get => throw null; } } + [System.AttributeUsage((System.AttributeTargets)1, Inherited = false)] public sealed class AssemblyKeyNameAttribute : System.Attribute { public AssemblyKeyNameAttribute(string keyName) => throw null; public string KeyName { get => throw null; } } + [System.AttributeUsage((System.AttributeTargets)1, AllowMultiple = true, Inherited = false)] public sealed class AssemblyMetadataAttribute : System.Attribute { public AssemblyMetadataAttribute(string key, string value) => throw null; @@ -7653,27 +7714,32 @@ public class AssemblyNameProxy : System.MarshalByRefObject public AssemblyNameProxy() => throw null; public System.Reflection.AssemblyName GetAssemblyName(string assemblyFile) => throw null; } + [System.AttributeUsage((System.AttributeTargets)1, Inherited = false)] public sealed class AssemblyProductAttribute : System.Attribute { public AssemblyProductAttribute(string product) => throw null; public string Product { get => throw null; } } + [System.AttributeUsage((System.AttributeTargets)1, Inherited = false, AllowMultiple = false)] public sealed class AssemblySignatureKeyAttribute : System.Attribute { public string Countersignature { get => throw null; } public AssemblySignatureKeyAttribute(string publicKey, string countersignature) => throw null; public string PublicKey { get => throw null; } } + [System.AttributeUsage((System.AttributeTargets)1, Inherited = false)] public sealed class AssemblyTitleAttribute : System.Attribute { public AssemblyTitleAttribute(string title) => throw null; public string Title { get => throw null; } } + [System.AttributeUsage((System.AttributeTargets)1, Inherited = false)] public sealed class AssemblyTrademarkAttribute : System.Attribute { public AssemblyTrademarkAttribute(string trademark) => throw null; public string Trademark { get => throw null; } } + [System.AttributeUsage((System.AttributeTargets)1, Inherited = false)] public sealed class AssemblyVersionAttribute : System.Attribute { public AssemblyVersionAttribute(string version) => throw null; @@ -7825,6 +7891,7 @@ public struct CustomAttributeTypedArgument : System.IEquatable throw null; public object Value { get => throw null; } } + [System.AttributeUsage((System.AttributeTargets)1036)] public sealed class DefaultMemberAttribute : System.Attribute { public DefaultMemberAttribute(string memberName) => throw null; @@ -8255,12 +8322,14 @@ public enum NullabilityState NotNull = 1, Nullable = 2, } + [System.AttributeUsage((System.AttributeTargets)1, AllowMultiple = false, Inherited = false)] public sealed class ObfuscateAssemblyAttribute : System.Attribute { public bool AssemblyIsPrivate { get => throw null; } public ObfuscateAssemblyAttribute(bool assemblyIsPrivate) => throw null; public bool StripAfterObfuscation { get => throw null; set { } } } + [System.AttributeUsage((System.AttributeTargets)8157, AllowMultiple = true, Inherited = false)] public sealed class ObfuscationAttribute : System.Attribute { public bool ApplyToMembers { get => throw null; set { } } @@ -8615,6 +8684,7 @@ public class MissingSatelliteAssemblyException : System.SystemException public MissingSatelliteAssemblyException(string message, string cultureName) => throw null; public string CultureName { get => throw null; } } + [System.AttributeUsage((System.AttributeTargets)1, AllowMultiple = false)] public sealed class NeutralResourcesLanguageAttribute : System.Attribute { public NeutralResourcesLanguageAttribute(string cultureName) => throw null; @@ -8678,6 +8748,7 @@ public class ResourceSet : System.IDisposable, System.Collections.IEnumerable public virtual string GetString(string name, bool ignoreCase) => throw null; protected virtual void ReadResources() => throw null; } + [System.AttributeUsage((System.AttributeTargets)1, AllowMultiple = false)] public sealed class SatelliteContractVersionAttribute : System.Attribute { public SatelliteContractVersionAttribute(string version) => throw null; @@ -8697,6 +8768,7 @@ public sealed class AmbiguousImplementationException : System.Exception public AmbiguousImplementationException(string message) => throw null; public AmbiguousImplementationException(string message, System.Exception innerException) => throw null; } + [System.AttributeUsage((System.AttributeTargets)1, Inherited = false)] public sealed class AssemblyTargetedPatchBandAttribute : System.Attribute { public AssemblyTargetedPatchBandAttribute(string targetedPatchBand) => throw null; @@ -8704,6 +8776,7 @@ public sealed class AssemblyTargetedPatchBandAttribute : System.Attribute } namespace CompilerServices { + [System.AttributeUsage((System.AttributeTargets)256)] public sealed class AccessedThroughPropertyAttribute : System.Attribute { public AccessedThroughPropertyAttribute(string propertyName) => throw null; @@ -8717,15 +8790,18 @@ public struct AsyncIteratorMethodBuilder public static System.Runtime.CompilerServices.AsyncIteratorMethodBuilder Create() => throw null; public void MoveNext(ref TStateMachine stateMachine) where TStateMachine : System.Runtime.CompilerServices.IAsyncStateMachine => throw null; } + [System.AttributeUsage((System.AttributeTargets)64, Inherited = false, AllowMultiple = false)] public sealed class AsyncIteratorStateMachineAttribute : System.Runtime.CompilerServices.StateMachineAttribute { public AsyncIteratorStateMachineAttribute(System.Type stateMachineType) : base(default(System.Type)) => throw null; } + [System.AttributeUsage((System.AttributeTargets)5212, Inherited = false, AllowMultiple = false)] public sealed class AsyncMethodBuilderAttribute : System.Attribute { public System.Type BuilderType { get => throw null; } public AsyncMethodBuilderAttribute(System.Type builderType) => throw null; } + [System.AttributeUsage((System.AttributeTargets)64, Inherited = false, AllowMultiple = false)] public sealed class AsyncStateMachineAttribute : System.Runtime.CompilerServices.StateMachineAttribute { public AsyncStateMachineAttribute(System.Type stateMachineType) : base(default(System.Type)) => throw null; @@ -8808,19 +8884,23 @@ public class CallConvThiscall { public CallConvThiscall() => throw null; } + [System.AttributeUsage((System.AttributeTargets)2048, AllowMultiple = false, Inherited = false)] public sealed class CallerArgumentExpressionAttribute : System.Attribute { public CallerArgumentExpressionAttribute(string parameterName) => throw null; public string ParameterName { get => throw null; } } + [System.AttributeUsage((System.AttributeTargets)2048, Inherited = false)] public sealed class CallerFilePathAttribute : System.Attribute { public CallerFilePathAttribute() => throw null; } + [System.AttributeUsage((System.AttributeTargets)2048, Inherited = false)] public sealed class CallerLineNumberAttribute : System.Attribute { public CallerLineNumberAttribute() => throw null; } + [System.AttributeUsage((System.AttributeTargets)2048, Inherited = false)] public sealed class CallerMemberNameAttribute : System.Attribute { public CallerMemberNameAttribute() => throw null; @@ -8830,12 +8910,14 @@ public enum CompilationRelaxations { NoStringInterning = 8, } + [System.AttributeUsage((System.AttributeTargets)71)] public class CompilationRelaxationsAttribute : System.Attribute { public int CompilationRelaxations { get => throw null; } public CompilationRelaxationsAttribute(int relaxations) => throw null; public CompilationRelaxationsAttribute(System.Runtime.CompilerServices.CompilationRelaxations relaxations) => throw null; } + [System.AttributeUsage((System.AttributeTargets)32767, AllowMultiple = true, Inherited = false)] public sealed class CompilerFeatureRequiredAttribute : System.Attribute { public CompilerFeatureRequiredAttribute(string featureName) => throw null; @@ -8844,10 +8926,12 @@ public sealed class CompilerFeatureRequiredAttribute : System.Attribute public const string RefStructs = default; public const string RequiredMembers = default; } + [System.AttributeUsage((System.AttributeTargets)32767, Inherited = true)] public sealed class CompilerGeneratedAttribute : System.Attribute { public CompilerGeneratedAttribute() => throw null; } + [System.AttributeUsage((System.AttributeTargets)4)] public class CompilerGlobalScopeAttribute : System.Attribute { public CompilerGlobalScopeAttribute() => throw null; @@ -8927,22 +9011,26 @@ public struct ConfiguredValueTaskAwaiter : System.Runtime.CompilerServices.ICrit } public System.Runtime.CompilerServices.ConfiguredValueTaskAwaitable.ConfiguredValueTaskAwaiter GetAwaiter() => throw null; } + [System.AttributeUsage((System.AttributeTargets)2304, Inherited = false)] public abstract class CustomConstantAttribute : System.Attribute { protected CustomConstantAttribute() => throw null; public abstract object Value { get; } } + [System.AttributeUsage((System.AttributeTargets)2304, Inherited = false)] public sealed class DateTimeConstantAttribute : System.Runtime.CompilerServices.CustomConstantAttribute { public DateTimeConstantAttribute(long ticks) => throw null; public override object Value { get => throw null; } } + [System.AttributeUsage((System.AttributeTargets)2304, Inherited = false)] public sealed class DecimalConstantAttribute : System.Attribute { public DecimalConstantAttribute(byte scale, byte sign, int hi, int mid, int low) => throw null; public DecimalConstantAttribute(byte scale, byte sign, uint hi, uint mid, uint low) => throw null; public decimal Value { get => throw null; } } + [System.AttributeUsage((System.AttributeTargets)1)] public sealed class DefaultDependencyAttribute : System.Attribute { public DefaultDependencyAttribute(System.Runtime.CompilerServices.LoadHint loadHintArgument) => throw null; @@ -8966,36 +9054,44 @@ public struct DefaultInterpolatedStringHandler public override string ToString() => throw null; public string ToStringAndClear() => throw null; } + [System.AttributeUsage((System.AttributeTargets)1, AllowMultiple = true)] public sealed class DependencyAttribute : System.Attribute { public DependencyAttribute(string dependentAssemblyArgument, System.Runtime.CompilerServices.LoadHint loadHintArgument) => throw null; public string DependentAssembly { get => throw null; } public System.Runtime.CompilerServices.LoadHint LoadHint { get => throw null; } } + [System.AttributeUsage((System.AttributeTargets)1, AllowMultiple = false, Inherited = false)] public sealed class DisablePrivateReflectionAttribute : System.Attribute { public DisablePrivateReflectionAttribute() => throw null; } + [System.AttributeUsage((System.AttributeTargets)1, Inherited = false, AllowMultiple = false)] public sealed class DisableRuntimeMarshallingAttribute : System.Attribute { public DisableRuntimeMarshallingAttribute() => throw null; } + [System.AttributeUsage((System.AttributeTargets)32767)] public class DiscardableAttribute : System.Attribute { public DiscardableAttribute() => throw null; } + [System.AttributeUsage((System.AttributeTargets)2048, Inherited = false)] public sealed class EnumeratorCancellationAttribute : System.Attribute { public EnumeratorCancellationAttribute() => throw null; } + [System.AttributeUsage((System.AttributeTargets)69)] public sealed class ExtensionAttribute : System.Attribute { public ExtensionAttribute() => throw null; } + [System.AttributeUsage((System.AttributeTargets)256)] public sealed class FixedAddressValueTypeAttribute : System.Attribute { public FixedAddressValueTypeAttribute() => throw null; } + [System.AttributeUsage((System.AttributeTargets)256, Inherited = false)] public sealed class FixedBufferAttribute : System.Attribute { public FixedBufferAttribute(System.Type elementType, int length) => throw null; @@ -9015,6 +9111,7 @@ public interface ICriticalNotifyCompletion : System.Runtime.CompilerServices.INo { void UnsafeOnCompleted(System.Action continuation); } + [System.AttributeUsage((System.AttributeTargets)128, Inherited = true)] public sealed class IndexerNameAttribute : System.Attribute { public IndexerNameAttribute(string indexerName) => throw null; @@ -9023,22 +9120,26 @@ public interface INotifyCompletion { void OnCompleted(System.Action continuation); } + [System.AttributeUsage((System.AttributeTargets)1, AllowMultiple = true, Inherited = false)] public sealed class InternalsVisibleToAttribute : System.Attribute { public bool AllInternalsVisible { get => throw null; set { } } public string AssemblyName { get => throw null; } public InternalsVisibleToAttribute(string assemblyName) => throw null; } + [System.AttributeUsage((System.AttributeTargets)2048, AllowMultiple = false, Inherited = false)] public sealed class InterpolatedStringHandlerArgumentAttribute : System.Attribute { public string[] Arguments { get => throw null; } public InterpolatedStringHandlerArgumentAttribute(string argument) => throw null; public InterpolatedStringHandlerArgumentAttribute(params string[] arguments) => throw null; } + [System.AttributeUsage((System.AttributeTargets)12, AllowMultiple = false, Inherited = false)] public sealed class InterpolatedStringHandlerAttribute : System.Attribute { public InterpolatedStringHandlerAttribute() => throw null; } + [System.AttributeUsage((System.AttributeTargets)8)] public sealed class IsByRefLikeAttribute : System.Attribute { public IsByRefLikeAttribute() => throw null; @@ -9049,6 +9150,7 @@ public static class IsConst public static class IsExternalInit { } + [System.AttributeUsage((System.AttributeTargets)32767, Inherited = false)] public sealed class IsReadOnlyAttribute : System.Attribute { public IsReadOnlyAttribute() => throw null; @@ -9060,6 +9162,7 @@ public interface IStrongBox public static class IsVolatile { } + [System.AttributeUsage((System.AttributeTargets)64, Inherited = false, AllowMultiple = false)] public sealed class IteratorStateMachineAttribute : System.Runtime.CompilerServices.StateMachineAttribute { public IteratorStateMachineAttribute(System.Type stateMachineType) : base(default(System.Type)) => throw null; @@ -9082,6 +9185,7 @@ public enum MethodCodeType OPTIL = 2, Runtime = 3, } + [System.AttributeUsage((System.AttributeTargets)96, Inherited = false)] public sealed class MethodImplAttribute : System.Attribute { public MethodImplAttribute() => throw null; @@ -9103,6 +9207,7 @@ public enum MethodImplOptions AggressiveOptimization = 512, InternalCall = 4096, } + [System.AttributeUsage((System.AttributeTargets)64, Inherited = false)] public sealed class ModuleInitializerAttribute : System.Attribute { public ModuleInitializerAttribute() => throw null; @@ -9129,20 +9234,24 @@ public struct PoolingAsyncValueTaskMethodBuilder public void Start(ref TStateMachine stateMachine) where TStateMachine : System.Runtime.CompilerServices.IAsyncStateMachine => throw null; public System.Threading.Tasks.ValueTask Task { get => throw null; } } + [System.AttributeUsage((System.AttributeTargets)64, AllowMultiple = false, Inherited = false)] public sealed class PreserveBaseOverridesAttribute : System.Attribute { public PreserveBaseOverridesAttribute() => throw null; } + [System.AttributeUsage((System.AttributeTargets)1, AllowMultiple = false)] public sealed class ReferenceAssemblyAttribute : System.Attribute { public ReferenceAssemblyAttribute() => throw null; public ReferenceAssemblyAttribute(string description) => throw null; public string Description { get => throw null; } } + [System.AttributeUsage((System.AttributeTargets)396, AllowMultiple = false, Inherited = false)] public sealed class RequiredMemberAttribute : System.Attribute { public RequiredMemberAttribute() => throw null; } + [System.AttributeUsage((System.AttributeTargets)1, Inherited = false, AllowMultiple = false)] public sealed class RuntimeCompatibilityAttribute : System.Attribute { public RuntimeCompatibilityAttribute() => throw null; @@ -9194,19 +9303,23 @@ public sealed class RuntimeWrappedException : System.Exception public override void GetObjectData(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) => throw null; public object WrappedException { get => throw null; } } + [System.AttributeUsage((System.AttributeTargets)1774, Inherited = false)] public sealed class SkipLocalsInitAttribute : System.Attribute { public SkipLocalsInitAttribute() => throw null; } + [System.AttributeUsage((System.AttributeTargets)972)] public sealed class SpecialNameAttribute : System.Attribute { public SpecialNameAttribute() => throw null; } + [System.AttributeUsage((System.AttributeTargets)64, Inherited = false, AllowMultiple = false)] public class StateMachineAttribute : System.Attribute { public StateMachineAttribute(System.Type stateMachineType) => throw null; public System.Type StateMachineType { get => throw null; } } + [System.AttributeUsage((System.AttributeTargets)1, Inherited = false)] public sealed class StringFreezingAttribute : System.Attribute { public StringFreezingAttribute() => throw null; @@ -9218,6 +9331,7 @@ public class StrongBox : System.Runtime.CompilerServices.IStrongBox public T Value; object System.Runtime.CompilerServices.IStrongBox.Value { get => throw null; set { } } } + [System.AttributeUsage((System.AttributeTargets)3)] public sealed class SuppressIldasmAttribute : System.Attribute { public SuppressIldasmAttribute() => throw null; @@ -9247,16 +9361,19 @@ public struct TaskAwaiter : System.Runtime.CompilerServices.ICriticalNo public void OnCompleted(System.Action continuation) => throw null; public void UnsafeOnCompleted(System.Action continuation) => throw null; } + [System.AttributeUsage((System.AttributeTargets)11148)] public sealed class TupleElementNamesAttribute : System.Attribute { public TupleElementNamesAttribute(string[] transformNames) => throw null; public System.Collections.Generic.IList TransformNames { get => throw null; } } + [System.AttributeUsage((System.AttributeTargets)5148, Inherited = false, AllowMultiple = false)] public sealed class TypeForwardedFromAttribute : System.Attribute { public string AssemblyFullName { get => throw null; } public TypeForwardedFromAttribute(string assemblyFullName) => throw null; } + [System.AttributeUsage((System.AttributeTargets)1, AllowMultiple = true, Inherited = false)] public sealed class TypeForwardedToAttribute : System.Attribute { public TypeForwardedToAttribute(System.Type destination) => throw null; @@ -9307,6 +9424,7 @@ public static class Unsafe public static void WriteUnaligned(ref byte destination, T value) => throw null; public static unsafe void WriteUnaligned(void* destination, T value) => throw null; } + [System.AttributeUsage((System.AttributeTargets)8)] public sealed class UnsafeValueTypeAttribute : System.Attribute { public UnsafeValueTypeAttribute() => throw null; @@ -9356,10 +9474,12 @@ public abstract class CriticalFinalizerObject { protected CriticalFinalizerObject() => throw null; } + [System.AttributeUsage((System.AttributeTargets)96, Inherited = false)] public sealed class PrePrepareMethodAttribute : System.Attribute { public PrePrepareMethodAttribute() => throw null; } + [System.AttributeUsage((System.AttributeTargets)1133, Inherited = false)] public sealed class ReliabilityContractAttribute : System.Attribute { public System.Runtime.ConstrainedExecution.Cer Cer { get => throw null; } @@ -9396,6 +9516,7 @@ public class FirstChanceExceptionEventArgs : System.EventArgs public FirstChanceExceptionEventArgs(System.Exception exception) => throw null; public System.Exception Exception { get => throw null; } } + [System.AttributeUsage((System.AttributeTargets)64, AllowMultiple = false, Inherited = false)] public sealed class HandleProcessCorruptedStateExceptionsAttribute : System.Attribute { public HandleProcessCorruptedStateExceptionsAttribute() => throw null; @@ -9441,6 +9562,7 @@ public enum CharSet Unicode = 3, Auto = 4, } + [System.AttributeUsage((System.AttributeTargets)5597, Inherited = false)] public sealed class ComVisibleAttribute : System.Attribute { public ComVisibleAttribute(bool visibility) => throw null; @@ -9469,6 +9591,7 @@ public class ExternalException : System.SystemException public virtual int ErrorCode { get => throw null; } public override string ToString() => throw null; } + [System.AttributeUsage((System.AttributeTargets)256, Inherited = false)] public sealed class FieldOffsetAttribute : System.Attribute { public FieldOffsetAttribute(int offset) => throw null; @@ -9499,6 +9622,7 @@ public enum GCHandleType Normal = 2, Pinned = 3, } + [System.AttributeUsage((System.AttributeTargets)2048, Inherited = false)] public sealed class InAttribute : System.Attribute { public InAttribute() => throw null; @@ -9511,10 +9635,12 @@ public enum LayoutKind } namespace Marshalling { + [System.AttributeUsage((System.AttributeTargets)12)] public sealed class ContiguousCollectionMarshallerAttribute : System.Attribute { public ContiguousCollectionMarshallerAttribute() => throw null; } + [System.AttributeUsage((System.AttributeTargets)12, AllowMultiple = true)] public sealed class CustomMarshallerAttribute : System.Attribute { public CustomMarshallerAttribute(System.Type managedType, System.Runtime.InteropServices.Marshalling.MarshalMode marshalMode, System.Type marshallerType) => throw null; @@ -9538,6 +9664,7 @@ public enum MarshalMode ElementRef = 8, ElementOut = 9, } + [System.AttributeUsage((System.AttributeTargets)4124)] public sealed class NativeMarshallingAttribute : System.Attribute { public NativeMarshallingAttribute(System.Type nativeType) => throw null; @@ -9599,6 +9726,7 @@ public struct OSPlatform : System.IEquatable throw null; public static System.Runtime.InteropServices.OSPlatform Windows { get => throw null; } } + [System.AttributeUsage((System.AttributeTargets)2048, Inherited = false)] public sealed class OutAttribute : System.Attribute { public OutAttribute() => throw null; @@ -9644,6 +9772,7 @@ public abstract class SafeHandle : System.Runtime.ConstrainedExecution.CriticalF protected void SetHandle(nint handle) => throw null; public void SetHandleAsInvalid() => throw null; } + [System.AttributeUsage((System.AttributeTargets)12, Inherited = false)] public sealed class StructLayoutAttribute : System.Attribute { public System.Runtime.InteropServices.CharSet CharSet; @@ -9653,6 +9782,7 @@ public sealed class StructLayoutAttribute : System.Attribute public int Size; public System.Runtime.InteropServices.LayoutKind Value { get => throw null; } } + [System.AttributeUsage((System.AttributeTargets)64, Inherited = false)] public sealed class SuppressGCTransitionAttribute : System.Attribute { public SuppressGCTransitionAttribute() => throw null; @@ -9761,22 +9891,27 @@ public interface ISerializable { void GetObjectData(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context); } + [System.AttributeUsage((System.AttributeTargets)64, Inherited = false)] public sealed class OnDeserializedAttribute : System.Attribute { public OnDeserializedAttribute() => throw null; } + [System.AttributeUsage((System.AttributeTargets)64, Inherited = false)] public sealed class OnDeserializingAttribute : System.Attribute { public OnDeserializingAttribute() => throw null; } + [System.AttributeUsage((System.AttributeTargets)64, Inherited = false)] public sealed class OnSerializedAttribute : System.Attribute { public OnSerializedAttribute() => throw null; } + [System.AttributeUsage((System.AttributeTargets)64, Inherited = false)] public sealed class OnSerializingAttribute : System.Attribute { public OnSerializingAttribute() => throw null; } + [System.AttributeUsage((System.AttributeTargets)256, Inherited = false)] public sealed class OptionalFieldAttribute : System.Attribute { public OptionalFieldAttribute() => throw null; @@ -9878,6 +10013,7 @@ public enum StreamingContextStates All = 255, } } + [System.AttributeUsage((System.AttributeTargets)96, AllowMultiple = false, Inherited = false)] public sealed class TargetedPatchingOptOutAttribute : System.Attribute { public TargetedPatchingOptOutAttribute(string reason) => throw null; @@ -9885,6 +10021,7 @@ public sealed class TargetedPatchingOptOutAttribute : System.Attribute } namespace Versioning { + [System.AttributeUsage((System.AttributeTargets)5887, AllowMultiple = false, Inherited = false)] public sealed class ComponentGuaranteesAttribute : System.Attribute { public ComponentGuaranteesAttribute(System.Runtime.Versioning.ComponentGuaranteesOptions guarantees) => throw null; @@ -9914,6 +10051,7 @@ public sealed class FrameworkName : System.IEquatable throw null; public System.Version Version { get => throw null; } } + [System.AttributeUsage((System.AttributeTargets)2047, AllowMultiple = true, Inherited = false)] public sealed class ObsoletedOSPlatformAttribute : System.Runtime.Versioning.OSPlatformAttribute { public ObsoletedOSPlatformAttribute(string platformName) => throw null; @@ -9925,6 +10063,7 @@ public abstract class OSPlatformAttribute : System.Attribute { public string PlatformName { get => throw null; } } + [System.AttributeUsage((System.AttributeTargets)6143, Inherited = false)] public sealed class RequiresPreviewFeaturesAttribute : System.Attribute { public RequiresPreviewFeaturesAttribute() => throw null; @@ -9932,6 +10071,7 @@ public sealed class RequiresPreviewFeaturesAttribute : System.Attribute public string Message { get => throw null; } public string Url { get => throw null; set { } } } + [System.AttributeUsage((System.AttributeTargets)224, Inherited = false)] public sealed class ResourceConsumptionAttribute : System.Attribute { public System.Runtime.Versioning.ResourceScope ConsumptionScope { get => throw null; } @@ -9939,6 +10079,7 @@ public sealed class ResourceConsumptionAttribute : System.Attribute public ResourceConsumptionAttribute(System.Runtime.Versioning.ResourceScope resourceScope, System.Runtime.Versioning.ResourceScope consumptionScope) => throw null; public System.Runtime.Versioning.ResourceScope ResourceScope { get => throw null; } } + [System.AttributeUsage((System.AttributeTargets)480, Inherited = false)] public sealed class ResourceExposureAttribute : System.Attribute { public ResourceExposureAttribute(System.Runtime.Versioning.ResourceScope exposureLevel) => throw null; @@ -9955,30 +10096,36 @@ public enum ResourceScope Private = 16, Assembly = 32, } + [System.AttributeUsage((System.AttributeTargets)2047, AllowMultiple = true, Inherited = false)] public sealed class SupportedOSPlatformAttribute : System.Runtime.Versioning.OSPlatformAttribute { public SupportedOSPlatformAttribute(string platformName) => throw null; } + [System.AttributeUsage((System.AttributeTargets)448, AllowMultiple = true, Inherited = false)] public sealed class SupportedOSPlatformGuardAttribute : System.Runtime.Versioning.OSPlatformAttribute { public SupportedOSPlatformGuardAttribute(string platformName) => throw null; } + [System.AttributeUsage((System.AttributeTargets)1, AllowMultiple = false, Inherited = false)] public sealed class TargetFrameworkAttribute : System.Attribute { public TargetFrameworkAttribute(string frameworkName) => throw null; public string FrameworkDisplayName { get => throw null; set { } } public string FrameworkName { get => throw null; } } + [System.AttributeUsage((System.AttributeTargets)1, AllowMultiple = false, Inherited = false)] public sealed class TargetPlatformAttribute : System.Runtime.Versioning.OSPlatformAttribute { public TargetPlatformAttribute(string platformName) => throw null; } + [System.AttributeUsage((System.AttributeTargets)2047, AllowMultiple = true, Inherited = false)] public sealed class UnsupportedOSPlatformAttribute : System.Runtime.Versioning.OSPlatformAttribute { public UnsupportedOSPlatformAttribute(string platformName) => throw null; public UnsupportedOSPlatformAttribute(string platformName, string message) => throw null; public string Message { get => throw null; } } + [System.AttributeUsage((System.AttributeTargets)448, AllowMultiple = true, Inherited = false)] public sealed class UnsupportedOSPlatformGuardAttribute : System.Runtime.Versioning.OSPlatformAttribute { public UnsupportedOSPlatformGuardAttribute(string platformName) => throw null; @@ -10167,6 +10314,7 @@ public struct SByte : System.Numerics.IAdditionOperators, S } namespace Security { + [System.AttributeUsage((System.AttributeTargets)1, AllowMultiple = false, Inherited = false)] public sealed class AllowPartiallyTrustedCallersAttribute : System.Attribute { public AllowPartiallyTrustedCallersAttribute() => throw null; @@ -10211,6 +10359,7 @@ public enum PartialTrustVisibilityLevel } namespace Permissions { + [System.AttributeUsage((System.AttributeTargets)109, AllowMultiple = true, Inherited = false)] public abstract class CodeAccessSecurityAttribute : System.Security.Permissions.SecurityAttribute { protected CodeAccessSecurityAttribute(System.Security.Permissions.SecurityAction action) : base(default(System.Security.Permissions.SecurityAction)) => throw null; @@ -10232,6 +10381,7 @@ public enum SecurityAction RequestOptional = 9, RequestRefuse = 10, } + [System.AttributeUsage((System.AttributeTargets)109, AllowMultiple = true, Inherited = false)] public abstract class SecurityAttribute : System.Attribute { public System.Security.Permissions.SecurityAction Action { get => throw null; set { } } @@ -10239,6 +10389,7 @@ public abstract class SecurityAttribute : System.Attribute protected SecurityAttribute(System.Security.Permissions.SecurityAction action) => throw null; public bool Unrestricted { get => throw null; set { } } } + [System.AttributeUsage((System.AttributeTargets)109, AllowMultiple = true, Inherited = false)] public sealed class SecurityPermissionAttribute : System.Security.Permissions.CodeAccessSecurityAttribute { public bool Assertion { get => throw null; set { } } @@ -10347,6 +10498,7 @@ public enum TokenImpersonationLevel Delegation = 4, } } + [System.AttributeUsage((System.AttributeTargets)5501, AllowMultiple = false, Inherited = false)] public sealed class SecurityCriticalAttribute : System.Attribute { public SecurityCriticalAttribute() => throw null; @@ -10402,6 +10554,7 @@ public class SecurityException : System.SystemException public override string ToString() => throw null; public string Url { get => throw null; set { } } } + [System.AttributeUsage((System.AttributeTargets)1, AllowMultiple = false)] public sealed class SecurityRulesAttribute : System.Attribute { public SecurityRulesAttribute(System.Security.SecurityRuleSet ruleSet) => throw null; @@ -10414,22 +10567,27 @@ public enum SecurityRuleSet : byte Level1 = 1, Level2 = 2, } + [System.AttributeUsage((System.AttributeTargets)5500, AllowMultiple = false, Inherited = false)] public sealed class SecuritySafeCriticalAttribute : System.Attribute { public SecuritySafeCriticalAttribute() => throw null; } + [System.AttributeUsage((System.AttributeTargets)1, AllowMultiple = false, Inherited = false)] public sealed class SecurityTransparentAttribute : System.Attribute { public SecurityTransparentAttribute() => throw null; } + [System.AttributeUsage((System.AttributeTargets)5501, AllowMultiple = false, Inherited = false)] public sealed class SecurityTreatAsSafeAttribute : System.Attribute { public SecurityTreatAsSafeAttribute() => throw null; } + [System.AttributeUsage((System.AttributeTargets)5188, AllowMultiple = true, Inherited = false)] public sealed class SuppressUnmanagedCodeSecurityAttribute : System.Attribute { public SuppressUnmanagedCodeSecurityAttribute() => throw null; } + [System.AttributeUsage((System.AttributeTargets)2, AllowMultiple = true, Inherited = false)] public sealed class UnverifiableCodeAttribute : System.Attribute { public UnverifiableCodeAttribute() => throw null; @@ -10442,6 +10600,7 @@ public class VerificationException : System.SystemException public VerificationException(string message, System.Exception innerException) => throw null; } } + [System.AttributeUsage((System.AttributeTargets)4124, Inherited = false)] public sealed class SerializableAttribute : System.Attribute { public SerializableAttribute() => throw null; @@ -10675,6 +10834,7 @@ public sealed class StackOverflowException : System.SystemException public StackOverflowException(string message) => throw null; public StackOverflowException(string message, System.Exception innerException) => throw null; } + [System.AttributeUsage((System.AttributeTargets)64)] public sealed class STAThreadAttribute : System.Attribute { public STAThreadAttribute() => throw null; @@ -11998,6 +12158,7 @@ public static partial class WaitHandleExtensions public static void SetSafeWaitHandle(this System.Threading.WaitHandle waitHandle, Microsoft.Win32.SafeHandles.SafeWaitHandle value) => throw null; } } + [System.AttributeUsage((System.AttributeTargets)256, Inherited = false)] public class ThreadStaticAttribute : System.Attribute { public ThreadStaticAttribute() => throw null; diff --git a/csharp/ql/test/resources/stubs/_frameworks/Microsoft.NETCore.App/System.Text.Json.cs b/csharp/ql/test/resources/stubs/_frameworks/Microsoft.NETCore.App/System.Text.Json.cs index c82449571d9e..cc9925e61482 100644 --- a/csharp/ql/test/resources/stubs/_frameworks/Microsoft.NETCore.App/System.Text.Json.cs +++ b/csharp/ql/test/resources/stubs/_frameworks/Microsoft.NETCore.App/System.Text.Json.cs @@ -501,6 +501,7 @@ public abstract class JsonAttribute : System.Attribute { protected JsonAttribute() => throw null; } + [System.AttributeUsage((System.AttributeTargets)32, AllowMultiple = false)] public sealed class JsonConstructorAttribute : System.Text.Json.Serialization.JsonAttribute { public JsonConstructorAttribute() => throw null; @@ -519,6 +520,7 @@ public abstract class JsonConverter : System.Text.Json.Serialization.JsonConv public abstract void Write(System.Text.Json.Utf8JsonWriter writer, T value, System.Text.Json.JsonSerializerOptions options); public virtual void WriteAsPropertyName(System.Text.Json.Utf8JsonWriter writer, T value, System.Text.Json.JsonSerializerOptions options) => throw null; } + [System.AttributeUsage((System.AttributeTargets)1436, AllowMultiple = false)] public class JsonConverterAttribute : System.Text.Json.Serialization.JsonAttribute { public System.Type ConverterType { get => throw null; } @@ -531,6 +533,7 @@ public abstract class JsonConverterFactory : System.Text.Json.Serialization.Json public abstract System.Text.Json.Serialization.JsonConverter CreateConverter(System.Type typeToConvert, System.Text.Json.JsonSerializerOptions options); protected JsonConverterFactory() => throw null; } + [System.AttributeUsage((System.AttributeTargets)1028, AllowMultiple = true, Inherited = false)] public class JsonDerivedTypeAttribute : System.Text.Json.Serialization.JsonAttribute { public JsonDerivedTypeAttribute(System.Type derivedType) => throw null; @@ -539,10 +542,12 @@ public class JsonDerivedTypeAttribute : System.Text.Json.Serialization.JsonAttri public System.Type DerivedType { get => throw null; } public object TypeDiscriminator { get => throw null; } } + [System.AttributeUsage((System.AttributeTargets)384, AllowMultiple = false)] public sealed class JsonExtensionDataAttribute : System.Text.Json.Serialization.JsonAttribute { public JsonExtensionDataAttribute() => throw null; } + [System.AttributeUsage((System.AttributeTargets)384, AllowMultiple = false)] public sealed class JsonIgnoreAttribute : System.Text.Json.Serialization.JsonAttribute { public System.Text.Json.Serialization.JsonIgnoreCondition Condition { get => throw null; set { } } @@ -555,6 +560,7 @@ public enum JsonIgnoreCondition WhenWritingDefault = 2, WhenWritingNull = 3, } + [System.AttributeUsage((System.AttributeTargets)384, AllowMultiple = false)] public sealed class JsonIncludeAttribute : System.Text.Json.Serialization.JsonAttribute { public JsonIncludeAttribute() => throw null; @@ -572,11 +578,13 @@ public enum JsonNumberHandling WriteAsString = 2, AllowNamedFloatingPointLiterals = 4, } + [System.AttributeUsage((System.AttributeTargets)396, AllowMultiple = false)] public sealed class JsonNumberHandlingAttribute : System.Text.Json.Serialization.JsonAttribute { public JsonNumberHandlingAttribute(System.Text.Json.Serialization.JsonNumberHandling handling) => throw null; public System.Text.Json.Serialization.JsonNumberHandling Handling { get => throw null; } } + [System.AttributeUsage((System.AttributeTargets)1028, AllowMultiple = false, Inherited = false)] public sealed class JsonPolymorphicAttribute : System.Text.Json.Serialization.JsonAttribute { public JsonPolymorphicAttribute() => throw null; @@ -584,20 +592,24 @@ public sealed class JsonPolymorphicAttribute : System.Text.Json.Serialization.Js public string TypeDiscriminatorPropertyName { get => throw null; set { } } public System.Text.Json.Serialization.JsonUnknownDerivedTypeHandling UnknownDerivedTypeHandling { get => throw null; set { } } } + [System.AttributeUsage((System.AttributeTargets)384, AllowMultiple = false)] public sealed class JsonPropertyNameAttribute : System.Text.Json.Serialization.JsonAttribute { public JsonPropertyNameAttribute(string name) => throw null; public string Name { get => throw null; } } + [System.AttributeUsage((System.AttributeTargets)384, AllowMultiple = false)] public sealed class JsonPropertyOrderAttribute : System.Text.Json.Serialization.JsonAttribute { public JsonPropertyOrderAttribute(int order) => throw null; public int Order { get => throw null; } } + [System.AttributeUsage((System.AttributeTargets)384, AllowMultiple = false)] public sealed class JsonRequiredAttribute : System.Text.Json.Serialization.JsonAttribute { public JsonRequiredAttribute() => throw null; } + [System.AttributeUsage((System.AttributeTargets)4, AllowMultiple = true)] public sealed class JsonSerializableAttribute : System.Text.Json.Serialization.JsonAttribute { public JsonSerializableAttribute(System.Type type) => throw null; @@ -619,6 +631,7 @@ public enum JsonSourceGenerationMode Metadata = 1, Serialization = 2, } + [System.AttributeUsage((System.AttributeTargets)4, AllowMultiple = false)] public sealed class JsonSourceGenerationOptionsAttribute : System.Text.Json.Serialization.JsonAttribute { public JsonSourceGenerationOptionsAttribute() => throw null; diff --git a/csharp/ql/test/resources/stubs/_frameworks/Microsoft.NETCore.App/System.Text.RegularExpressions.cs b/csharp/ql/test/resources/stubs/_frameworks/Microsoft.NETCore.App/System.Text.RegularExpressions.cs index 235693df8aa3..18f601ea3ed2 100644 --- a/csharp/ql/test/resources/stubs/_frameworks/Microsoft.NETCore.App/System.Text.RegularExpressions.cs +++ b/csharp/ql/test/resources/stubs/_frameworks/Microsoft.NETCore.App/System.Text.RegularExpressions.cs @@ -43,6 +43,7 @@ public class CaptureCollection : System.Collections.Generic.ICollection throw null; } public System.Text.RegularExpressions.Capture this[int i] { get => throw null; } } + [System.AttributeUsage((System.AttributeTargets)64, AllowMultiple = false, Inherited = false)] public sealed class GeneratedRegexAttribute : System.Attribute { public GeneratedRegexAttribute(string pattern) => throw null; diff --git a/csharp/ql/test/resources/stubs/_frameworks/Microsoft.NETCore.App/System.Xml.ReaderWriter.cs b/csharp/ql/test/resources/stubs/_frameworks/Microsoft.NETCore.App/System.Xml.ReaderWriter.cs index 0b4e91673711..8b06ae6c2264 100644 --- a/csharp/ql/test/resources/stubs/_frameworks/Microsoft.NETCore.App/System.Xml.ReaderWriter.cs +++ b/csharp/ql/test/resources/stubs/_frameworks/Microsoft.NETCore.App/System.Xml.ReaderWriter.cs @@ -879,10 +879,12 @@ public interface IXmlSerializable void ReadXml(System.Xml.XmlReader reader); void WriteXml(System.Xml.XmlWriter writer); } + [System.AttributeUsage((System.AttributeTargets)10624, AllowMultiple = false)] public class XmlAnyAttributeAttribute : System.Attribute { public XmlAnyAttributeAttribute() => throw null; } + [System.AttributeUsage((System.AttributeTargets)10624, AllowMultiple = true)] public class XmlAnyElementAttribute : System.Attribute { public XmlAnyElementAttribute() => throw null; @@ -892,6 +894,7 @@ public class XmlAnyElementAttribute : System.Attribute public string Namespace { get => throw null; set { } } public int Order { get => throw null; set { } } } + [System.AttributeUsage((System.AttributeTargets)10624)] public class XmlAttributeAttribute : System.Attribute { public string AttributeName { get => throw null; set { } } @@ -904,6 +907,7 @@ public class XmlAttributeAttribute : System.Attribute public string Namespace { get => throw null; set { } } public System.Type Type { get => throw null; set { } } } + [System.AttributeUsage((System.AttributeTargets)10624, AllowMultiple = true)] public class XmlElementAttribute : System.Attribute { public XmlElementAttribute() => throw null; @@ -918,20 +922,24 @@ public class XmlElementAttribute : System.Attribute public int Order { get => throw null; set { } } public System.Type Type { get => throw null; set { } } } + [System.AttributeUsage((System.AttributeTargets)256)] public class XmlEnumAttribute : System.Attribute { public XmlEnumAttribute() => throw null; public XmlEnumAttribute(string name) => throw null; public string Name { get => throw null; set { } } } + [System.AttributeUsage((System.AttributeTargets)10624)] public class XmlIgnoreAttribute : System.Attribute { public XmlIgnoreAttribute() => throw null; } + [System.AttributeUsage((System.AttributeTargets)10624, AllowMultiple = false)] public class XmlNamespaceDeclarationsAttribute : System.Attribute { public XmlNamespaceDeclarationsAttribute() => throw null; } + [System.AttributeUsage((System.AttributeTargets)9244)] public class XmlRootAttribute : System.Attribute { public XmlRootAttribute() => throw null; @@ -941,6 +949,7 @@ public class XmlRootAttribute : System.Attribute public bool IsNullable { get => throw null; set { } } public string Namespace { get => throw null; set { } } } + [System.AttributeUsage((System.AttributeTargets)1036)] public sealed class XmlSchemaProviderAttribute : System.Attribute { public XmlSchemaProviderAttribute(string methodName) => throw null; @@ -956,6 +965,7 @@ public class XmlSerializerNamespaces public XmlSerializerNamespaces(System.Xml.XmlQualifiedName[] namespaces) => throw null; public System.Xml.XmlQualifiedName[] ToArray() => throw null; } + [System.AttributeUsage((System.AttributeTargets)10624)] public class XmlTextAttribute : System.Attribute { public XmlTextAttribute() => throw null; diff --git a/csharp/ql/test/resources/stubs/_frameworks/Microsoft.NETCore.App/System.Xml.XmlSerializer.cs b/csharp/ql/test/resources/stubs/_frameworks/Microsoft.NETCore.App/System.Xml.XmlSerializer.cs index 63df5eb2ca04..0d57ef76deb4 100644 --- a/csharp/ql/test/resources/stubs/_frameworks/Microsoft.NETCore.App/System.Xml.XmlSerializer.cs +++ b/csharp/ql/test/resources/stubs/_frameworks/Microsoft.NETCore.App/System.Xml.XmlSerializer.cs @@ -54,6 +54,7 @@ public interface IXmlTextParser public abstract class SchemaImporter { } + [System.AttributeUsage((System.AttributeTargets)10624)] public class SoapAttributeAttribute : System.Attribute { public string AttributeName { get => throw null; set { } } @@ -81,6 +82,7 @@ public class SoapAttributes public bool SoapIgnore { get => throw null; set { } } public System.Xml.Serialization.SoapTypeAttribute SoapType { get => throw null; set { } } } + [System.AttributeUsage((System.AttributeTargets)10624)] public class SoapElementAttribute : System.Attribute { public SoapElementAttribute() => throw null; @@ -89,16 +91,19 @@ public class SoapElementAttribute : System.Attribute public string ElementName { get => throw null; set { } } public bool IsNullable { get => throw null; set { } } } + [System.AttributeUsage((System.AttributeTargets)256)] public class SoapEnumAttribute : System.Attribute { public SoapEnumAttribute() => throw null; public SoapEnumAttribute(string name) => throw null; public string Name { get => throw null; set { } } } + [System.AttributeUsage((System.AttributeTargets)10624)] public class SoapIgnoreAttribute : System.Attribute { public SoapIgnoreAttribute() => throw null; } + [System.AttributeUsage((System.AttributeTargets)1100, AllowMultiple = true)] public class SoapIncludeAttribute : System.Attribute { public SoapIncludeAttribute(System.Type type) => throw null; @@ -125,6 +130,7 @@ public class SoapSchemaMember public string MemberName { get => throw null; set { } } public System.Xml.XmlQualifiedName MemberType { get => throw null; set { } } } + [System.AttributeUsage((System.AttributeTargets)1052)] public class SoapTypeAttribute : System.Attribute { public SoapTypeAttribute() => throw null; @@ -152,6 +158,7 @@ public class XmlAnyElementAttributes : System.Collections.CollectionBase public void Remove(System.Xml.Serialization.XmlAnyElementAttribute attribute) => throw null; public System.Xml.Serialization.XmlAnyElementAttribute this[int index] { get => throw null; set { } } } + [System.AttributeUsage((System.AttributeTargets)10624, AllowMultiple = false)] public class XmlArrayAttribute : System.Attribute { public XmlArrayAttribute() => throw null; @@ -162,6 +169,7 @@ public class XmlArrayAttribute : System.Attribute public string Namespace { get => throw null; set { } } public int Order { get => throw null; set { } } } + [System.AttributeUsage((System.AttributeTargets)10624, AllowMultiple = true)] public class XmlArrayItemAttribute : System.Attribute { public XmlArrayItemAttribute() => throw null; @@ -223,6 +231,7 @@ public class XmlAttributes public System.Xml.Serialization.XmlTextAttribute XmlText { get => throw null; set { } } public System.Xml.Serialization.XmlTypeAttribute XmlType { get => throw null; set { } } } + [System.AttributeUsage((System.AttributeTargets)10624, AllowMultiple = false)] public class XmlChoiceIdentifierAttribute : System.Attribute { public XmlChoiceIdentifierAttribute() => throw null; @@ -256,6 +265,7 @@ public class XmlElementEventArgs : System.EventArgs public object ObjectBeingDeserialized { get => throw null; } } public delegate void XmlElementEventHandler(object sender, System.Xml.Serialization.XmlElementEventArgs e); + [System.AttributeUsage((System.AttributeTargets)1100, AllowMultiple = true)] public class XmlIncludeAttribute : System.Attribute { public XmlIncludeAttribute(System.Type type) => throw null; @@ -635,6 +645,7 @@ public class XmlSerializer public event System.Xml.Serialization.XmlNodeEventHandler UnknownNode; public event System.Xml.Serialization.UnreferencedObjectEventHandler UnreferencedObject; } + [System.AttributeUsage((System.AttributeTargets)1052, AllowMultiple = false)] public sealed class XmlSerializerAssemblyAttribute : System.Attribute { public string AssemblyName { get => throw null; set { } } @@ -666,6 +677,7 @@ public abstract class XmlSerializerImplementation public virtual System.Collections.Hashtable WriteMethods { get => throw null; } public virtual System.Xml.Serialization.XmlSerializationWriter Writer { get => throw null; } } + [System.AttributeUsage((System.AttributeTargets)1)] public sealed class XmlSerializerVersionAttribute : System.Attribute { public XmlSerializerVersionAttribute() => throw null; @@ -675,6 +687,7 @@ public sealed class XmlSerializerVersionAttribute : System.Attribute public System.Type Type { get => throw null; set { } } public string Version { get => throw null; set { } } } + [System.AttributeUsage((System.AttributeTargets)1052)] public class XmlTypeAttribute : System.Attribute { public bool AnonymousType { get => throw null; set { } } diff --git a/csharp/ql/src/Stubs/README.md b/csharp/scripts/stubs/README.md similarity index 72% rename from csharp/ql/src/Stubs/README.md rename to csharp/scripts/stubs/README.md index 2b12e1d0b202..910b49ca9c14 100644 --- a/csharp/ql/src/Stubs/README.md +++ b/csharp/scripts/stubs/README.md @@ -5,10 +5,10 @@ Stubs can be generated from Nuget packages with the `make_stubs_nuget.py` script The following calls generate stubs for `Newtonsoft.Json`: ``` -python make_stubs_nuget.py Newtonsoft.Json -python make_stubs_nuget.py Newtonsoft.Json latest -python make_stubs_nuget.py Newtonsoft.Json 13.0.1 -python make_stubs_nuget.py Newtonsoft.Json 13.0.1 /Users/tmp/working-dir +python3 make_stubs_nuget.py classlib Newtonsoft.Json +python3 make_stubs_nuget.py classlib Newtonsoft.Json latest +python3 make_stubs_nuget.py classlib Newtonsoft.Json 13.0.1 +python3 make_stubs_nuget.py classlib Newtonsoft.Json 13.0.1 /Users/tmp/working-dir ``` The output stubs are found in the `[DIR]/output/stubs` folder and can be copied over to `csharp/ql/test/resources/stubs`. diff --git a/csharp/ql/src/Stubs/helpers.py b/csharp/scripts/stubs/helpers.py similarity index 100% rename from csharp/ql/src/Stubs/helpers.py rename to csharp/scripts/stubs/helpers.py diff --git a/csharp/ql/src/Stubs/make_stubs_nuget.py b/csharp/scripts/stubs/make_stubs_nuget.py similarity index 98% rename from csharp/ql/src/Stubs/make_stubs_nuget.py rename to csharp/scripts/stubs/make_stubs_nuget.py index 28126b0cf7b2..fb2543822995 100644 --- a/csharp/ql/src/Stubs/make_stubs_nuget.py +++ b/csharp/scripts/stubs/make_stubs_nuget.py @@ -82,7 +82,7 @@ def run_cmd(cmd, msg="Failed to run command"): run_cmd(['dotnet', 'new', 'globaljson', '--force', '--sdk-version', sdk_version, '--output', workDir]) print("\n* Running stub generator") -helpers.run_cmd_cwd(['dotnet', 'run', '--project', thisDir + '/../../../extractor/Semmle.Extraction.CSharp.DependencyStubGenerator/Semmle.Extraction.CSharp.DependencyStubGenerator.csproj'], projectDirIn) +helpers.run_cmd_cwd(['dotnet', 'run', '--project', thisDir + '/../../extractor/Semmle.Extraction.CSharp.DependencyStubGenerator/Semmle.Extraction.CSharp.DependencyStubGenerator.csproj'], projectDirIn) print("\n* Creating new raw output project") rawSrcOutputDirName = 'src' diff --git a/docs/codeql/ql-training/query-examples/java/data-flow-java-1.ql b/docs/codeql/ql-training/query-examples/java/data-flow-java-1.ql index ca14242c10a5..4bc121965b58 100644 --- a/docs/codeql/ql-training/query-examples/java/data-flow-java-1.ql +++ b/docs/codeql/ql-training/query-examples/java/data-flow-java-1.ql @@ -4,7 +4,7 @@ class StringConcat extends AddExpr { StringConcat() { getType() instanceof TypeString } } -from MethodAccess ma +from MethodCall ma where ma.getMethod().getName().matches("sparql%Query") and ma.getArgument(0) instanceof StringConcat diff --git a/docs/codeql/ql-training/query-examples/java/data-flow-java-2.ql b/docs/codeql/ql-training/query-examples/java/data-flow-java-2.ql index 87f41f59fe27..552b9babdbda 100644 --- a/docs/codeql/ql-training/query-examples/java/data-flow-java-2.ql +++ b/docs/codeql/ql-training/query-examples/java/data-flow-java-2.ql @@ -1,7 +1,7 @@ import java import semmle.code.java.dataflow.DataFlow::DataFlow -from MethodAccess ma, StringConcat stringConcat +from MethodCall ma, StringConcat stringConcat where ma.getMethod().getName().matches("sparql%Query") and localFlow(exprNode(stringConcat), exprNode(ma.getArgument(0))) diff --git a/docs/codeql/ql-training/query-examples/java/query-injection-java-1.ql b/docs/codeql/ql-training/query-examples/java/query-injection-java-1.ql index e9ad5a7113e3..9993a4cffb89 100644 --- a/docs/codeql/ql-training/query-examples/java/query-injection-java-1.ql +++ b/docs/codeql/ql-training/query-examples/java/query-injection-java-1.ql @@ -1,6 +1,6 @@ import java -from Method m, MethodAccess ma +from Method m, MethodCall ma where m.getName().matches("sparql%Query") and ma.getMethod() = m diff --git a/docs/codeql/ql-training/query-examples/java/query-injection-java-2.ql b/docs/codeql/ql-training/query-examples/java/query-injection-java-2.ql index bb2e76d168a2..98f2279b4e50 100644 --- a/docs/codeql/ql-training/query-examples/java/query-injection-java-2.ql +++ b/docs/codeql/ql-training/query-examples/java/query-injection-java-2.ql @@ -1,6 +1,6 @@ import java -from Method m, MethodAccess ma +from Method m, MethodCall ma where m.getName().matches("sparql%Query") and ma.getMethod() = m and diff --git a/docs/codeql/ql-training/query-examples/java/query-injection-java-3.ql b/docs/codeql/ql-training/query-examples/java/query-injection-java-3.ql index 9c7186ce4bfb..ebe52bbe3595 100644 --- a/docs/codeql/ql-training/query-examples/java/query-injection-java-3.ql +++ b/docs/codeql/ql-training/query-examples/java/query-injection-java-3.ql @@ -2,7 +2,7 @@ import java predicate isStringConcat(AddExpr ae) { ae.getType() instanceof TypeString } -from Method m, MethodAccess ma +from Method m, MethodCall ma where m.getName().matches("sparql%Query") and ma.getMethod() = m and diff --git a/docs/codeql/writing-codeql-queries/debugging-data-flow-queries-using-partial-flow.rst b/docs/codeql/writing-codeql-queries/debugging-data-flow-queries-using-partial-flow.rst index d2b09e2d92f2..b47dbba2159a 100644 --- a/docs/codeql/writing-codeql-queries/debugging-data-flow-queries-using-partial-flow.rst +++ b/docs/codeql/writing-codeql-queries/debugging-data-flow-queries-using-partial-flow.rst @@ -59,7 +59,7 @@ Partial flow A naive next step could be to change the sink definition to ``any()``. This would mean that we would get a lot of flow to all the places that are reachable from the sources. While this approach may work in some cases, you might find that it produces so many results that it's very hard to explore the findings. It can also dramatically affect query performance. More importantly, you might not even see all the partial flow paths. This is because the data-flow library tries very hard to prune impossible paths and, since field stores and reads must be evenly matched along a path, we will never see paths going through a store that fail to reach a corresponding read. This can make it hard to see where flow actually stops. -To avoid these problems, the data-flow library comes with a mechanism for exploring partial flow that tries to deal with these caveats. This is the ``MyFlow::FlowExploration::partialFlow`` predicate: +To avoid these problems, the data-flow library comes with a mechanism for exploring partial flow that tries to deal with these caveats. This is the ``MyFlow::FlowExplorationFwd::partialFlow`` predicate: .. code-block:: ql @@ -77,21 +77,19 @@ To avoid these problems, the data-flow library comes with a mechanism for explor */ predicate partialFlow(PartialPathNode source, PartialPathNode node, int dist) { -There is also a ``partialFlowRev`` for exploring flow backwards from a sink. +There is also a ``MyFlow::FlowExplorationRev::partialFlow`` for exploring flow backwards from a sink. -To get access to these predicates you must instantiate the ``MyFlow::FlowExploration<>`` module with an exploration limit. For example: +To get access to these predicates you must instantiate the ``MyFlow::FlowExplorationFwd<>`` module with an exploration limit (or the ``MyFlow::FlowExplorationRev<>`` module for reverse flow). For example: .. code-block:: ql int explorationLimit() { result = 5 } - module MyPartialFlow = MyFlow::FlowExploration; + module MyPartialFlow = MyFlow::FlowExplorationFwd; This defines the exploration radius within which ``partialFlow`` returns results. -To get good performance when using ``partialFlow`` it is important to ensure the ``isSink`` predicate of the configuration has no results. Likewise, when using ``partialFlowRev`` the ``isSource`` predicate of the configuration should have no results. - -It is also useful to focus on a single source at a time as the starting point for the flow exploration. This is most easily done by adding a temporary restriction in the ``isSource`` predicate. +It is useful to focus on a single source at a time as the starting point for the flow exploration. This is most easily done by adding a temporary restriction in the ``isSource`` predicate. To do quick evaluations of partial flow it is often easiest to add a predicate to the query that is solely intended for quick evaluation (right-click the predicate name and choose "CodeQL: Quick Evaluation"). A good starting point is something like: diff --git a/go/ql/consistency-queries/DataFlowConsistency.ql b/go/ql/consistency-queries/DataFlowConsistency.ql new file mode 100644 index 000000000000..ba19be49c6bc --- /dev/null +++ b/go/ql/consistency-queries/DataFlowConsistency.ql @@ -0,0 +1 @@ +import semmle.go.dataflow.internal.DataFlowImplConsistency::Consistency diff --git a/go/ql/consistency-queries/qlpack.yml b/go/ql/consistency-queries/qlpack.yml new file mode 100644 index 000000000000..01232241fc14 --- /dev/null +++ b/go/ql/consistency-queries/qlpack.yml @@ -0,0 +1,9 @@ +name: codeql-go-consistency-queries +version: 0.0.0 +groups: + - go + - queries +extractor: go +dependencies: + codeql/go-all: ${workspace} +warnOnImplicitThis: true \ No newline at end of file diff --git a/go/ql/lib/change-notes/2023-10-20-enclosing-callable-for-external-files.md b/go/ql/lib/change-notes/2023-10-20-enclosing-callable-for-external-files.md new file mode 100644 index 000000000000..59a646c2c8cb --- /dev/null +++ b/go/ql/lib/change-notes/2023-10-20-enclosing-callable-for-external-files.md @@ -0,0 +1,4 @@ +--- +category: fix +--- +* Fixed a bug where data flow nodes in files that are not in the project being analyzed (such as libraries) and are not contained within a function were not given an enclosing `Callable`. Note that for nodes that are not contained within a function, the enclosing callable is considered to be the file itself. This may cause some minor changes to results. diff --git a/go/ql/lib/change-notes/2023-10-25-reflectedxss-cookie-sanitizer.md b/go/ql/lib/change-notes/2023-10-25-reflectedxss-cookie-sanitizer.md new file mode 100644 index 000000000000..efb8faee097a --- /dev/null +++ b/go/ql/lib/change-notes/2023-10-25-reflectedxss-cookie-sanitizer.md @@ -0,0 +1,4 @@ +--- +category: minorAnalysis +--- +* Added [Request.Cookie](https://pkg.go.dev/net/http#Request.Cookie) to reflected XSS sanitizers. \ No newline at end of file diff --git a/go/ql/lib/semmle/go/dataflow/internal/DataFlowImplConsistency.qll b/go/ql/lib/semmle/go/dataflow/internal/DataFlowImplConsistency.qll new file mode 100644 index 000000000000..6397b79716b0 --- /dev/null +++ b/go/ql/lib/semmle/go/dataflow/internal/DataFlowImplConsistency.qll @@ -0,0 +1,13 @@ +/** + * Provides consistency queries for checking invariants in the language-specific + * data-flow classes and predicates. + */ + +private import go +private import DataFlowImplSpecific +private import TaintTrackingImplSpecific +private import codeql.dataflow.internal.DataFlowImplConsistency + +private module Input implements InputSig { } + +module Consistency = MakeConsistency; diff --git a/go/ql/lib/semmle/go/dataflow/internal/DataFlowNodes.qll b/go/ql/lib/semmle/go/dataflow/internal/DataFlowNodes.qll index 5a51f16b83ad..188832803dd8 100644 --- a/go/ql/lib/semmle/go/dataflow/internal/DataFlowNodes.qll +++ b/go/ql/lib/semmle/go/dataflow/internal/DataFlowNodes.qll @@ -21,9 +21,14 @@ module Private { DataFlowCallable nodeGetEnclosingCallable(Node n) { result.asCallable() = n.getEnclosingCallable() or - (n = MkInstructionNode(_) or n = MkSsaNode(_) or n = MkGlobalFunctionNode(_)) and + not n instanceof FlowSummaryNode and not exists(n.getEnclosingCallable()) and - result.asFileScope() = n.getFile() + ( + result.asFileScope() = n.getFile() + or + not exists(n.getFile()) and + result.isExternalFileScope() + ) or result.asSummarizedCallable() = n.(FlowSummaryNode).getSummarizedCallable() } diff --git a/go/ql/lib/semmle/go/dataflow/internal/DataFlowPrivate.qll b/go/ql/lib/semmle/go/dataflow/internal/DataFlowPrivate.qll index 93a1946655b8..c75796594fbf 100644 --- a/go/ql/lib/semmle/go/dataflow/internal/DataFlowPrivate.qll +++ b/go/ql/lib/semmle/go/dataflow/internal/DataFlowPrivate.qll @@ -256,6 +256,7 @@ class DataFlowLocation = Location; private newtype TDataFlowCallable = TCallable(Callable c) or TFileScope(File f) or + TExternalFileScope() or TSummarizedCallable(FlowSummary::SummarizedCallable c) class DataFlowCallable extends TDataFlowCallable { @@ -269,6 +270,11 @@ class DataFlowCallable extends TDataFlowCallable { */ File asFileScope() { this = TFileScope(result) } + /** + * Holds if this `DataFlowCallable` is an external file scope. + */ + predicate isExternalFileScope() { this = TExternalFileScope() } + /** * Gets the `SummarizedCallable` corresponding to this `DataFlowCallable`, if any. */ diff --git a/go/ql/lib/semmle/go/security/IncorrectIntegerConversionLib.qll b/go/ql/lib/semmle/go/security/IncorrectIntegerConversionLib.qll index 1aa9a428179d..e8601b37fda5 100644 --- a/go/ql/lib/semmle/go/security/IncorrectIntegerConversionLib.qll +++ b/go/ql/lib/semmle/go/security/IncorrectIntegerConversionLib.qll @@ -1,16 +1,48 @@ import go -/** - * Gets the maximum value of an integer (signed if `isSigned` - * is true, unsigned otherwise) with `bitSize` bits. - */ -float getMaxIntValue(int bitSize, boolean isSigned) { - bitSize in [8, 16, 32] and - ( - isSigned = true and result = 2.pow(bitSize - 1) - 1 - or - isSigned = false and result = 2.pow(bitSize) - 1 - ) +/** The constant `math.MaxInt` or the constant `math.MaxUint`. */ +abstract private class MaxIntOrMaxUint extends DeclaredConstant { + /** + * Gets the (binary) order of magnitude when the architecture has bit size + * `architectureBitSize`, which is defined to be the integer `x` such that + * `2.pow(x) - 1` is the value of this constant. + */ + abstract int getOrder(int architectureBitSize); + + /** + * Holds if the value of this constant given `architectureBitSize` minus + * `strictnessOffset` is less than or equal to `2.pow(b) - 1`. + */ + predicate isBoundFor(int b, int architectureBitSize, float strictnessOffset) { + // 2.pow(x) - 1 - strictnessOffset <= 2.pow(b) - 1 + exists(int x | + x = this.getOrder(architectureBitSize) and + b = validBitSize() and + ( + strictnessOffset = 0 and x <= b + or + strictnessOffset = 1 and x <= b - 1 + ) + ) + } +} + +/** The constant `math.MaxInt`. */ +private class MaxInt extends MaxIntOrMaxUint { + MaxInt() { this.hasQualifiedName("math", "MaxInt") } + + override int getOrder(int architectureBitSize) { + architectureBitSize = [32, 64] and result = architectureBitSize - 1 + } +} + +/** The constant `math.MaxUint`. */ +private class MaxUint extends MaxIntOrMaxUint { + MaxUint() { this.hasQualifiedName("math", "MaxUint") } + + override int getOrder(int architectureBitSize) { + architectureBitSize = [32, 64] and result = architectureBitSize + } } /** @@ -204,7 +236,7 @@ private class MaxValueState extends TMaxValueState { predicate architectureBitSizeUnknown() { this.architectureBitSize().isUnknown() } /** - * Gets the bitsize we should use for a sink. + * Gets the bitsize we should use for a sink of type `uint`. * * If the architecture bit size is known, then we should use that. Otherwise, * we should use 32 bits, because that will find results that only exist on @@ -257,15 +289,27 @@ private predicate upperBoundCheckGuard(DataFlow::Node g, Expr e, boolean branch) /** An upper bound check that compares a variable to a constant value. */ class UpperBoundCheckGuard extends DataFlow::RelationalComparisonNode { UpperBoundCheckGuard() { + // Note that even though `x > c` and `x >= c` do not look like upper bound + // checks, on the branches where they are false the conditions are `x <= c` + // and `x < c` respectively, which are upper bound checks. count(expr.getAnOperand().getExactValue()) = 1 and expr.getAnOperand().getType().getUnderlyingType() instanceof IntegerType } /** - * Holds if this upper bound check ensures the non-constant operand is less - * than or equal to `2^(bitsize) - 1`. In this case, the upper bound check - * is a barrier guard. `architectureBitSize` is used if the constant operand - * is `math.MaxInt` or `math.MaxUint`. + * Holds if this upper bound check should stop flow for a flow state with bit + * size `bitSize` and architecture bit size `architectureBitSize`. + * + * A flow state has bit size `bitSize` if that is the smallest valid bit size + * `b` such that the maximum value that could get to that point is less than + * or equal to `2^(b) - 1`. So the flow should be stopped if there is a valid + * bit size `b` which is less than `bitSize` such that the maximum value that + * could get to that point is than or equal to `2^(b) - 1`. In this case, + * the upper bound check is a barrier guard, because the flow should have bit + * size equal to the smallest such `b` instead of `bitSize`. + * + * The argument `architectureBitSize` is only used if the constant operand is + * `math.MaxInt` or `math.MaxUint`. * * Note that we have to use floats here because integers in CodeQL are * represented by 32-bit signed integers, which cannot represent some of the @@ -274,25 +318,25 @@ class UpperBoundCheckGuard extends DataFlow::RelationalComparisonNode { predicate isBoundFor(int bitSize, int architectureBitSize) { bitSize = validBitSize() and architectureBitSize = [32, 64] and - exists(float bound, float strictnessOffset | - // For `x < c` the bound is `c-1`. For `x >= c` we will be an upper bound - // on the `branch` argument of `checks` is false, which is equivalent to - // `x < c`. + exists(int b, float strictnessOffset | + // It is sufficient to check for the next valid bit size below `bitSize`. + b = max(int a | a = validBitSize() and a < bitSize) and + // We will use the format `x <= c - strictnessOffset`. Since `x < c` is + // the same as `x <= c-1`, we set `strictnessOffset` to 1 in this case. + // For `x >= c` we will be dealing with the case where the `branch` + // argument of `checks` is false, which is equivalent to `x < c`. if expr instanceof LssExpr or expr instanceof GeqExpr then strictnessOffset = 1 else strictnessOffset = 0 | - exists(DeclaredConstant maxint, DeclaredConstant maxuint | - maxint.hasQualifiedName("math", "MaxInt") and maxuint.hasQualifiedName("math", "MaxUint") - | - if expr.getAnOperand() = maxint.getAReference() - then bound = getMaxIntValue(architectureBitSize, true) - else - if expr.getAnOperand() = maxuint.getAReference() - then bound = getMaxIntValue(architectureBitSize, false) - else bound = expr.getAnOperand().getExactValue().toFloat() - ) and - bound - strictnessOffset < 2.pow(bitSize) - 1 + if expr.getAnOperand() = any(MaxIntOrMaxUint m).getAReference() + then + any(MaxIntOrMaxUint m | expr.getAnOperand() = m.getAReference()) + .isBoundFor(b, architectureBitSize, strictnessOffset) + else + // We want `x <= c - strictnessOffset` to guarantee that `x <= 2^b - 1`, + // which is equivalent to saying `c - strictnessOffset <= 2^b - 1`. + expr.getAnOperand().getExactValue().toFloat() - strictnessOffset <= 2.pow(b) - 1 ) } @@ -316,7 +360,7 @@ class UpperBoundCheckGuard extends DataFlow::RelationalComparisonNode { * _ = uint16(parsed) * } * ``` - * `parsed < math.MaxInt16` is an `UpperBoundCheckGuard` and `uint16(parsed)` + * `parsed <= math.MaxInt16` is an `UpperBoundCheckGuard` and `uint16(parsed)` * is an `UpperBoundCheck` that would be a barrier for flow states with bit * size greater than 15 and would transform them to a flow state with bit size * 15 and the same architecture bit size. diff --git a/go/ql/lib/semmle/go/security/ReflectedXssCustomizations.qll b/go/ql/lib/semmle/go/security/ReflectedXssCustomizations.qll index 71c25d889fa3..b1c81950a6c8 100644 --- a/go/ql/lib/semmle/go/security/ReflectedXssCustomizations.qll +++ b/go/ql/lib/semmle/go/security/ReflectedXssCustomizations.qll @@ -22,6 +22,18 @@ module ReflectedXss { /** A shared XSS sanitizer as a sanitizer for reflected XSS. */ private class SharedXssSanitizer extends Sanitizer instanceof SharedXss::Sanitizer { } + /** + * A request.Cookie method returns the request cookie, which is not user controlled in reflected XSS context. + */ + class CookieSanitizer extends Sanitizer { + CookieSanitizer() { + exists(Method m, DataFlow::CallNode call | call = m.getACall() | + m.hasQualifiedName("net/http", "Request", "Cookie") and + this = call.getResult(0) + ) + } + } + /** * A third-party controllable input, considered as a flow source for reflected XSS. */ diff --git a/go/ql/src/change-notes/2023-10-27-incorrect-integer-conversion-guards.md b/go/ql/src/change-notes/2023-10-27-incorrect-integer-conversion-guards.md new file mode 100644 index 000000000000..2c5f163879f9 --- /dev/null +++ b/go/ql/src/change-notes/2023-10-27-incorrect-integer-conversion-guards.md @@ -0,0 +1,4 @@ +--- +category: minorAnalysis +--- +* The query `go/incorrect-integer-conversion` now correctly recognizes more guards of the form `if val <= x` to protect a conversion `uintX(val)`. diff --git a/go/ql/test/library-tests/semmle/go/frameworks/XNetHtml/ReflectedXss.expected b/go/ql/test/library-tests/semmle/go/frameworks/XNetHtml/ReflectedXss.expected index 21c6a94e4ad4..1124ca22b055 100644 --- a/go/ql/test/library-tests/semmle/go/frameworks/XNetHtml/ReflectedXss.expected +++ b/go/ql/test/library-tests/semmle/go/frameworks/XNetHtml/ReflectedXss.expected @@ -1,123 +1,127 @@ edges -| test.go:11:2:11:42 | ... := ...[0] | test.go:14:42:14:53 | selection of Value | -| test.go:14:22:14:54 | call to UnescapeString | test.go:14:15:14:55 | type conversion | -| test.go:14:42:14:53 | selection of Value | test.go:14:22:14:54 | call to UnescapeString | -| test.go:16:2:16:36 | ... := ...[0] | test.go:17:15:17:31 | type conversion | -| test.go:16:2:16:36 | ... := ...[0] | test.go:28:22:28:25 | node | -| test.go:16:24:16:35 | selection of Body | test.go:16:2:16:36 | ... := ...[0] | -| test.go:19:2:19:48 | ... := ...[0] | test.go:20:15:20:32 | type conversion | -| test.go:19:36:19:47 | selection of Body | test.go:19:2:19:48 | ... := ...[0] | -| test.go:22:2:22:50 | ... := ...[0] | test.go:23:15:23:35 | type conversion | -| test.go:22:33:22:44 | selection of Body | test.go:22:2:22:50 | ... := ...[0] | -| test.go:25:2:25:62 | ... := ...[0] | test.go:26:15:26:36 | type conversion | -| test.go:25:45:25:56 | selection of Body | test.go:25:2:25:62 | ... := ...[0] | -| test.go:30:15:30:45 | call to NewTokenizer | test.go:31:15:31:23 | tokenizer | -| test.go:30:15:30:45 | call to NewTokenizer | test.go:32:15:32:23 | tokenizer | -| test.go:30:15:30:45 | call to NewTokenizer | test.go:33:17:33:25 | tokenizer | -| test.go:30:15:30:45 | call to NewTokenizer | test.go:35:15:35:23 | tokenizer | -| test.go:30:15:30:45 | call to NewTokenizer | test.go:36:22:36:30 | tokenizer | -| test.go:30:33:30:44 | selection of Body | test.go:30:15:30:45 | call to NewTokenizer | -| test.go:31:15:31:23 | tokenizer | test.go:31:15:31:34 | call to Buffered | -| test.go:32:15:32:23 | tokenizer | test.go:32:15:32:29 | call to Raw | -| test.go:33:2:33:35 | ... := ...[1] | test.go:34:15:34:19 | value | -| test.go:33:17:33:25 | tokenizer | test.go:33:2:33:35 | ... := ...[1] | -| test.go:35:15:35:23 | tokenizer | test.go:35:15:35:30 | call to Text | -| test.go:36:22:36:30 | tokenizer | test.go:36:22:36:38 | call to Token | -| test.go:36:22:36:38 | call to Token | test.go:36:15:36:44 | type conversion | -| test.go:38:23:38:77 | call to NewTokenizerFragment | test.go:39:15:39:31 | tokenizerFragment | -| test.go:38:49:38:60 | selection of Body | test.go:38:23:38:77 | call to NewTokenizerFragment | -| test.go:39:15:39:31 | tokenizerFragment | test.go:39:15:39:42 | call to Buffered | -| test.go:41:6:41:14 | definition of cleanNode | test.go:44:22:44:31 | &... | -| test.go:41:6:41:14 | definition of cleanNode | test.go:44:22:44:31 | &... | -| test.go:41:6:41:14 | definition of cleanNode | test.go:44:23:44:31 | cleanNode | -| test.go:42:2:42:43 | ... := ...[0] | test.go:43:24:43:34 | taintedNode | -| test.go:42:31:42:42 | selection of Body | test.go:42:2:42:43 | ... := ...[0] | -| test.go:43:24:43:34 | taintedNode | test.go:41:6:41:14 | definition of cleanNode | -| test.go:44:22:44:31 | &... | test.go:44:22:44:31 | &... | -| test.go:44:22:44:31 | &... | test.go:44:22:44:31 | &... | -| test.go:44:22:44:31 | &... | test.go:44:23:44:31 | cleanNode | -| test.go:44:22:44:31 | &... [pointer] | test.go:44:22:44:31 | &... | -| test.go:44:22:44:31 | &... [pointer] | test.go:44:22:44:31 | &... | -| test.go:44:22:44:31 | &... [pointer] | test.go:44:23:44:31 | cleanNode | -| test.go:44:23:44:31 | cleanNode | test.go:44:22:44:31 | &... [pointer] | -| test.go:46:6:46:15 | definition of cleanNode2 | test.go:49:22:49:32 | &... | -| test.go:46:6:46:15 | definition of cleanNode2 | test.go:49:22:49:32 | &... | -| test.go:46:6:46:15 | definition of cleanNode2 | test.go:49:23:49:32 | cleanNode2 | -| test.go:47:2:47:44 | ... := ...[0] | test.go:48:26:48:37 | taintedNode2 | -| test.go:47:32:47:43 | selection of Body | test.go:47:2:47:44 | ... := ...[0] | -| test.go:48:26:48:37 | taintedNode2 | test.go:46:6:46:15 | definition of cleanNode2 | -| test.go:49:22:49:32 | &... | test.go:49:22:49:32 | &... | -| test.go:49:22:49:32 | &... | test.go:49:22:49:32 | &... | -| test.go:49:22:49:32 | &... | test.go:49:23:49:32 | cleanNode2 | -| test.go:49:22:49:32 | &... [pointer] | test.go:49:22:49:32 | &... | -| test.go:49:22:49:32 | &... [pointer] | test.go:49:22:49:32 | &... | -| test.go:49:22:49:32 | &... [pointer] | test.go:49:23:49:32 | cleanNode2 | -| test.go:49:23:49:32 | cleanNode2 | test.go:49:22:49:32 | &... [pointer] | +| test.go:12:12:12:22 | selection of URL | test.go:12:12:12:30 | call to Query | +| test.go:12:12:12:30 | call to Query | test.go:12:12:12:44 | call to Get | +| test.go:12:12:12:44 | call to Get | test.go:15:42:15:47 | param1 | +| test.go:15:22:15:48 | call to UnescapeString | test.go:15:15:15:49 | type conversion | +| test.go:15:42:15:47 | param1 | test.go:15:22:15:48 | call to UnescapeString | +| test.go:17:2:17:36 | ... := ...[0] | test.go:18:15:18:31 | type conversion | +| test.go:17:2:17:36 | ... := ...[0] | test.go:29:22:29:25 | node | +| test.go:17:24:17:35 | selection of Body | test.go:17:2:17:36 | ... := ...[0] | +| test.go:20:2:20:48 | ... := ...[0] | test.go:21:15:21:32 | type conversion | +| test.go:20:36:20:47 | selection of Body | test.go:20:2:20:48 | ... := ...[0] | +| test.go:23:2:23:50 | ... := ...[0] | test.go:24:15:24:35 | type conversion | +| test.go:23:33:23:44 | selection of Body | test.go:23:2:23:50 | ... := ...[0] | +| test.go:26:2:26:62 | ... := ...[0] | test.go:27:15:27:36 | type conversion | +| test.go:26:45:26:56 | selection of Body | test.go:26:2:26:62 | ... := ...[0] | +| test.go:31:15:31:45 | call to NewTokenizer | test.go:32:15:32:23 | tokenizer | +| test.go:31:15:31:45 | call to NewTokenizer | test.go:33:15:33:23 | tokenizer | +| test.go:31:15:31:45 | call to NewTokenizer | test.go:34:17:34:25 | tokenizer | +| test.go:31:15:31:45 | call to NewTokenizer | test.go:36:15:36:23 | tokenizer | +| test.go:31:15:31:45 | call to NewTokenizer | test.go:37:22:37:30 | tokenizer | +| test.go:31:33:31:44 | selection of Body | test.go:31:15:31:45 | call to NewTokenizer | +| test.go:32:15:32:23 | tokenizer | test.go:32:15:32:34 | call to Buffered | +| test.go:33:15:33:23 | tokenizer | test.go:33:15:33:29 | call to Raw | +| test.go:34:2:34:35 | ... := ...[1] | test.go:35:15:35:19 | value | +| test.go:34:17:34:25 | tokenizer | test.go:34:2:34:35 | ... := ...[1] | +| test.go:36:15:36:23 | tokenizer | test.go:36:15:36:30 | call to Text | +| test.go:37:22:37:30 | tokenizer | test.go:37:22:37:38 | call to Token | +| test.go:37:22:37:38 | call to Token | test.go:37:15:37:44 | type conversion | +| test.go:39:23:39:77 | call to NewTokenizerFragment | test.go:40:15:40:31 | tokenizerFragment | +| test.go:39:49:39:60 | selection of Body | test.go:39:23:39:77 | call to NewTokenizerFragment | +| test.go:40:15:40:31 | tokenizerFragment | test.go:40:15:40:42 | call to Buffered | +| test.go:42:6:42:14 | definition of cleanNode | test.go:45:22:45:31 | &... | +| test.go:42:6:42:14 | definition of cleanNode | test.go:45:22:45:31 | &... | +| test.go:42:6:42:14 | definition of cleanNode | test.go:45:23:45:31 | cleanNode | +| test.go:43:2:43:43 | ... := ...[0] | test.go:44:24:44:34 | taintedNode | +| test.go:43:31:43:42 | selection of Body | test.go:43:2:43:43 | ... := ...[0] | +| test.go:44:24:44:34 | taintedNode | test.go:42:6:42:14 | definition of cleanNode | +| test.go:45:22:45:31 | &... | test.go:45:22:45:31 | &... | +| test.go:45:22:45:31 | &... | test.go:45:22:45:31 | &... | +| test.go:45:22:45:31 | &... | test.go:45:23:45:31 | cleanNode | +| test.go:45:22:45:31 | &... [pointer] | test.go:45:22:45:31 | &... | +| test.go:45:22:45:31 | &... [pointer] | test.go:45:22:45:31 | &... | +| test.go:45:22:45:31 | &... [pointer] | test.go:45:23:45:31 | cleanNode | +| test.go:45:23:45:31 | cleanNode | test.go:45:22:45:31 | &... [pointer] | +| test.go:47:6:47:15 | definition of cleanNode2 | test.go:50:22:50:32 | &... | +| test.go:47:6:47:15 | definition of cleanNode2 | test.go:50:22:50:32 | &... | +| test.go:47:6:47:15 | definition of cleanNode2 | test.go:50:23:50:32 | cleanNode2 | +| test.go:48:2:48:44 | ... := ...[0] | test.go:49:26:49:37 | taintedNode2 | +| test.go:48:32:48:43 | selection of Body | test.go:48:2:48:44 | ... := ...[0] | +| test.go:49:26:49:37 | taintedNode2 | test.go:47:6:47:15 | definition of cleanNode2 | +| test.go:50:22:50:32 | &... | test.go:50:22:50:32 | &... | +| test.go:50:22:50:32 | &... | test.go:50:22:50:32 | &... | +| test.go:50:22:50:32 | &... | test.go:50:23:50:32 | cleanNode2 | +| test.go:50:22:50:32 | &... [pointer] | test.go:50:22:50:32 | &... | +| test.go:50:22:50:32 | &... [pointer] | test.go:50:22:50:32 | &... | +| test.go:50:22:50:32 | &... [pointer] | test.go:50:23:50:32 | cleanNode2 | +| test.go:50:23:50:32 | cleanNode2 | test.go:50:22:50:32 | &... [pointer] | nodes -| test.go:11:2:11:42 | ... := ...[0] | semmle.label | ... := ...[0] | -| test.go:14:15:14:55 | type conversion | semmle.label | type conversion | -| test.go:14:22:14:54 | call to UnescapeString | semmle.label | call to UnescapeString | -| test.go:14:42:14:53 | selection of Value | semmle.label | selection of Value | -| test.go:16:2:16:36 | ... := ...[0] | semmle.label | ... := ...[0] | -| test.go:16:24:16:35 | selection of Body | semmle.label | selection of Body | -| test.go:17:15:17:31 | type conversion | semmle.label | type conversion | -| test.go:19:2:19:48 | ... := ...[0] | semmle.label | ... := ...[0] | -| test.go:19:36:19:47 | selection of Body | semmle.label | selection of Body | -| test.go:20:15:20:32 | type conversion | semmle.label | type conversion | -| test.go:22:2:22:50 | ... := ...[0] | semmle.label | ... := ...[0] | -| test.go:22:33:22:44 | selection of Body | semmle.label | selection of Body | -| test.go:23:15:23:35 | type conversion | semmle.label | type conversion | -| test.go:25:2:25:62 | ... := ...[0] | semmle.label | ... := ...[0] | -| test.go:25:45:25:56 | selection of Body | semmle.label | selection of Body | -| test.go:26:15:26:36 | type conversion | semmle.label | type conversion | -| test.go:28:22:28:25 | node | semmle.label | node | -| test.go:30:15:30:45 | call to NewTokenizer | semmle.label | call to NewTokenizer | -| test.go:30:33:30:44 | selection of Body | semmle.label | selection of Body | -| test.go:31:15:31:23 | tokenizer | semmle.label | tokenizer | -| test.go:31:15:31:34 | call to Buffered | semmle.label | call to Buffered | +| test.go:12:12:12:22 | selection of URL | semmle.label | selection of URL | +| test.go:12:12:12:30 | call to Query | semmle.label | call to Query | +| test.go:12:12:12:44 | call to Get | semmle.label | call to Get | +| test.go:15:15:15:49 | type conversion | semmle.label | type conversion | +| test.go:15:22:15:48 | call to UnescapeString | semmle.label | call to UnescapeString | +| test.go:15:42:15:47 | param1 | semmle.label | param1 | +| test.go:17:2:17:36 | ... := ...[0] | semmle.label | ... := ...[0] | +| test.go:17:24:17:35 | selection of Body | semmle.label | selection of Body | +| test.go:18:15:18:31 | type conversion | semmle.label | type conversion | +| test.go:20:2:20:48 | ... := ...[0] | semmle.label | ... := ...[0] | +| test.go:20:36:20:47 | selection of Body | semmle.label | selection of Body | +| test.go:21:15:21:32 | type conversion | semmle.label | type conversion | +| test.go:23:2:23:50 | ... := ...[0] | semmle.label | ... := ...[0] | +| test.go:23:33:23:44 | selection of Body | semmle.label | selection of Body | +| test.go:24:15:24:35 | type conversion | semmle.label | type conversion | +| test.go:26:2:26:62 | ... := ...[0] | semmle.label | ... := ...[0] | +| test.go:26:45:26:56 | selection of Body | semmle.label | selection of Body | +| test.go:27:15:27:36 | type conversion | semmle.label | type conversion | +| test.go:29:22:29:25 | node | semmle.label | node | +| test.go:31:15:31:45 | call to NewTokenizer | semmle.label | call to NewTokenizer | +| test.go:31:33:31:44 | selection of Body | semmle.label | selection of Body | | test.go:32:15:32:23 | tokenizer | semmle.label | tokenizer | -| test.go:32:15:32:29 | call to Raw | semmle.label | call to Raw | -| test.go:33:2:33:35 | ... := ...[1] | semmle.label | ... := ...[1] | -| test.go:33:17:33:25 | tokenizer | semmle.label | tokenizer | -| test.go:34:15:34:19 | value | semmle.label | value | -| test.go:35:15:35:23 | tokenizer | semmle.label | tokenizer | -| test.go:35:15:35:30 | call to Text | semmle.label | call to Text | -| test.go:36:15:36:44 | type conversion | semmle.label | type conversion | -| test.go:36:22:36:30 | tokenizer | semmle.label | tokenizer | -| test.go:36:22:36:38 | call to Token | semmle.label | call to Token | -| test.go:38:23:38:77 | call to NewTokenizerFragment | semmle.label | call to NewTokenizerFragment | -| test.go:38:49:38:60 | selection of Body | semmle.label | selection of Body | -| test.go:39:15:39:31 | tokenizerFragment | semmle.label | tokenizerFragment | -| test.go:39:15:39:42 | call to Buffered | semmle.label | call to Buffered | -| test.go:41:6:41:14 | definition of cleanNode | semmle.label | definition of cleanNode | -| test.go:42:2:42:43 | ... := ...[0] | semmle.label | ... := ...[0] | -| test.go:42:31:42:42 | selection of Body | semmle.label | selection of Body | -| test.go:43:24:43:34 | taintedNode | semmle.label | taintedNode | -| test.go:44:22:44:31 | &... | semmle.label | &... | -| test.go:44:22:44:31 | &... | semmle.label | &... | -| test.go:44:22:44:31 | &... [pointer] | semmle.label | &... [pointer] | -| test.go:44:23:44:31 | cleanNode | semmle.label | cleanNode | -| test.go:46:6:46:15 | definition of cleanNode2 | semmle.label | definition of cleanNode2 | -| test.go:47:2:47:44 | ... := ...[0] | semmle.label | ... := ...[0] | -| test.go:47:32:47:43 | selection of Body | semmle.label | selection of Body | -| test.go:48:26:48:37 | taintedNode2 | semmle.label | taintedNode2 | -| test.go:49:22:49:32 | &... | semmle.label | &... | -| test.go:49:22:49:32 | &... | semmle.label | &... | -| test.go:49:22:49:32 | &... [pointer] | semmle.label | &... [pointer] | -| test.go:49:23:49:32 | cleanNode2 | semmle.label | cleanNode2 | +| test.go:32:15:32:34 | call to Buffered | semmle.label | call to Buffered | +| test.go:33:15:33:23 | tokenizer | semmle.label | tokenizer | +| test.go:33:15:33:29 | call to Raw | semmle.label | call to Raw | +| test.go:34:2:34:35 | ... := ...[1] | semmle.label | ... := ...[1] | +| test.go:34:17:34:25 | tokenizer | semmle.label | tokenizer | +| test.go:35:15:35:19 | value | semmle.label | value | +| test.go:36:15:36:23 | tokenizer | semmle.label | tokenizer | +| test.go:36:15:36:30 | call to Text | semmle.label | call to Text | +| test.go:37:15:37:44 | type conversion | semmle.label | type conversion | +| test.go:37:22:37:30 | tokenizer | semmle.label | tokenizer | +| test.go:37:22:37:38 | call to Token | semmle.label | call to Token | +| test.go:39:23:39:77 | call to NewTokenizerFragment | semmle.label | call to NewTokenizerFragment | +| test.go:39:49:39:60 | selection of Body | semmle.label | selection of Body | +| test.go:40:15:40:31 | tokenizerFragment | semmle.label | tokenizerFragment | +| test.go:40:15:40:42 | call to Buffered | semmle.label | call to Buffered | +| test.go:42:6:42:14 | definition of cleanNode | semmle.label | definition of cleanNode | +| test.go:43:2:43:43 | ... := ...[0] | semmle.label | ... := ...[0] | +| test.go:43:31:43:42 | selection of Body | semmle.label | selection of Body | +| test.go:44:24:44:34 | taintedNode | semmle.label | taintedNode | +| test.go:45:22:45:31 | &... | semmle.label | &... | +| test.go:45:22:45:31 | &... | semmle.label | &... | +| test.go:45:22:45:31 | &... [pointer] | semmle.label | &... [pointer] | +| test.go:45:23:45:31 | cleanNode | semmle.label | cleanNode | +| test.go:47:6:47:15 | definition of cleanNode2 | semmle.label | definition of cleanNode2 | +| test.go:48:2:48:44 | ... := ...[0] | semmle.label | ... := ...[0] | +| test.go:48:32:48:43 | selection of Body | semmle.label | selection of Body | +| test.go:49:26:49:37 | taintedNode2 | semmle.label | taintedNode2 | +| test.go:50:22:50:32 | &... | semmle.label | &... | +| test.go:50:22:50:32 | &... | semmle.label | &... | +| test.go:50:22:50:32 | &... [pointer] | semmle.label | &... [pointer] | +| test.go:50:23:50:32 | cleanNode2 | semmle.label | cleanNode2 | subpaths #select -| test.go:14:15:14:55 | type conversion | test.go:11:2:11:42 | ... := ...[0] | test.go:14:15:14:55 | type conversion | Cross-site scripting vulnerability due to $@. | test.go:11:2:11:42 | ... := ...[0] | user-provided value | test.go:0:0:0:0 | test.go | | -| test.go:17:15:17:31 | type conversion | test.go:16:24:16:35 | selection of Body | test.go:17:15:17:31 | type conversion | Cross-site scripting vulnerability due to $@. | test.go:16:24:16:35 | selection of Body | user-provided value | test.go:0:0:0:0 | test.go | | -| test.go:20:15:20:32 | type conversion | test.go:19:36:19:47 | selection of Body | test.go:20:15:20:32 | type conversion | Cross-site scripting vulnerability due to $@. | test.go:19:36:19:47 | selection of Body | user-provided value | test.go:0:0:0:0 | test.go | | -| test.go:23:15:23:35 | type conversion | test.go:22:33:22:44 | selection of Body | test.go:23:15:23:35 | type conversion | Cross-site scripting vulnerability due to $@. | test.go:22:33:22:44 | selection of Body | user-provided value | test.go:0:0:0:0 | test.go | | -| test.go:26:15:26:36 | type conversion | test.go:25:45:25:56 | selection of Body | test.go:26:15:26:36 | type conversion | Cross-site scripting vulnerability due to $@. | test.go:25:45:25:56 | selection of Body | user-provided value | test.go:0:0:0:0 | test.go | | -| test.go:28:22:28:25 | node | test.go:16:24:16:35 | selection of Body | test.go:28:22:28:25 | node | Cross-site scripting vulnerability due to $@. | test.go:16:24:16:35 | selection of Body | user-provided value | test.go:0:0:0:0 | test.go | | -| test.go:31:15:31:34 | call to Buffered | test.go:30:33:30:44 | selection of Body | test.go:31:15:31:34 | call to Buffered | Cross-site scripting vulnerability due to $@. | test.go:30:33:30:44 | selection of Body | user-provided value | test.go:0:0:0:0 | test.go | | -| test.go:32:15:32:29 | call to Raw | test.go:30:33:30:44 | selection of Body | test.go:32:15:32:29 | call to Raw | Cross-site scripting vulnerability due to $@. | test.go:30:33:30:44 | selection of Body | user-provided value | test.go:0:0:0:0 | test.go | | -| test.go:34:15:34:19 | value | test.go:30:33:30:44 | selection of Body | test.go:34:15:34:19 | value | Cross-site scripting vulnerability due to $@. | test.go:30:33:30:44 | selection of Body | user-provided value | test.go:0:0:0:0 | test.go | | -| test.go:35:15:35:30 | call to Text | test.go:30:33:30:44 | selection of Body | test.go:35:15:35:30 | call to Text | Cross-site scripting vulnerability due to $@. | test.go:30:33:30:44 | selection of Body | user-provided value | test.go:0:0:0:0 | test.go | | -| test.go:36:15:36:44 | type conversion | test.go:30:33:30:44 | selection of Body | test.go:36:15:36:44 | type conversion | Cross-site scripting vulnerability due to $@. | test.go:30:33:30:44 | selection of Body | user-provided value | test.go:0:0:0:0 | test.go | | -| test.go:39:15:39:42 | call to Buffered | test.go:38:49:38:60 | selection of Body | test.go:39:15:39:42 | call to Buffered | Cross-site scripting vulnerability due to $@. | test.go:38:49:38:60 | selection of Body | user-provided value | test.go:0:0:0:0 | test.go | | -| test.go:44:22:44:31 | &... | test.go:42:31:42:42 | selection of Body | test.go:44:22:44:31 | &... | Cross-site scripting vulnerability due to $@. | test.go:42:31:42:42 | selection of Body | user-provided value | test.go:0:0:0:0 | test.go | | -| test.go:49:22:49:32 | &... | test.go:47:32:47:43 | selection of Body | test.go:49:22:49:32 | &... | Cross-site scripting vulnerability due to $@. | test.go:47:32:47:43 | selection of Body | user-provided value | test.go:0:0:0:0 | test.go | | +| test.go:15:15:15:49 | type conversion | test.go:12:12:12:22 | selection of URL | test.go:15:15:15:49 | type conversion | Cross-site scripting vulnerability due to $@. | test.go:12:12:12:22 | selection of URL | user-provided value | test.go:0:0:0:0 | test.go | | +| test.go:18:15:18:31 | type conversion | test.go:17:24:17:35 | selection of Body | test.go:18:15:18:31 | type conversion | Cross-site scripting vulnerability due to $@. | test.go:17:24:17:35 | selection of Body | user-provided value | test.go:0:0:0:0 | test.go | | +| test.go:21:15:21:32 | type conversion | test.go:20:36:20:47 | selection of Body | test.go:21:15:21:32 | type conversion | Cross-site scripting vulnerability due to $@. | test.go:20:36:20:47 | selection of Body | user-provided value | test.go:0:0:0:0 | test.go | | +| test.go:24:15:24:35 | type conversion | test.go:23:33:23:44 | selection of Body | test.go:24:15:24:35 | type conversion | Cross-site scripting vulnerability due to $@. | test.go:23:33:23:44 | selection of Body | user-provided value | test.go:0:0:0:0 | test.go | | +| test.go:27:15:27:36 | type conversion | test.go:26:45:26:56 | selection of Body | test.go:27:15:27:36 | type conversion | Cross-site scripting vulnerability due to $@. | test.go:26:45:26:56 | selection of Body | user-provided value | test.go:0:0:0:0 | test.go | | +| test.go:29:22:29:25 | node | test.go:17:24:17:35 | selection of Body | test.go:29:22:29:25 | node | Cross-site scripting vulnerability due to $@. | test.go:17:24:17:35 | selection of Body | user-provided value | test.go:0:0:0:0 | test.go | | +| test.go:32:15:32:34 | call to Buffered | test.go:31:33:31:44 | selection of Body | test.go:32:15:32:34 | call to Buffered | Cross-site scripting vulnerability due to $@. | test.go:31:33:31:44 | selection of Body | user-provided value | test.go:0:0:0:0 | test.go | | +| test.go:33:15:33:29 | call to Raw | test.go:31:33:31:44 | selection of Body | test.go:33:15:33:29 | call to Raw | Cross-site scripting vulnerability due to $@. | test.go:31:33:31:44 | selection of Body | user-provided value | test.go:0:0:0:0 | test.go | | +| test.go:35:15:35:19 | value | test.go:31:33:31:44 | selection of Body | test.go:35:15:35:19 | value | Cross-site scripting vulnerability due to $@. | test.go:31:33:31:44 | selection of Body | user-provided value | test.go:0:0:0:0 | test.go | | +| test.go:36:15:36:30 | call to Text | test.go:31:33:31:44 | selection of Body | test.go:36:15:36:30 | call to Text | Cross-site scripting vulnerability due to $@. | test.go:31:33:31:44 | selection of Body | user-provided value | test.go:0:0:0:0 | test.go | | +| test.go:37:15:37:44 | type conversion | test.go:31:33:31:44 | selection of Body | test.go:37:15:37:44 | type conversion | Cross-site scripting vulnerability due to $@. | test.go:31:33:31:44 | selection of Body | user-provided value | test.go:0:0:0:0 | test.go | | +| test.go:40:15:40:42 | call to Buffered | test.go:39:49:39:60 | selection of Body | test.go:40:15:40:42 | call to Buffered | Cross-site scripting vulnerability due to $@. | test.go:39:49:39:60 | selection of Body | user-provided value | test.go:0:0:0:0 | test.go | | +| test.go:45:22:45:31 | &... | test.go:43:31:43:42 | selection of Body | test.go:45:22:45:31 | &... | Cross-site scripting vulnerability due to $@. | test.go:43:31:43:42 | selection of Body | user-provided value | test.go:0:0:0:0 | test.go | | +| test.go:50:22:50:32 | &... | test.go:48:32:48:43 | selection of Body | test.go:50:22:50:32 | &... | Cross-site scripting vulnerability due to $@. | test.go:48:32:48:43 | selection of Body | user-provided value | test.go:0:0:0:0 | test.go | | diff --git a/go/ql/test/library-tests/semmle/go/frameworks/XNetHtml/SqlInjection.expected b/go/ql/test/library-tests/semmle/go/frameworks/XNetHtml/SqlInjection.expected index 33a8ca661908..a36880faf24e 100644 --- a/go/ql/test/library-tests/semmle/go/frameworks/XNetHtml/SqlInjection.expected +++ b/go/ql/test/library-tests/semmle/go/frameworks/XNetHtml/SqlInjection.expected @@ -1,10 +1,10 @@ edges -| test.go:55:2:55:42 | ... := ...[0] | test.go:56:29:56:40 | selection of Value | -| test.go:56:29:56:40 | selection of Value | test.go:56:11:56:41 | call to EscapeString | +| test.go:56:2:56:42 | ... := ...[0] | test.go:57:29:57:40 | selection of Value | +| test.go:57:29:57:40 | selection of Value | test.go:57:11:57:41 | call to EscapeString | nodes -| test.go:55:2:55:42 | ... := ...[0] | semmle.label | ... := ...[0] | -| test.go:56:11:56:41 | call to EscapeString | semmle.label | call to EscapeString | -| test.go:56:29:56:40 | selection of Value | semmle.label | selection of Value | +| test.go:56:2:56:42 | ... := ...[0] | semmle.label | ... := ...[0] | +| test.go:57:11:57:41 | call to EscapeString | semmle.label | call to EscapeString | +| test.go:57:29:57:40 | selection of Value | semmle.label | selection of Value | subpaths #select -| test.go:56:11:56:41 | call to EscapeString | test.go:55:2:55:42 | ... := ...[0] | test.go:56:11:56:41 | call to EscapeString | This query depends on a $@. | test.go:55:2:55:42 | ... := ...[0] | user-provided value | +| test.go:57:11:57:41 | call to EscapeString | test.go:56:2:56:42 | ... := ...[0] | test.go:57:11:57:41 | call to EscapeString | This query depends on a $@. | test.go:56:2:56:42 | ... := ...[0] | user-provided value | diff --git a/go/ql/test/library-tests/semmle/go/frameworks/XNetHtml/test.go b/go/ql/test/library-tests/semmle/go/frameworks/XNetHtml/test.go index 0ecf7e6b27a7..a89167e126c4 100644 --- a/go/ql/test/library-tests/semmle/go/frameworks/XNetHtml/test.go +++ b/go/ql/test/library-tests/semmle/go/frameworks/XNetHtml/test.go @@ -2,16 +2,17 @@ package test import ( "database/sql" - "golang.org/x/net/html" "net/http" + + "golang.org/x/net/html" ) func test(request *http.Request, writer http.ResponseWriter) { - cookie, _ := request.Cookie("SomeCookie") - writer.Write([]byte(html.EscapeString(cookie.Value))) // GOOD: escaped. + param1 := request.URL.Query().Get("param1") + writer.Write([]byte(html.EscapeString(param1))) // GOOD: escaped. - writer.Write([]byte(html.UnescapeString(cookie.Value))) // BAD: unescaped. + writer.Write([]byte(html.UnescapeString(param1))) // BAD: unescaped. node, _ := html.Parse(request.Body) writer.Write([]byte(node.Data)) // BAD: writing unescaped HTML data diff --git a/go/ql/test/query-tests/Security/CWE-079/ReflectedXss.expected b/go/ql/test/query-tests/Security/CWE-079/ReflectedXss.expected index 31a8d0971587..6367e8681794 100644 --- a/go/ql/test/query-tests/Security/CWE-079/ReflectedXss.expected +++ b/go/ql/test/query-tests/Security/CWE-079/ReflectedXss.expected @@ -9,9 +9,6 @@ edges | contenttype.go:73:10:73:28 | call to FormValue | contenttype.go:79:11:79:14 | data | | contenttype.go:88:10:88:28 | call to FormValue | contenttype.go:91:4:91:7 | data | | contenttype.go:113:10:113:28 | call to FormValue | contenttype.go:114:50:114:53 | data | -| reflectedxsstest.go:27:2:27:38 | ... := ...[0] | reflectedxsstest.go:28:50:28:55 | cookie | -| reflectedxsstest.go:28:17:28:56 | call to Sprintf | reflectedxsstest.go:28:10:28:57 | type conversion | -| reflectedxsstest.go:28:50:28:55 | cookie | reflectedxsstest.go:28:17:28:56 | call to Sprintf | | reflectedxsstest.go:31:2:31:44 | ... := ...[0] | reflectedxsstest.go:32:34:32:37 | file | | reflectedxsstest.go:31:2:31:44 | ... := ...[1] | reflectedxsstest.go:34:46:34:60 | selection of Filename | | reflectedxsstest.go:32:2:32:38 | ... := ...[0] | reflectedxsstest.go:33:49:33:55 | content | @@ -62,10 +59,6 @@ nodes | contenttype.go:91:4:91:7 | data | semmle.label | data | | contenttype.go:113:10:113:28 | call to FormValue | semmle.label | call to FormValue | | contenttype.go:114:50:114:53 | data | semmle.label | data | -| reflectedxsstest.go:27:2:27:38 | ... := ...[0] | semmle.label | ... := ...[0] | -| reflectedxsstest.go:28:10:28:57 | type conversion | semmle.label | type conversion | -| reflectedxsstest.go:28:17:28:56 | call to Sprintf | semmle.label | call to Sprintf | -| reflectedxsstest.go:28:50:28:55 | cookie | semmle.label | cookie | | reflectedxsstest.go:31:2:31:44 | ... := ...[0] | semmle.label | ... := ...[0] | | reflectedxsstest.go:31:2:31:44 | ... := ...[1] | semmle.label | ... := ...[1] | | reflectedxsstest.go:32:2:32:38 | ... := ...[0] | semmle.label | ... := ...[0] | @@ -119,7 +112,6 @@ subpaths | contenttype.go:79:11:79:14 | data | contenttype.go:73:10:73:28 | call to FormValue | contenttype.go:79:11:79:14 | data | Cross-site scripting vulnerability due to $@. | contenttype.go:73:10:73:28 | call to FormValue | user-provided value | contenttype.go:0:0:0:0 | contenttype.go | | | contenttype.go:91:4:91:7 | data | contenttype.go:88:10:88:28 | call to FormValue | contenttype.go:91:4:91:7 | data | Cross-site scripting vulnerability due to $@. | contenttype.go:88:10:88:28 | call to FormValue | user-provided value | contenttype.go:0:0:0:0 | contenttype.go | | | contenttype.go:114:50:114:53 | data | contenttype.go:113:10:113:28 | call to FormValue | contenttype.go:114:50:114:53 | data | Cross-site scripting vulnerability due to $@. | contenttype.go:113:10:113:28 | call to FormValue | user-provided value | contenttype.go:0:0:0:0 | contenttype.go | | -| reflectedxsstest.go:28:10:28:57 | type conversion | reflectedxsstest.go:27:2:27:38 | ... := ...[0] | reflectedxsstest.go:28:10:28:57 | type conversion | Cross-site scripting vulnerability due to $@. | reflectedxsstest.go:27:2:27:38 | ... := ...[0] | user-provided value | reflectedxsstest.go:0:0:0:0 | reflectedxsstest.go | | | reflectedxsstest.go:33:10:33:57 | type conversion | reflectedxsstest.go:31:2:31:44 | ... := ...[0] | reflectedxsstest.go:33:10:33:57 | type conversion | Cross-site scripting vulnerability due to $@. | reflectedxsstest.go:31:2:31:44 | ... := ...[0] | user-provided value | reflectedxsstest.go:0:0:0:0 | reflectedxsstest.go | | | reflectedxsstest.go:34:10:34:62 | type conversion | reflectedxsstest.go:31:2:31:44 | ... := ...[1] | reflectedxsstest.go:34:10:34:62 | type conversion | Cross-site scripting vulnerability due to $@. | reflectedxsstest.go:31:2:31:44 | ... := ...[1] | user-provided value | reflectedxsstest.go:0:0:0:0 | reflectedxsstest.go | | | reflectedxsstest.go:44:10:44:55 | type conversion | reflectedxsstest.go:38:2:38:35 | ... := ...[0] | reflectedxsstest.go:44:10:44:55 | type conversion | Cross-site scripting vulnerability due to $@. | reflectedxsstest.go:38:2:38:35 | ... := ...[0] | user-provided value | reflectedxsstest.go:0:0:0:0 | reflectedxsstest.go | | diff --git a/go/ql/test/query-tests/Security/CWE-079/reflectedxsstest.go b/go/ql/test/query-tests/Security/CWE-079/reflectedxsstest.go index d1ea413c3b92..70bb248298de 100644 --- a/go/ql/test/query-tests/Security/CWE-079/reflectedxsstest.go +++ b/go/ql/test/query-tests/Security/CWE-079/reflectedxsstest.go @@ -25,7 +25,7 @@ func ServeJsonDirect(w http.ResponseWriter, r http.Request) { func ErrTest(w http.ResponseWriter, r http.Request) { cookie, err := r.Cookie("somecookie") - w.Write([]byte(fmt.Sprintf("Cookie result: %v", cookie))) // BAD: Cookie's value is user-controlled + w.Write([]byte(fmt.Sprintf("Cookie result: %v", cookie))) // GOOD: Cookie's value is not user-controlled in reflected xss. w.Write([]byte(fmt.Sprintf("Cookie check error: %v", err))) // GOOD: Cookie's err return is harmless http.Error(w, fmt.Sprintf("Cookie result: %v", cookie), 500) // Good: only plain text is written. file, header, err := r.FormFile("someFile") diff --git a/go/ql/test/query-tests/Security/CWE-681/IncorrectIntegerConversion.go b/go/ql/test/query-tests/Security/CWE-681/IncorrectIntegerConversion.go index ed0983fedc83..3f87ae51e92a 100644 --- a/go/ql/test/query-tests/Security/CWE-681/IncorrectIntegerConversion.go +++ b/go/ql/test/query-tests/Security/CWE-681/IncorrectIntegerConversion.go @@ -333,8 +333,11 @@ func testBoundsChecking(input string) { _ = uint16(parsed) _ = int16(parsed) // $ hasValueFlow="type conversion" } - if parsed < 5 { - _ = uint16(parsed) + if parsed <= 255 { + _ = uint8(parsed) + } + if parsed <= 256 { + _ = uint8(parsed) // $ hasValueFlow="type conversion" } if err == nil && 1 == 1 && parsed < math.MaxInt8 { _ = int8(parsed) @@ -349,6 +352,15 @@ func testBoundsChecking(input string) { } } +func testBoundsChecking2(input string) error { + version, err := strconv.ParseUint(input, 10, 0) + if err != nil || version > math.MaxInt { + return fmt.Errorf("checksum has invalid version: %w", err) + } + _ = int(version) + return nil +} + func testRightShifted(input string) { { parsed, err := strconv.ParseInt(input, 10, 32) diff --git a/java/documentation/library-coverage/coverage.csv b/java/documentation/library-coverage/coverage.csv index 3304352f9ef3..7d5383499397 100644 --- a/java/documentation/library-coverage/coverage.csv +++ b/java/documentation/library-coverage/coverage.csv @@ -172,7 +172,7 @@ org.springframework.cache,,,13,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,13 org.springframework.context,,,3,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,3, org.springframework.core.io,2,,,,,,,,,,,,,,,,,,,,1,,,,,,,,,1,,,,,,,,,,,,,,, org.springframework.data.repository,,,1,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1 -org.springframework.http,14,,71,,,,,,,,,,,,,,,,,,,,,,,,,,,14,,,,,,,,,,,,,,61,10 +org.springframework.http,14,,77,,,,,,,,,,,,,,,,,,,,,,,,,,,14,,,,,,,,,,,,,,67,10 org.springframework.jdbc.core,19,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,19,,,,,,,,,,,,, org.springframework.jdbc.datasource,4,,,,,,,,,,,,,,,,,,,,,,,,,,,,,4,,,,,,,,,,,,,,, org.springframework.jdbc.object,9,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,9,,,,,,,,,,,,, diff --git a/java/documentation/library-coverage/coverage.rst b/java/documentation/library-coverage/coverage.rst index a8779182dce7..ecf7b57ecb4a 100644 --- a/java/documentation/library-coverage/coverage.rst +++ b/java/documentation/library-coverage/coverage.rst @@ -21,7 +21,7 @@ Java framework & library support Java Standard Library,``java.*``,10,692,201,76,,9,,,18 Java extensions,"``javax.*``, ``jakarta.*``",67,686,42,4,4,,1,1,4 Kotlin Standard Library,``kotlin*``,,1849,16,14,,,,,2 - `Spring `_,``org.springframework.*``,29,483,115,4,,28,14,,35 + `Spring `_,``org.springframework.*``,29,489,115,4,,28,14,,35 Others,"``actions.osgi``, ``antlr``, ``cn.hutool.core.codec``, ``com.alibaba.druid.sql``, ``com.alibaba.fastjson2``, ``com.esotericsoftware.kryo.io``, ``com.esotericsoftware.kryo5.io``, ``com.fasterxml.jackson.core``, ``com.fasterxml.jackson.databind``, ``com.google.gson``, ``com.hubspot.jinjava``, ``com.jcraft.jsch``, ``com.mitchellbosecke.pebble``, ``com.opensymphony.xwork2``, ``com.rabbitmq.client``, ``com.thoughtworks.xstream``, ``com.unboundid.ldap.sdk``, ``com.zaxxer.hikari``, ``flexjson``, ``freemarker.cache``, ``freemarker.template``, ``groovy.lang``, ``groovy.text``, ``groovy.util``, ``hudson``, ``io.jsonwebtoken``, ``io.netty.bootstrap``, ``io.netty.buffer``, ``io.netty.channel``, ``io.netty.handler.codec``, ``io.netty.handler.ssl``, ``io.netty.handler.stream``, ``io.netty.resolver``, ``io.netty.util``, ``javafx.scene.web``, ``jenkins``, ``jodd.json``, ``net.sf.json``, ``net.sf.saxon.s9api``, ``ognl``, ``okhttp3``, ``org.acegisecurity``, ``org.antlr.runtime``, ``org.apache.commons.codec``, ``org.apache.commons.compress.archivers.tar``, ``org.apache.commons.exec``, ``org.apache.commons.httpclient.util``, ``org.apache.commons.jelly``, ``org.apache.commons.jexl2``, ``org.apache.commons.jexl3``, ``org.apache.commons.lang``, ``org.apache.commons.logging``, ``org.apache.commons.net``, ``org.apache.commons.ognl``, ``org.apache.cxf.catalog``, ``org.apache.cxf.common.classloader``, ``org.apache.cxf.common.jaxb``, ``org.apache.cxf.common.logging``, ``org.apache.cxf.configuration.jsse``, ``org.apache.cxf.helpers``, ``org.apache.cxf.resource``, ``org.apache.cxf.staxutils``, ``org.apache.cxf.tools.corba.utils``, ``org.apache.cxf.tools.util``, ``org.apache.cxf.transform``, ``org.apache.directory.ldap.client.api``, ``org.apache.hadoop.fs``, ``org.apache.hadoop.hive.metastore``, ``org.apache.hc.client5.http.async.methods``, ``org.apache.hc.client5.http.classic.methods``, ``org.apache.hc.client5.http.fluent``, ``org.apache.hive.hcatalog.templeton``, ``org.apache.ibatis.jdbc``, ``org.apache.log4j``, ``org.apache.shiro.codec``, ``org.apache.shiro.jndi``, ``org.apache.struts.beanvalidation.validation.interceptor``, ``org.apache.struts2``, ``org.apache.tools.ant``, ``org.apache.tools.zip``, ``org.apache.velocity.app``, ``org.apache.velocity.runtime``, ``org.codehaus.cargo.container.installer``, ``org.codehaus.groovy.control``, ``org.dom4j``, ``org.eclipse.jetty.client``, ``org.fusesource.leveldbjni``, ``org.geogebra.web.full.main``, ``org.gradle.api.file``, ``org.hibernate``, ``org.influxdb``, ``org.jdbi.v3.core``, ``org.jenkins.ui.icon``, ``org.jenkins.ui.symbol``, ``org.jooq``, ``org.kohsuke.stapler``, ``org.mvel2``, ``org.openjdk.jmh.runner.options``, ``org.owasp.esapi``, ``org.scijava.log``, ``org.slf4j``, ``org.thymeleaf``, ``org.xml.sax``, ``org.xmlpull.v1``, ``org.yaml.snakeyaml``, ``play.libs.ws``, ``play.mvc``, ``ratpack.core.form``, ``ratpack.core.handling``, ``ratpack.core.http``, ``ratpack.exec``, ``ratpack.form``, ``ratpack.func``, ``ratpack.handling``, ``ratpack.http``, ``ratpack.util``, ``retrofit2``",131,10503,706,116,6,18,18,,208 - Totals,,299,18891,2200,315,16,122,33,1,401 + Totals,,299,18897,2200,315,16,122,33,1,401 diff --git a/java/ql/automodel/src/README.md b/java/ql/automodel/src/README.md new file mode 100644 index 000000000000..317947bda1a4 --- /dev/null +++ b/java/ql/automodel/src/README.md @@ -0,0 +1,183 @@ +# Automodel Java Extraction Queries + +This pack contains the automodel extraction queries for Java. Automodel uses extraction queries to extract the information it needs in order to create a prompt for a large language model. There's extraction queries for positive examples (things that are known to be, e.g., a sink), for negative examples (things that are known not to be, e.g., a sink), and for candidates (things where we should ask the large language model to classify). + +## Extraction Queries in `java/ql/automodel/src` + +Included in this pack are queries for both application mode and framework mode. + +| Kind | Mode | Query File | +|------|------|------------| +| Candidates | Application Mode | [AutomodelApplicationModeExtractCandidates.ql](https://github.com/github/codeql/blob/main/java/ql/automodel/src/AutomodelApplicationModeExtractCandidates.ql) | +| Positive Examples | Application Mode | [AutomodelApplicationModeExtractPositiveExamples.ql](https://github.com/github/codeql/blob/main/java/ql/automodel/src/AutomodelApplicationModeExtractPositiveExamples.ql) | +| Negative Examples | Application Mode | [AutomodelApplicationModeExtractNegativeExamples.ql](https://github.com/github/codeql/blob/main/java/ql/automodel/src/AutomodelApplicationModeExtractNegativeExamples.ql) | +| Candidates | Framework Mode | [AutomodelFrameworkModeExtractCandidates.ql](https://github.com/github/codeql/blob/main/java/ql/automodel/src/AutomodelFrameworkModeExtractCandidates.ql) | +| Positive Examples | Framework Mode | [AutomodelFrameworkModeExtractPositiveExamples.ql](https://github.com/github/codeql/blob/main/java/ql/automodel/src/AutomodelFrameworkModeExtractPositiveExamples.ql) | +| Negative Examples | Framework Mode | [AutomodelFrameworkModeExtractNegativeExamples.ql](https://github.com/github/codeql/blob/main/java/ql/automodel/src/AutomodelFrameworkModeExtractNegativeExamples.ql) | + +## Running the Queries + +The extraction queries are part of a separate query pack, `codeql/java-automodel-queries`. Use this pack to run them. The queries are tagged appropriately, you can use the tags (example here: https://github.com/github/codeql/blob/main/java/ql/automodel/src/AutomodelApplicationModeExtractNegativeExamples.ql#L8) to construct query suites. + +For example, a query suite selecting all example extraction queries (positive and negative) for application mode looks like this: + +``` +# File: automodel-application-mode-extraction-examples.qls +# --- +# Query suite for extracting examples for automodel + +- description: Automodel application mode examples extraction. +- queries: . + from: codeql/java-automodel-queries +- include: + tags contain all: + - automodel + - extract + - application-mode + - examples +``` + +## Important Software Design Concepts and Goals + +### Concept: `Endpoint` + +Endpoints are source code locations of interest. All positive examples, negative examples, and all candidates are endpoints, but not all endpoints are examples or candidates. Each mode decides which endpoints are relevant. For instance, if the Java application mode wants to support candidates for sinks that are arguments passed to unknown method calls, then the Java application mode implementation needs to make sure that method arguments are endpoints. If you look at the `TApplicationModeEndpoint` implementation in [AutomodelApplicationModeCharacteristics.qll](https://github.com/github/codeql/blob/main/java/ql/automodel/src/AutomodelApplicationModeCharacteristics.qll), you can see that this is the case: the `TExplicitArgument` implements this behavior. + +Whether or not an endpoint is a positive/negative example, or a candidate depends on the individual extraction queries. + +### Concept: `EndpointCharacteristics` + +In the file [AutomodelSharedCharacteristics.ql](https://github.com/github/codeql/blob/main/java/ql/automodel/src/AutomodelSharedCharacteristics.ql), you will find the definition of the QL class `EndpointCharacteristic`. + +An endpoint characteristic is a QL class that "tags" all endpoints for which the characteristic's `appliesToEndpoint` predicate holds. The characteristic defines a `hasImplications` predicate that declares whether all the endpoints should be considered as sinks/sources/negatives, and with which confidence. + +The positive, negative, and candidate extraction queries largely[^1] use characteristics to decide which endpoint to select. For instance, if a characteristic exists that applies to an endpoint, and the characteristic implies (cf. `hasImplications`) that the endpoint is a sink with a high confidence – then that endpoint will be selected as a positive example. See the use of `isKnownAs` in [AutomodelFrameworkModeExtractPositiveExamples.ql](https://github.com/github/codeql/blob/main/java/ql/automodel/src/AutomodelFrameworkModeExtractPositiveExamples.ql). + +[^1]: Candidate extraction queries are an exception, they treat `UninterestingToModelCharacteristic` differently. + +#### :warning: Warning + +Do not try to "fix" shortcomings that could be fixed by a better prompt or better example selection by adding language- or mode-specific characteristics . Those "fixes" tend to be confusing downstream when questions like "why wasn't this location selected as a candidate?" becomes progressively harder and harder to answer. It's best to rely on characteristics in the code that is shared across all languages and modes (see [Shared Code](#shared-code)). + +## Shared Code + +A significant part of the behavior of extraction queries is implemented in shared modules. When we add support for new languages, we expect to move the shared code to a separate QL pack. In the mean time, shared code modules must not import any java libraries. + +## Packaging + +Automodel extraction queries come as a dedicated package. See [qlpack.yml](https://github.com/github/codeql/blob/main/java/ql/automodel/src/qlpack.yml). The [publish.sh](https://github.com/github/codeql/blob/main/java/ql/automodel/publish.sh) script is responsible for publishing a new version to the [package registry](https://github.com/orgs/codeql/packages/container/package/java-automodel-queries). + +### Backwards Compatibility + +We try to keep changes to extraction queries backwards-compatible whenever feasible. There's several reasons: + + - That automodel can always decide which version of the package to run is a flawed assumption. We don't have direct control over the version of the extraction queries running on the user's local machine. + - An automodel deployment will sometimes require the extraction queries to be published. If the new version of the extraction queries works with the old version of automodel, then it is much easier to roll back deployments of automodel. + +## Candidate Examples + +This section contains a few examples of the kinds of candidates that our queries might select, and why. + +:warning: For clarity, this section presents "candidates" that are **actual** sinks. Therefore, the candidates presented here would actually be selected as positive examples in practice - rather than as candidates. + +### Framework Mode Candidates + +Framework mode is special because in framework mode, we extract candidates (as well as examples) from the implementation of a framework or library while the resulting models are applied in code bases that are _using_ the framework or library. + +In framework mode, endpoints currently can have a number of shapes (see: `newtype TFrameworkModeEndpoint` in [AutomodelApplicationModeExtractCandidates.ql](https://github.com/github/codeql/blob/main/java/ql/automodel/src/AutomodelFrameworkModeCharacteristics.qll)). Depending on what kind of endpoint it is, the candidate is a candidate for one or several extensible types (eg., `sinkModel`, `sourceModel`). + +#### Framework Mode Sink Candidates + +Sink candidates in framework mode are modelled as formal parameters of functions defined within the framework. We use these to represent the corresponding inputs of function calls in a client codebase, which would be passed into those parameters. + +For example, customer code could call the `Files.copy` method: + +```java +// customer code using a library +... +Files.copy(userInputPath, outStream); +... +``` + +In order for `userInputPath` to be modeled as a sink, the corresponding parameter must be selected as a candidate. In the following example, assuming they're not modeled yet, the parameters `source` and `out` would be candidates: + +```java +// Files.java +// library code that's analyzed in framework mode +public class Files { + public static void copy(Path source, OutputStream out) throws IOException { + // ... + } +} +``` + +#### Framework Mode Source Candidates + +Source candidates are a bit more varied than sink candidates: + +##### Parameters as Source Candidates + +A parameter could be a source, e.g. when a framework passes user-controlled data to a handler defined in customer code. +```java +// customer code using a library: +import java.net.http.WebSocket; + +final class MyListener extends WebSocket.Listener { + @override + public CompletionStage onText(WebSocket ws, CharSequence cs, boolean last) { + ... process data that was received from websocket + } +} +``` + +In this case, data passed to the program via a web socket connection is a source of remote data. Therefore, when we look at the implementation of `WebSocket.Listener` in framework mode, we need to produce a candidate for each parameter: + +```java +// WebSocket.java +// library code that's analyzed in framework mode +interface Listener { + ... + default CompletionStage onText(WebSocket webSocket CharSequence data, boolean last) { + // + } + ... +} +``` + +For framework mode, all parameters of the `onText` method should be candidates. If the candidates result in a model, the parameters of classes implementing this interface will be recognized as sources of remote data. + +:warning: a consequence of this is that we can have endpoints in framework mode that are both sink candidates, as well as source candidates. + +##### Return Values as Source Candidates + +The other kind of source candidate we model is the return value of a method. For example: + +```java +public class Socket { + ... + public InputStream getInputStream() throws IOException { + ... + } + ... +} +``` + +This method returns a source of remote data that should be modeled as a sink. We therefore want to select the _method_ as a candidate. + +### Application Mode Candidates + +In application mode, we extract candidates from an application that is using various libraries. + +#### Application Mode Source Candidates + +##### Overridden Parameters as Source Candidates + +In application mode, a parameter of a method that is overriding another method is taken as a source parameter to account for cases like the `WebSocket.Listener` example above where an application is implementing a "handler" that receives remote data. + +##### Return Values as Source Candidates + +Just like in framework mode, application mode also has to consider the return value of a call as a source candidate. The difference is that in application mode, we extract from the application sources, not the library sources. Therefore, we use the invocation expression as a candidate (unlike in framework mode, where we use the method definition). + +#### Application Mode Sink Candidates + +In application mode, arguments to calls are sink candidates. diff --git a/java/ql/consistency-queries/calls.ql b/java/ql/consistency-queries/calls.ql index 78ebc3fa9a68..85f4f47f38dd 100644 --- a/java/ql/consistency-queries/calls.ql +++ b/java/ql/consistency-queries/calls.ql @@ -1,6 +1,6 @@ import java -from MethodAccess ma +from MethodCall ma // Generally Kotlin calls will always use an explicit qualifier, except for calls // to the synthetic instance initializer , which use an implicit `this`. where diff --git a/java/ql/consistency-queries/cfgDeadEnds.ql b/java/ql/consistency-queries/cfgDeadEnds.ql index c0f2e6cfe1ff..73c30015a6fc 100644 --- a/java/ql/consistency-queries/cfgDeadEnds.ql +++ b/java/ql/consistency-queries/cfgDeadEnds.ql @@ -44,7 +44,7 @@ predicate shouldBeDeadEnd(ControlFlowNode n) { or n instanceof WildcardTypeAccess // TODO or - n instanceof MethodAccess // TODO + n instanceof MethodCall // TODO or n instanceof Method or diff --git a/java/ql/consistency-queries/children.ql b/java/ql/consistency-queries/children.ql index b22fd56d0446..7386ee79c000 100644 --- a/java/ql/consistency-queries/children.ql +++ b/java/ql/consistency-queries/children.ql @@ -37,11 +37,11 @@ predicate gapInChildren(Element e, int i) { // For statements may or may not declare a new variable (child 0), or // have a condition (child 1). not (e instanceof ForStmt and i = [0, 1]) and - // TODO: Clarify situation with Kotlin and MethodAccess. + // TODO: Clarify situation with Kotlin and MethodCall. // -1 can be skipped (type arguments from -2 down, no qualifier at -1, // then arguments from 0). // Can we also skip arguments, e.g. due to defaults for parameters? - not (e instanceof MethodAccess and e.getFile().isKotlinSourceFile()) and + not (e instanceof MethodCall and e.getFile().isKotlinSourceFile()) and // Kotlin-extracted annotations can have missing children where a default // value should be, because kotlinc doesn't load annotation defaults and we // want to leave a space for another extractor to fill in the default if it diff --git a/java/ql/examples/snippets/method_call.ql b/java/ql/examples/snippets/method_call.ql index e7bd527ef44d..7c4296f49af6 100644 --- a/java/ql/examples/snippets/method_call.ql +++ b/java/ql/examples/snippets/method_call.ql @@ -8,7 +8,7 @@ import java -from MethodAccess call, Method method +from MethodCall call, Method method where call.getMethod() = method and method.hasName("methodName") and diff --git a/java/ql/examples/snippets/mutualrecursion.ql b/java/ql/examples/snippets/mutualrecursion.ql index 67a3f12e7807..71d038c16e8d 100644 --- a/java/ql/examples/snippets/mutualrecursion.ql +++ b/java/ql/examples/snippets/mutualrecursion.ql @@ -10,7 +10,7 @@ import java from Method m, Method n where - exists(MethodAccess ma | ma.getCaller() = m and ma.getCallee() = n) and - exists(MethodAccess ma | ma.getCaller() = n and ma.getCallee() = m) and + exists(MethodCall ma | ma.getCaller() = m and ma.getCallee() = n) and + exists(MethodCall ma | ma.getCaller() = n and ma.getCallee() = m) and m != n select m, n diff --git a/java/ql/examples/snippets/null_argument.ql b/java/ql/examples/snippets/null_argument.ql index 116642b8aaf6..68523b812e41 100644 --- a/java/ql/examples/snippets/null_argument.ql +++ b/java/ql/examples/snippets/null_argument.ql @@ -11,7 +11,7 @@ import java -from MethodAccess call, Method add +from MethodCall call, Method add where call.getMethod().overrides*(add) and add.hasName("add") and diff --git a/java/ql/integration-tests/all-platforms/kotlin/annotation-id-consistency/PrintAst.expected b/java/ql/integration-tests/all-platforms/kotlin/annotation-id-consistency/PrintAst.expected index 6da5da6d522f..ce525f1727be 100644 --- a/java/ql/integration-tests/all-platforms/kotlin/annotation-id-consistency/PrintAst.expected +++ b/java/ql/integration-tests/all-platforms/kotlin/annotation-id-consistency/PrintAst.expected @@ -10,10 +10,10 @@ User.java: # 3| 0: [TypeAccess] Ann2 # 3| 5: [BlockStmt] { ... } # 4| 0: [ExprStmt] ; -# 4| 0: [MethodAccess] x(...) +# 4| 0: [MethodCall] x(...) # 4| -1: [VarAccess] a1 # 4| 1: [ExprStmt] ; -# 4| 0: [MethodAccess] z(...) +# 4| 0: [MethodCall] z(...) # 4| -1: [VarAccess] a2 # 4| 2: [ExprStmt] ; # 4| 0: [ClassInstanceExpr] new Annotated(...) @@ -49,7 +49,7 @@ ktUser.kt: # 8| 3: [ExprStmt] ; # 8| 0: [ImplicitCoercionToUnitExpr] # 8| 0: [TypeAccess] Unit -# 8| 1: [MethodAccess] isJavaLetter(...) +# 8| 1: [MethodCall] isJavaLetter(...) # 8| -1: [TypeAccess] Character # 8| 0: [CharacterLiteral] a test.kt: diff --git a/java/ql/integration-tests/all-platforms/kotlin/default-parameter-mad-flow/test.ql b/java/ql/integration-tests/all-platforms/kotlin/default-parameter-mad-flow/test.ql index 65f447971164..fe412adce903 100644 --- a/java/ql/integration-tests/all-platforms/kotlin/default-parameter-mad-flow/test.ql +++ b/java/ql/integration-tests/all-platforms/kotlin/default-parameter-mad-flow/test.ql @@ -5,7 +5,7 @@ private import semmle.code.java.dataflow.ExternalFlow module Config implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node n) { - n.asExpr().(MethodAccess).getCallee().getName() = "source" + n.asExpr().(MethodCall).getCallee().getName() = "source" or sourceNode(n, "kotlinMadFlowTest") } diff --git a/java/ql/integration-tests/all-platforms/kotlin/external-property-overloads/test.ql b/java/ql/integration-tests/all-platforms/kotlin/external-property-overloads/test.ql index 9e692390fa84..ef2918cb9554 100644 --- a/java/ql/integration-tests/all-platforms/kotlin/external-property-overloads/test.ql +++ b/java/ql/integration-tests/all-platforms/kotlin/external-property-overloads/test.ql @@ -1,4 +1,4 @@ import java -from MethodAccess ma +from MethodCall ma select ma, ma.getCallee() diff --git a/java/ql/integration-tests/all-platforms/kotlin/gradle_kotlinx_serialization/PrintAst.expected b/java/ql/integration-tests/all-platforms/kotlin/gradle_kotlinx_serialization/PrintAst.expected index a81cadccd10c..752db3cd6471 100644 --- a/java/ql/integration-tests/all-platforms/kotlin/gradle_kotlinx_serialization/PrintAst.expected +++ b/java/ql/integration-tests/all-platforms/kotlin/gradle_kotlinx_serialization/PrintAst.expected @@ -31,11 +31,11 @@ app/src/main/kotlin/testProject/App.kt: # 7| 0: [IntegerLiteral] 3 # 7| 1: [VarAccess] seen1 # 7| 1: [ExprStmt] ; -# 7| 0: [MethodAccess] throwMissingFieldException(...) +# 7| 0: [MethodCall] throwMissingFieldException(...) # 7| -1: [TypeAccess] PluginExceptionsKt # 7| 0: [VarAccess] seen1 # 7| 1: [IntegerLiteral] 3 -# 7| 2: [MethodAccess] getDescriptor(...) +# 7| 2: [MethodCall] getDescriptor(...) # 7| -1: [VarAccess] INSTANCE # 7| 1: [SuperConstructorInvocationStmt] super(...) # 7| 2: [ExprStmt] ; @@ -118,7 +118,7 @@ app/src/main/kotlin/testProject/App.kt: # 0| 1: [VarAccess] p0.language # 0| -1: [VarAccess] p0 # 0| 2: [ReturnStmt] return ... -# 0| 0: [MethodAccess] copy(...) +# 0| 0: [MethodCall] copy(...) # 0| -1: [VarAccess] p0 # 0| 0: [VarAccess] p1 # 0| 1: [VarAccess] p2 @@ -176,7 +176,7 @@ app/src/main/kotlin/testProject/App.kt: # 0| 5: [BlockStmt] { ... } # 0| 0: [LocalVariableDeclStmt] var ...; # 0| 1: [LocalVariableDeclExpr] result -# 0| 0: [MethodAccess] hashCode(...) +# 0| 0: [MethodCall] hashCode(...) # 0| -1: [VarAccess] this.name # 0| -1: [ThisAccess] this # 0| 1: [ExprStmt] ; @@ -186,7 +186,7 @@ app/src/main/kotlin/testProject/App.kt: # 0| 0: [MulExpr] ... * ... # 0| 0: [VarAccess] result # 0| 1: [IntegerLiteral] 31 -# 0| 1: [MethodAccess] hashCode(...) +# 0| 1: [MethodCall] hashCode(...) # 0| -1: [VarAccess] this.language # 0| -1: [ThisAccess] this # 0| 2: [ReturnStmt] return ... @@ -226,18 +226,18 @@ app/src/main/kotlin/testProject/App.kt: # 0| 0: [TypeAccess] SerialDescriptor # 7| 5: [BlockStmt] { ... } # 7| 0: [ExprStmt] ; -# 7| 0: [MethodAccess] encodeStringElement(...) +# 7| 0: [MethodCall] encodeStringElement(...) # 7| -1: [VarAccess] output # 7| 0: [VarAccess] serialDesc # 7| 1: [IntegerLiteral] 0 -# 7| 2: [MethodAccess] getName(...) +# 7| 2: [MethodCall] getName(...) # 7| -1: [VarAccess] self # 7| 1: [ExprStmt] ; -# 7| 0: [MethodAccess] encodeIntElement(...) +# 7| 0: [MethodCall] encodeIntElement(...) # 7| -1: [VarAccess] output # 7| 0: [VarAccess] serialDesc # 7| 1: [IntegerLiteral] 1 -# 7| 2: [MethodAccess] getLanguage(...) +# 7| 2: [MethodCall] getLanguage(...) # 7| -1: [VarAccess] self # 7| 10: [Class] $serializer #-----| -3: (Annotations) @@ -274,7 +274,7 @@ app/src/main/kotlin/testProject/App.kt: # 7| 5: [BlockStmt] { ... } # 7| 0: [LocalVariableDeclStmt] var ...; # 7| 1: [LocalVariableDeclExpr] tmp0_desc -# 7| 0: [MethodAccess] getDescriptor(...) +# 7| 0: [MethodCall] getDescriptor(...) # 7| -1: [ThisAccess] this # 7| 1: [LocalVariableDeclStmt] var ...; # 7| 1: [LocalVariableDeclExpr] tmp1_flag @@ -293,20 +293,20 @@ app/src/main/kotlin/testProject/App.kt: # 7| 0: [IntegerLiteral] 0 # 7| 6: [LocalVariableDeclStmt] var ...; # 7| 1: [LocalVariableDeclExpr] tmp6_input -# 7| 0: [MethodAccess] beginStructure(...) +# 7| 0: [MethodCall] beginStructure(...) # 7| -1: [VarAccess] decoder # 7| 0: [VarAccess] tmp0_desc # 7| 7: [ExprStmt] ; # 7| 0: [WhenExpr] when ... # 7| 0: [WhenBranch] ... -> ... -# 7| 0: [MethodAccess] decodeSequentially(...) +# 7| 0: [MethodCall] decodeSequentially(...) # 7| -1: [VarAccess] tmp6_input # 7| 1: [BlockStmt] { ... } # 7| 0: [BlockStmt] { ... } # 7| 0: [ExprStmt] ; # 7| 0: [AssignExpr] ...=... # 7| 0: [VarAccess] tmp4_local0 -# 7| 1: [MethodAccess] decodeStringElement(...) +# 7| 1: [MethodCall] decodeStringElement(...) # 7| -1: [VarAccess] tmp6_input # 7| 0: [VarAccess] tmp0_desc # 7| 1: [IntegerLiteral] 0 @@ -320,7 +320,7 @@ app/src/main/kotlin/testProject/App.kt: # 7| 0: [ExprStmt] ; # 7| 0: [AssignExpr] ...=... # 7| 0: [VarAccess] tmp5_local1 -# 7| 1: [MethodAccess] decodeIntElement(...) +# 7| 1: [MethodCall] decodeIntElement(...) # 7| -1: [VarAccess] tmp6_input # 7| 0: [VarAccess] tmp0_desc # 7| 1: [IntegerLiteral] 1 @@ -338,7 +338,7 @@ app/src/main/kotlin/testProject/App.kt: # 7| 0: [ExprStmt] ; # 7| 0: [AssignExpr] ...=... # 7| 0: [VarAccess] tmp2_index -# 7| 1: [MethodAccess] decodeElementIndex(...) +# 7| 1: [MethodCall] decodeElementIndex(...) # 7| -1: [VarAccess] tmp6_input # 7| 0: [VarAccess] tmp0_desc # 7| 1: [ExprStmt] ; @@ -359,7 +359,7 @@ app/src/main/kotlin/testProject/App.kt: # 7| 0: [ExprStmt] ; # 7| 0: [AssignExpr] ...=... # 7| 0: [VarAccess] tmp4_local0 -# 7| 1: [MethodAccess] decodeStringElement(...) +# 7| 1: [MethodCall] decodeStringElement(...) # 7| -1: [VarAccess] tmp6_input # 7| 0: [VarAccess] tmp0_desc # 7| 1: [IntegerLiteral] 0 @@ -377,7 +377,7 @@ app/src/main/kotlin/testProject/App.kt: # 7| 0: [ExprStmt] ; # 7| 0: [AssignExpr] ...=... # 7| 0: [VarAccess] tmp5_local1 -# 7| 1: [MethodAccess] decodeIntElement(...) +# 7| 1: [MethodCall] decodeIntElement(...) # 7| -1: [VarAccess] tmp6_input # 7| 0: [VarAccess] tmp0_desc # 7| 1: [IntegerLiteral] 1 @@ -394,7 +394,7 @@ app/src/main/kotlin/testProject/App.kt: # 7| -3: [TypeAccess] UnknownFieldException # 7| 0: [VarAccess] tmp2_index # 7| 8: [ExprStmt] ; -# 7| 0: [MethodAccess] endStructure(...) +# 7| 0: [MethodCall] endStructure(...) # 7| -1: [VarAccess] tmp6_input # 7| 0: [VarAccess] tmp0_desc # 7| 9: [ReturnStmt] return ... @@ -426,21 +426,21 @@ app/src/main/kotlin/testProject/App.kt: # 7| 5: [BlockStmt] { ... } # 7| 0: [LocalVariableDeclStmt] var ...; # 7| 1: [LocalVariableDeclExpr] tmp0_desc -# 7| 0: [MethodAccess] getDescriptor(...) +# 7| 0: [MethodCall] getDescriptor(...) # 7| -1: [ThisAccess] this # 7| 1: [LocalVariableDeclStmt] var ...; # 7| 1: [LocalVariableDeclExpr] tmp1_output -# 7| 0: [MethodAccess] beginStructure(...) +# 7| 0: [MethodCall] beginStructure(...) # 7| -1: [VarAccess] encoder # 7| 0: [VarAccess] tmp0_desc # 7| 2: [ExprStmt] ; -# 7| 0: [MethodAccess] write$Self(...) +# 7| 0: [MethodCall] write$Self(...) # 7| -1: [TypeAccess] Project # 7| 0: [VarAccess] value # 7| 1: [VarAccess] tmp1_output # 7| 2: [VarAccess] tmp0_desc # 7| 3: [ExprStmt] ; -# 7| 0: [MethodAccess] endStructure(...) +# 7| 0: [MethodCall] endStructure(...) # 7| -1: [VarAccess] tmp1_output # 7| 0: [VarAccess] tmp0_desc # 7| 6: [Constructor] $serializer @@ -456,12 +456,12 @@ app/src/main/kotlin/testProject/App.kt: # 7| 0: [TypeAccess] $serializer # 7| 2: [IntegerLiteral] 2 # 7| 1: [ExprStmt] ; -# 7| 0: [MethodAccess] addElement(...) +# 7| 0: [MethodCall] addElement(...) # 7| -1: [VarAccess] tmp0_serialDesc # 7| 0: [StringLiteral] "name" # 7| 1: [BooleanLiteral] false # 7| 2: [ExprStmt] ; -# 7| 0: [MethodAccess] addElement(...) +# 7| 0: [MethodCall] addElement(...) # 7| -1: [VarAccess] tmp0_serialDesc # 7| 0: [StringLiteral] "language" # 7| 1: [BooleanLiteral] false @@ -477,7 +477,7 @@ app/src/main/kotlin/testProject/App.kt: # 7| 0: [WildcardTypeAccess] ? ... # 7| 5: [BlockStmt] { ... } # 7| 0: [ReturnStmt] return ... -# 7| 0: [MethodAccess] typeParametersSerializers(...) +# 7| 0: [MethodCall] typeParametersSerializers(...) # 7| -1: [SuperAccess] GeneratedSerializer.super # 7| 0: [TypeAccess] GeneratedSerializer # 7| 11: [Class] Companion @@ -564,11 +564,11 @@ app/src/main/kotlin/testProject/App.kt: # 14| 0: [IntegerLiteral] 0 # 14| 1: [VarAccess] seen1 # 14| 1: [ExprStmt] ; -# 14| 0: [MethodAccess] throwMissingFieldException(...) +# 14| 0: [MethodCall] throwMissingFieldException(...) # 14| -1: [TypeAccess] PluginExceptionsKt # 14| 0: [VarAccess] seen1 # 14| 1: [IntegerLiteral] 0 -# 14| 2: [MethodAccess] getDescriptor(...) +# 14| 2: [MethodCall] getDescriptor(...) # 14| -1: [VarAccess] INSTANCE # 14| 1: [SuperConstructorInvocationStmt] super(...) # 14| 2: [ExprStmt] ; @@ -616,7 +616,7 @@ app/src/main/kotlin/testProject/App.kt: # 14| 0: [WhenBranch] ... -> ... # 14| 0: [WhenExpr] when ... # 14| 0: [WhenBranch] ... -> ... -# 14| 0: [MethodAccess] shouldEncodeElementDefault(...) +# 14| 0: [MethodCall] shouldEncodeElementDefault(...) # 14| -1: [VarAccess] output # 14| 0: [VarAccess] serialDesc # 14| 1: [IntegerLiteral] 0 @@ -626,15 +626,15 @@ app/src/main/kotlin/testProject/App.kt: # 14| 0: [BooleanLiteral] true # 14| 1: [ExprStmt] ; # 14| 0: [ValueNEExpr] ... (value not-equals) ... -# 14| 0: [MethodAccess] getId(...) +# 14| 0: [MethodCall] getId(...) # 14| -1: [VarAccess] self # 16| 1: [StringLiteral] "X" # 14| 1: [ExprStmt] ; -# 14| 0: [MethodAccess] encodeStringElement(...) +# 14| 0: [MethodCall] encodeStringElement(...) # 14| -1: [VarAccess] output # 14| 0: [VarAccess] serialDesc # 14| 1: [IntegerLiteral] 0 -# 14| 2: [MethodAccess] getId(...) +# 14| 2: [MethodCall] getId(...) # 14| -1: [VarAccess] self # 14| 3: [Class] $serializer #-----| -3: (Annotations) @@ -671,7 +671,7 @@ app/src/main/kotlin/testProject/App.kt: # 14| 5: [BlockStmt] { ... } # 14| 0: [LocalVariableDeclStmt] var ...; # 14| 1: [LocalVariableDeclExpr] tmp0_desc -# 14| 0: [MethodAccess] getDescriptor(...) +# 14| 0: [MethodCall] getDescriptor(...) # 14| -1: [ThisAccess] this # 14| 1: [LocalVariableDeclStmt] var ...; # 14| 1: [LocalVariableDeclExpr] tmp1_flag @@ -687,20 +687,20 @@ app/src/main/kotlin/testProject/App.kt: # 14| 0: [NullLiteral] null # 14| 5: [LocalVariableDeclStmt] var ...; # 14| 1: [LocalVariableDeclExpr] tmp5_input -# 14| 0: [MethodAccess] beginStructure(...) +# 14| 0: [MethodCall] beginStructure(...) # 14| -1: [VarAccess] decoder # 14| 0: [VarAccess] tmp0_desc # 14| 6: [ExprStmt] ; # 14| 0: [WhenExpr] when ... # 14| 0: [WhenBranch] ... -> ... -# 14| 0: [MethodAccess] decodeSequentially(...) +# 14| 0: [MethodCall] decodeSequentially(...) # 14| -1: [VarAccess] tmp5_input # 14| 1: [BlockStmt] { ... } # 14| 0: [BlockStmt] { ... } # 14| 0: [ExprStmt] ; # 14| 0: [AssignExpr] ...=... # 14| 0: [VarAccess] tmp4_local0 -# 14| 1: [MethodAccess] decodeStringElement(...) +# 14| 1: [MethodCall] decodeStringElement(...) # 14| -1: [VarAccess] tmp5_input # 14| 0: [VarAccess] tmp0_desc # 14| 1: [IntegerLiteral] 0 @@ -718,7 +718,7 @@ app/src/main/kotlin/testProject/App.kt: # 14| 0: [ExprStmt] ; # 14| 0: [AssignExpr] ...=... # 14| 0: [VarAccess] tmp2_index -# 14| 1: [MethodAccess] decodeElementIndex(...) +# 14| 1: [MethodCall] decodeElementIndex(...) # 14| -1: [VarAccess] tmp5_input # 14| 0: [VarAccess] tmp0_desc # 14| 1: [ExprStmt] ; @@ -739,7 +739,7 @@ app/src/main/kotlin/testProject/App.kt: # 14| 0: [ExprStmt] ; # 14| 0: [AssignExpr] ...=... # 14| 0: [VarAccess] tmp4_local0 -# 14| 1: [MethodAccess] decodeStringElement(...) +# 14| 1: [MethodCall] decodeStringElement(...) # 14| -1: [VarAccess] tmp5_input # 14| 0: [VarAccess] tmp0_desc # 14| 1: [IntegerLiteral] 0 @@ -756,7 +756,7 @@ app/src/main/kotlin/testProject/App.kt: # 14| -3: [TypeAccess] UnknownFieldException # 14| 0: [VarAccess] tmp2_index # 14| 7: [ExprStmt] ; -# 14| 0: [MethodAccess] endStructure(...) +# 14| 0: [MethodCall] endStructure(...) # 14| -1: [VarAccess] tmp5_input # 14| 0: [VarAccess] tmp0_desc # 14| 8: [ReturnStmt] return ... @@ -787,21 +787,21 @@ app/src/main/kotlin/testProject/App.kt: # 14| 5: [BlockStmt] { ... } # 14| 0: [LocalVariableDeclStmt] var ...; # 14| 1: [LocalVariableDeclExpr] tmp0_desc -# 14| 0: [MethodAccess] getDescriptor(...) +# 14| 0: [MethodCall] getDescriptor(...) # 14| -1: [ThisAccess] this # 14| 1: [LocalVariableDeclStmt] var ...; # 14| 1: [LocalVariableDeclExpr] tmp1_output -# 14| 0: [MethodAccess] beginStructure(...) +# 14| 0: [MethodCall] beginStructure(...) # 14| -1: [VarAccess] encoder # 14| 0: [VarAccess] tmp0_desc # 14| 2: [ExprStmt] ; -# 14| 0: [MethodAccess] write$Self(...) +# 14| 0: [MethodCall] write$Self(...) # 14| -1: [TypeAccess] X # 14| 0: [VarAccess] value # 14| 1: [VarAccess] tmp1_output # 14| 2: [VarAccess] tmp0_desc # 14| 3: [ExprStmt] ; -# 14| 0: [MethodAccess] endStructure(...) +# 14| 0: [MethodCall] endStructure(...) # 14| -1: [VarAccess] tmp1_output # 14| 0: [VarAccess] tmp0_desc # 14| 6: [Constructor] $serializer @@ -817,7 +817,7 @@ app/src/main/kotlin/testProject/App.kt: # 14| 0: [TypeAccess] $serializer # 14| 2: [IntegerLiteral] 1 # 14| 1: [ExprStmt] ; -# 14| 0: [MethodAccess] addElement(...) +# 14| 0: [MethodCall] addElement(...) # 14| -1: [VarAccess] tmp0_serialDesc # 14| 0: [StringLiteral] "id" # 14| 1: [BooleanLiteral] true @@ -833,7 +833,7 @@ app/src/main/kotlin/testProject/App.kt: # 14| 0: [WildcardTypeAccess] ? ... # 14| 5: [BlockStmt] { ... } # 14| 0: [ReturnStmt] return ... -# 14| 0: [MethodAccess] typeParametersSerializers(...) +# 14| 0: [MethodCall] typeParametersSerializers(...) # 14| -1: [SuperAccess] GeneratedSerializer.super # 14| 0: [TypeAccess] GeneratedSerializer # 14| 4: [Class] Companion diff --git a/java/ql/integration-tests/all-platforms/kotlin/nested_generic_types/test.ql b/java/ql/integration-tests/all-platforms/kotlin/nested_generic_types/test.ql index 5e6bd22674a6..b92e3466a87d 100644 --- a/java/ql/integration-tests/all-platforms/kotlin/nested_generic_types/test.ql +++ b/java/ql/integration-tests/all-platforms/kotlin/nested_generic_types/test.ql @@ -30,9 +30,7 @@ query predicate nestedTypes(NestedType nt, RefType parent) { parent = nt.getEnclosingType() } -query predicate javaKotlinCalleeAgreement( - MethodAccess javaMa, MethodAccess kotlinMa, Callable callee -) { +query predicate javaKotlinCalleeAgreement(MethodCall javaMa, MethodCall kotlinMa, Callable callee) { javaMa.getCallee() = callee and kotlinMa.getCallee() = callee and javaMa.getFile().getExtension() = "java" and diff --git a/java/ql/integration-tests/linux-only/kotlin/custom_plugin/PrintAst.expected b/java/ql/integration-tests/linux-only/kotlin/custom_plugin/PrintAst.expected index 6921b7541ad5..8d6c37e053a2 100644 --- a/java/ql/integration-tests/linux-only/kotlin/custom_plugin/PrintAst.expected +++ b/java/ql/integration-tests/linux-only/kotlin/custom_plugin/PrintAst.expected @@ -39,7 +39,7 @@ c.kt: # 0| 0: [TypeAccess] ProcessBuilder # 0| 5: [BlockStmt] { ... } # 0| 0: [ReturnStmt] return ... -# 0| 0: [MethodAccess] start(...) +# 0| 0: [MethodCall] start(...) # 0| -1: [VarAccess] param # 1| 2: [Constructor] C # 1| 5: [BlockStmt] { ... } @@ -62,7 +62,7 @@ e.kt: # 0| 3: [TypeAccess] boolean # 0| 5: [BlockStmt] { ... } # 0| 0: [ReturnStmt] return ... -# 0| 0: [MethodAccess] add(...) +# 0| 0: [MethodCall] add(...) # 0| -1: [ClassInstanceExpr] new ArrayList(...) # 0| -3: [TypeAccess] ArrayList # 0| 0: [IntegerLiteral] 1 @@ -71,7 +71,7 @@ e.kt: # 0| 3: [TypeAccess] Object # 0| 5: [BlockStmt] { ... } # 0| 0: [ReturnStmt] return ... -# 0| 0: [MethodAccess] put(...) +# 0| 0: [MethodCall] put(...) # 0| -1: [ClassInstanceExpr] new LinkedHashMap(...) # 0| -3: [TypeAccess] LinkedHashMap # 0| 0: [IntegerLiteral] 1 diff --git a/java/ql/integration-tests/posix-only/kotlin/generic-extension-property/test.ql b/java/ql/integration-tests/posix-only/kotlin/generic-extension-property/test.ql index b53b2fb30698..b34f4aa8da7e 100644 --- a/java/ql/integration-tests/posix-only/kotlin/generic-extension-property/test.ql +++ b/java/ql/integration-tests/posix-only/kotlin/generic-extension-property/test.ql @@ -1,4 +1,4 @@ import java -from MethodAccess ma +from MethodCall ma select ma, ma.getCallee().toString(), ma.getCallee().getAParamType().toString() diff --git a/java/ql/lib/change-notes/2023-10-23-spring-6-models.md b/java/ql/lib/change-notes/2023-10-23-spring-6-models.md new file mode 100644 index 000000000000..8c4f9f938f24 --- /dev/null +++ b/java/ql/lib/change-notes/2023-10-23-spring-6-models.md @@ -0,0 +1,4 @@ +--- +category: minorAnalysis +--- +* Added up to date models related to Spring Framework 6's `org.springframework.http.ResponseEntity`. diff --git a/java/ql/lib/change-notes/2023-10-24-java-renames.md b/java/ql/lib/change-notes/2023-10-24-java-renames.md new file mode 100644 index 000000000000..e6aebad211cc --- /dev/null +++ b/java/ql/lib/change-notes/2023-10-24-java-renames.md @@ -0,0 +1,5 @@ +--- +category: minorAnalysis +--- +* Java classes `MethodAccess`, `LValue` and `RValue` were renamed to `MethodCall`, `VarWrite` and `VarRead` respectively, along with related predicates and class names. The old names remain usable for the time being but are deprecated and should be replaced. +* New class `NewClassExpr` was added to represent specifically an explicit `new ClassName(...)` invocation, in contrast to `ClassInstanceExpr` which also includes expressions that implicitly instantiate classes, such as defining a lambda or taking a method reference. diff --git a/java/ql/lib/definitions.qll b/java/ql/lib/definitions.qll index b82e19c564d4..e4b93f6f7e14 100644 --- a/java/ql/lib/definitions.qll +++ b/java/ql/lib/definitions.qll @@ -15,7 +15,7 @@ import IDEContextual * the location may be slightly inaccurate and include such whitespace, * but it should suffice for the purpose of avoiding overlapping definitions. */ -private class LocationOverridingMethodAccess extends MethodAccess { +private class LocationOverridingMethodCall extends MethodCall { override predicate hasLocationInfo(string path, int sl, int sc, int el, int ec) { exists(MemberRefExpr e | e.getReferencedCallable() = this.getMethod() | exists(int elRef, int ecRef | e.hasLocationInfo(path, _, _, elRef, ecRef) | @@ -152,7 +152,7 @@ private class LocationOverridingImportStaticTypeMember extends ImportStaticTypeM } private Element definition(Element e, string kind) { - e.(MethodAccess).getMethod().getSourceDeclaration() = result and + e.(MethodCall).getMethod().getSourceDeclaration() = result and kind = "M" and not result instanceof InitializerMethod or diff --git a/java/ql/lib/ext/org.springframework.http.model.yml b/java/ql/lib/ext/org.springframework.http.model.yml index cb5f18a7732d..b949d8bcd431 100644 --- a/java/ql/lib/ext/org.springframework.http.model.yml +++ b/java/ql/lib/ext/org.springframework.http.model.yml @@ -64,10 +64,16 @@ extensions: - ["org.springframework.http", "RequestEntity", True, "getUrl", "()", "", "Argument[this]", "ReturnValue", "taint", "manual"] - ["org.springframework.http", "ResponseEntity", True, "ResponseEntity", "(MultiValueMap,HttpStatus)", "", "Argument[0].MapKey", "Argument[this]", "taint", "manual"] - ["org.springframework.http", "ResponseEntity", True, "ResponseEntity", "(MultiValueMap,HttpStatus)", "", "Argument[0].MapValue.Element", "Argument[this]", "taint", "manual"] + - ["org.springframework.http", "ResponseEntity", True, "ResponseEntity", "(MultiValueMap,HttpStatusCode)", "", "Argument[0].MapKey", "Argument[this]", "taint", "manual"] + - ["org.springframework.http", "ResponseEntity", True, "ResponseEntity", "(MultiValueMap,HttpStatusCode)", "", "Argument[0].MapValue.Element", "Argument[this]", "taint", "manual"] - ["org.springframework.http", "ResponseEntity", True, "ResponseEntity", "(Object,HttpStatus)", "", "Argument[0]", "Argument[this]", "taint", "manual"] + - ["org.springframework.http", "ResponseEntity", True, "ResponseEntity", "(Object,HttpStatusCode)", "", "Argument[0]", "Argument[this]", "taint", "manual"] - ["org.springframework.http", "ResponseEntity", True, "ResponseEntity", "(Object,MultiValueMap,HttpStatus)", "", "Argument[0]", "Argument[this]", "taint", "manual"] - ["org.springframework.http", "ResponseEntity", True, "ResponseEntity", "(Object,MultiValueMap,HttpStatus)", "", "Argument[1].MapKey", "Argument[this]", "taint", "manual"] - ["org.springframework.http", "ResponseEntity", True, "ResponseEntity", "(Object,MultiValueMap,HttpStatus)", "", "Argument[1].MapValue.Element", "Argument[this]", "taint", "manual"] + - ["org.springframework.http", "ResponseEntity", True, "ResponseEntity", "(Object,MultiValueMap,HttpStatusCode)", "", "Argument[0]", "Argument[this]", "taint", "manual"] + - ["org.springframework.http", "ResponseEntity", True, "ResponseEntity", "(Object,MultiValueMap,HttpStatusCode)", "", "Argument[1].MapKey", "Argument[this]", "taint", "manual"] + - ["org.springframework.http", "ResponseEntity", True, "ResponseEntity", "(Object,MultiValueMap,HttpStatusCode)", "", "Argument[1].MapValue.Element", "Argument[this]", "taint", "manual"] - ["org.springframework.http", "ResponseEntity", True, "ResponseEntity", "(Object,MultiValueMap,int)", "", "Argument[0]", "Argument[this]", "taint", "manual"] - ["org.springframework.http", "ResponseEntity", True, "ResponseEntity", "(Object,MultiValueMap,int)", "", "Argument[1].MapKey", "Argument[this]", "taint", "manual"] - ["org.springframework.http", "ResponseEntity", True, "ResponseEntity", "(Object,MultiValueMap,int)", "", "Argument[1].MapValue.Element", "Argument[this]", "taint", "manual"] diff --git a/java/ql/lib/ext/threatmodels/supported-threat-models.model.yml b/java/ql/lib/ext/threatmodels/supported-threat-models.model.yml deleted file mode 100644 index 8c6c533228d5..000000000000 --- a/java/ql/lib/ext/threatmodels/supported-threat-models.model.yml +++ /dev/null @@ -1,7 +0,0 @@ -extensions: - - - addsTo: - pack: codeql/java-all - extensible: supportedThreatModels - data: - - ["default"] # The "default" threat model is always included. diff --git a/java/ql/lib/qlpack.yml b/java/ql/lib/qlpack.yml index 98daf03df528..2261427469eb 100644 --- a/java/ql/lib/qlpack.yml +++ b/java/ql/lib/qlpack.yml @@ -8,7 +8,9 @@ upgrades: upgrades dependencies: codeql/dataflow: ${workspace} codeql/mad: ${workspace} + codeql/rangeanalysis: ${workspace} codeql/regex: ${workspace} + codeql/threat-models: ${workspace} codeql/tutorial: ${workspace} codeql/typetracking: ${workspace} codeql/util: ${workspace} @@ -16,5 +18,4 @@ dataExtensions: - ext/*.model.yml - ext/generated/*.model.yml - ext/experimental/*.model.yml - - ext/threatmodels/*.model.yml warnOnImplicitThis: true diff --git a/java/ql/lib/semmle/code/java/Collections.qll b/java/ql/lib/semmle/code/java/Collections.qll index b890c8545e50..9fd64dc60ee3 100644 --- a/java/ql/lib/semmle/code/java/Collections.qll +++ b/java/ql/lib/semmle/code/java/Collections.qll @@ -82,7 +82,7 @@ class CollectionMutator extends CollectionMethod { } /** A method call that mutates a collection. */ -class CollectionMutation extends MethodAccess { +class CollectionMutation extends MethodCall { CollectionMutation() { this.getMethod() instanceof CollectionMutator } /** Holds if the result of this call is not immediately discarded. */ diff --git a/java/ql/lib/semmle/code/java/ControlFlowGraph.qll b/java/ql/lib/semmle/code/java/ControlFlowGraph.qll index 6b3795df2b09..572c8629626e 100644 --- a/java/ql/lib/semmle/code/java/ControlFlowGraph.qll +++ b/java/ql/lib/semmle/code/java/ControlFlowGraph.qll @@ -43,7 +43,7 @@ * * An important goal of the CFG is to get the order of side-effects correct. * Most expressions can have side-effects and must therefore be modeled in the - * CFG in AST post-order. For example, a `MethodAccess` evaluates its arguments + * CFG in AST post-order. For example, a `MethodCall` evaluates its arguments * before the call. Most statements don't have side-effects, but merely affect * the control-flow and some could therefore be excluded from the CFG. However, * as a design choice, all statements are included in the CFG and generally @@ -190,7 +190,7 @@ private module ControlFlowGraphImpl { /** * Bind `t` to an unchecked exception that may occur in a precondition check. */ - private predicate uncheckedExceptionFromMethod(MethodAccess ma, ThrowableType t) { + private predicate uncheckedExceptionFromMethod(MethodCall ma, ThrowableType t) { conditionCheckArgument(ma, _, _) and (t instanceof TypeError or t instanceof TypeRuntimeException) } @@ -349,8 +349,8 @@ private module ControlFlowGraphImpl { forall(Parameter p | p = this.getAParameter() | exists(p.getAnAccess())) } - /** Gets a `MethodAccess` that calls this method. */ - MethodAccess getAnAccess() { result.getMethod().getAPossibleImplementation() = this } + /** Gets a `MethodCall` that calls this method. */ + MethodCall getAnAccess() { result.getMethod().getAPossibleImplementation() = this } } /** Holds if a call to `m` indicates that `m` is expected to return. */ @@ -390,9 +390,9 @@ private module ControlFlowGraphImpl { } /** - * Gets a `MethodAccess` that always throws an exception or calls `exit`. + * Gets a `MethodCall` that always throws an exception or calls `exit`. */ - private MethodAccess nonReturningMethodAccess() { + private MethodCall nonReturningMethodCall() { result.getMethod().getSourceDeclaration() = nonReturningMethod() or result = likelyNonReturningMethod().getAnAccess() } @@ -422,7 +422,7 @@ private module ControlFlowGraphImpl { * Gets an expression that always throws an exception or calls `exit`. */ private Expr nonReturningExpr() { - result = nonReturningMethodAccess() + result = nonReturningMethodCall() or result.(StmtExpr).getStmt() = nonReturningStmt() or @@ -473,7 +473,7 @@ private module ControlFlowGraphImpl { or this instanceof ClassExpr or - this instanceof RValue + this instanceof VarRead or this instanceof Call // includes both expressions and statements or @@ -554,7 +554,7 @@ private module ControlFlowGraphImpl { or index = 0 and result = this.(LocalVariableDeclExpr).getInit() or - index = 0 and result = this.(RValue).getQualifier() and not result instanceof TypeAccess + index = 0 and result = this.(VarRead).getQualifier() and not result instanceof TypeAccess or exists(Call e | e = this | index = -1 and result = e.getQualifier() and not result instanceof TypeAccess @@ -588,7 +588,7 @@ private module ControlFlowGraphImpl { not this instanceof BooleanLiteral and not this instanceof ReturnStmt and not this instanceof ThrowStmt and - not this = nonReturningMethodAccess() + not this = nonReturningMethodCall() } } diff --git a/java/ql/lib/semmle/code/java/Expr.qll b/java/ql/lib/semmle/code/java/Expr.qll index d307e16cad21..89e79b3ad0aa 100644 --- a/java/ql/lib/semmle/code/java/Expr.qll +++ b/java/ql/lib/semmle/code/java/Expr.qll @@ -530,6 +530,9 @@ class Literal extends Expr, @literal { * Gets a string representation of this literal as it appeared * in the source code. * + * For Kotlin the result might not match the exact representation + * used in the source code. + * * **Important:** Unless a query explicitly wants to check how * a literal was written in the source code, the predicate * `getValue()` (or value predicates of subclasses) should be @@ -1251,6 +1254,14 @@ class ClassInstanceExpr extends Expr, ConstructorCall, @classinstancexpr { override string getAPrimaryQlClass() { result = "ClassInstanceExpr" } } +/** + * An explicit `new TypeName(...)` expression. + * + * Note this does not include implicit instance creation such as lambda expressions + * or `instanceVar::methodName` references. To include those too, use `ClassInstanceExpr`. + */ +class NewClassExpr extends @newexpr, ClassInstanceExpr { } + /** A functional expression is either a lambda expression or a member reference expression. */ abstract class FunctionalExpr extends ClassInstanceExpr { /** Gets the implicit method corresponding to this functional expression. */ @@ -1372,7 +1383,7 @@ class MemberRefExpr extends FunctionalExpr, @memberref { */ RefType getReceiverType() { exists(Expr resultExpr | resultExpr = this.getResultExpr() | - result = resultExpr.(MethodAccess).getReceiverType() or + result = resultExpr.(MethodCall).getReceiverType() or result = resultExpr.(ClassInstanceExpr).getConstructedType() or result = resultExpr.(ArrayCreationExpr).getType() ) @@ -1768,24 +1779,29 @@ class VarAccess extends Expr, @varaccess { Variable getVariable() { variableBinding(this, result) } /** - * Holds if this variable access is an l-value. + * Holds if this variable access is a write access. * - * An l-value is a write access to a variable, which occurs as the destination of an assignment. + * That means the access is the destination of an assignment. */ - predicate isLValue() { + predicate isVarWrite() { exists(Assignment a | a.getDest() = this) or exists(UnaryAssignExpr e | e.getExpr() = this) } + /** DEPRECATED: Alias for `isVarWrite`. */ + deprecated predicate isLValue() { this.isVarWrite() } + /** - * Holds if this variable access is an r-value. + * Holds if this variable access is a read access. * - * An r-value is a read access to a variable. * In other words, it is a variable access that does _not_ occur as the destination of * a simple assignment, but it may occur as the destination of a compound assignment * or a unary assignment. */ - predicate isRValue() { not exists(AssignExpr a | a.getDest() = this) } + predicate isVarRead() { not exists(AssignExpr a | a.getDest() = this) } + + /** DEPRECATED: Alias for `isVarRead`. */ + deprecated predicate isRValue() { this.isVarRead() } /** Gets a printable representation of this expression. */ override string toString() { @@ -1831,37 +1847,46 @@ class ExtensionReceiverAccess extends VarAccess { } /** - * An l-value is a write access to a variable, which occurs as the destination of an assignment. + * A write access to a variable, which occurs as the destination of an assignment. */ -class LValue extends VarAccess { - LValue() { this.isLValue() } +class VarWrite extends VarAccess { + VarWrite() { this.isVarWrite() } /** - * Gets a source expression used in an assignment to this l-value. + * Gets a source of the assignment that executes this variable write. * * For assignments using the `=` operator, the source expression * is simply the RHS of the assignment. * - * Note that for l-values occurring on the LHS of compound assignment operators + * Note that for writes occurring on the LHS of compound assignment operators * (such as (`+=`), both the RHS and the LHS of the compound assignment * are source expressions of the assignment. */ - Expr getRhs() { exists(Assignment e | e.getDest() = this and e.getSource() = result) } + Expr getASource() { exists(Assignment e | e.getDest() = this and e.getSource() = result) } + + /** DEPRECATED: (Inaccurately-named) alias for `getASource` */ + deprecated Expr getRhs() { result = this.getASource() } } +/** DEPRECATED: Alias for `VarWrite`. */ +deprecated class LValue = VarWrite; + /** - * An r-value is a read access to a variable. + * A read access to a variable. * * In other words, it is a variable access that does _not_ occur as the destination of * a simple assignment, but it may occur as the destination of a compound assignment * or a unary assignment. */ -class RValue extends VarAccess { - RValue() { this.isRValue() } +class VarRead extends VarAccess { + VarRead() { this.isVarRead() } } -/** A method access is an invocation of a method with a list of arguments. */ -class MethodAccess extends Expr, Call, @methodaccess { +/** DEPRECATED: Alias for `VarRead`. */ +deprecated class RValue = VarRead; + +/** A method call is an invocation of a method with a list of arguments. */ +class MethodCall extends Expr, Call, @methodaccess { /** Gets the qualifying expression of this method access, if any. */ override Expr getQualifier() { result.isNthChildOf(this, -1) } @@ -1909,21 +1934,30 @@ class MethodAccess extends Expr, Call, @methodaccess { } /** - * Holds if this is a method access to an instance method of `this`. That is, + * Holds if this is a method call to an instance method of `this`. That is, * the qualifier is either an explicit or implicit unqualified `this` or `super`. */ - predicate isOwnMethodAccess() { Qualifier::ownMemberAccess(this) } + predicate isOwnMethodCall() { Qualifier::ownMemberAccess(this) } + + /** DEPRECATED: Alias for `isOwnMethodCall`. */ + deprecated predicate isOwnMethodAccess() { this.isOwnMethodCall() } /** - * Holds if this is a method access to an instance method of the enclosing + * Holds if this is a method call to an instance method of the enclosing * class `t`. That is, the qualifier is either an explicit or implicit * `t`-qualified `this` or `super`. */ - predicate isEnclosingMethodAccess(RefType t) { Qualifier::enclosingMemberAccess(this, t) } + predicate isEnclosingMethodCall(RefType t) { Qualifier::enclosingMemberAccess(this, t) } + + /** DEPRECATED: Alias for `isEnclosingMethodCall`. */ + deprecated predicate isEnclosingMethodAccess(RefType t) { this.isEnclosingMethodCall(t) } - override string getAPrimaryQlClass() { result = "MethodAccess" } + override string getAPrimaryQlClass() { result = "MethodCall" } } +/** DEPRECATED: Alias for `MethodCall`. */ +deprecated class MethodAccess = MethodCall; + /** A type access is a (possibly qualified) reference to a type. */ class TypeAccess extends Expr, Annotatable, @typeaccess { /** Gets the qualifier of this type access, if any. */ @@ -2085,23 +2119,32 @@ class Call extends ExprParent, @caller { } /** A polymorphic call to an instance method. */ -class VirtualMethodAccess extends MethodAccess { - VirtualMethodAccess() { +class VirtualMethodCall extends MethodCall { + VirtualMethodCall() { this.getMethod().isVirtual() and not this.getQualifier() instanceof SuperAccess } } +/** DEPRECATED: Alias for `VirtualMethodCall`. */ +deprecated class VirtualMethodAccess = VirtualMethodCall; + /** A static method call. */ -class StaticMethodAccess extends MethodAccess { - StaticMethodAccess() { this.getMethod().isStatic() } +class StaticMethodCall extends MethodCall { + StaticMethodCall() { this.getMethod().isStatic() } } +/** DEPRECATED: Alias for `StaticMethodCall`. */ +deprecated class StaticMethodAccess = StaticMethodCall; + /** A call to a method in the superclass. */ -class SuperMethodAccess extends MethodAccess { - SuperMethodAccess() { this.getQualifier() instanceof SuperAccess } +class SuperMethodCall extends MethodCall { + SuperMethodCall() { this.getQualifier() instanceof SuperAccess } } +/** DEPRECATED: Alias for `SuperMethodCall`. */ +deprecated class SuperMethodAccess = SuperMethodCall; + /** * A constructor call, which occurs either as a constructor invocation inside a * constructor, or as part of a class instance expression. @@ -2150,23 +2193,23 @@ private module Qualifier { TThis() or TEnclosing(RefType t) - /** An expression that accesses a member. That is, either a `FieldAccess` or a `MethodAccess`. */ + /** An expression that accesses a member. That is, either a `FieldAccess` or a `MethodCall`. */ class MemberAccess extends Expr { MemberAccess() { this instanceof FieldAccess or - this instanceof MethodAccess + this instanceof MethodCall } /** Gets the member accessed by this member access. */ Member getMember() { result = this.(FieldAccess).getField() or - result = this.(MethodAccess).getMethod() + result = this.(MethodCall).getMethod() } /** Gets the qualifier of this member access, if any. */ Expr getQualifier() { result = this.(FieldAccess).getQualifier() or - result = this.(MethodAccess).getQualifier() + result = this.(MethodCall).getQualifier() } } @@ -2236,10 +2279,10 @@ private module Qualifier { } /** An expression that assigns a value to a field. */ -class FieldWrite extends FieldAccess, LValue { } +class FieldWrite extends FieldAccess, VarWrite { } /** An expression that reads a field. */ -class FieldRead extends FieldAccess, RValue { } +class FieldRead extends FieldAccess, VarRead { } private predicate hasInstantiation(RefType t) { t instanceof TypeVariable or diff --git a/java/ql/lib/semmle/code/java/Generics.qll b/java/ql/lib/semmle/code/java/Generics.qll index affc0132f948..5f67d78b383e 100644 --- a/java/ql/lib/semmle/code/java/Generics.qll +++ b/java/ql/lib/semmle/code/java/Generics.qll @@ -479,7 +479,7 @@ class GenericCall extends Call { } private RefType getAnExplicitTypeArgument(TypeVariable v) { - exists(GenericCallable gen, MethodAccess call, int i | + exists(GenericCallable gen, MethodCall call, int i | this = call and gen = call.getCallee() and v = gen.getTypeParameter(i) and diff --git a/java/ql/lib/semmle/code/java/JDK.qll b/java/ql/lib/semmle/code/java/JDK.qll index 6372b22c8f4e..7623cc87393c 100644 --- a/java/ql/lib/semmle/code/java/JDK.qll +++ b/java/ql/lib/semmle/code/java/JDK.qll @@ -259,10 +259,10 @@ class MethodSystemGetProperty extends ValuePreservingMethod { } /** - * An access to a method named `getProperty` on class `java.lang.System`. + * A call to a method named `getProperty` on class `java.lang.System`. */ -class MethodAccessSystemGetProperty extends MethodAccess { - MethodAccessSystemGetProperty() { this.getMethod() instanceof MethodSystemGetProperty } +class MethodCallSystemGetProperty extends MethodCall { + MethodCallSystemGetProperty() { this.getMethod() instanceof MethodSystemGetProperty } /** * Holds if this call has a compile-time constant first argument with the value `propertyName`. @@ -276,6 +276,9 @@ class MethodAccessSystemGetProperty extends MethodAccess { } } +/** DEPRECATED: Alias for `MethodCallSystemGetProperty`. */ +deprecated class MethodAccessSystemGetProperty = MethodCallSystemGetProperty; + /** * Any method named `exit` on class `java.lang.Runtime` or `java.lang.System`. */ diff --git a/java/ql/lib/semmle/code/java/JMX.qll b/java/ql/lib/semmle/code/java/JMX.qll index 66aa951ba28d..5b4860e64e30 100644 --- a/java/ql/lib/semmle/code/java/JMX.qll +++ b/java/ql/lib/semmle/code/java/JMX.qll @@ -39,7 +39,7 @@ class RegisteredManagedBeanImpl extends Class { /** * A call that registers an object with the `MBeanServer`, directly or indirectly. */ -class JmxRegistrationCall extends MethodAccess { +class JmxRegistrationCall extends MethodCall { JmxRegistrationCall() { this.getCallee() instanceof JmxRegistrationMethod } /** diff --git a/java/ql/lib/semmle/code/java/Maps.qll b/java/ql/lib/semmle/code/java/Maps.qll index 1157cb76f5c5..95a3da1e4c7e 100644 --- a/java/ql/lib/semmle/code/java/Maps.qll +++ b/java/ql/lib/semmle/code/java/Maps.qll @@ -49,7 +49,7 @@ class MapSizeMethod extends MapMethod { } /** A method call that mutates a map. */ -class MapMutation extends MethodAccess { +class MapMutation extends MethodCall { MapMutation() { this.getMethod() instanceof MapMutator } /** Holds if the result of this call is not immediately discarded. */ @@ -76,7 +76,7 @@ class FreshMap extends ClassInstanceExpr { /** * A call to `Map.put(key, value)`. */ -class MapPutCall extends MethodAccess { +class MapPutCall extends MethodCall { MapPutCall() { this.getCallee().(MapMethod).hasName("put") } /** Gets the key argument of this call. */ diff --git a/java/ql/lib/semmle/code/java/Member.qll b/java/ql/lib/semmle/code/java/Member.qll index b871451f408b..49c9107d5d1c 100644 --- a/java/ql/lib/semmle/code/java/Member.qll +++ b/java/ql/lib/semmle/code/java/Member.qll @@ -129,7 +129,7 @@ class Callable extends StmtParent, Member, @callable { * Holds if this callable calls `target` * using a `super` method call. */ - predicate callsSuper(Method target) { this.getACallSite(target) instanceof SuperMethodAccess } + predicate callsSuper(Method target) { this.getACallSite(target) instanceof SuperMethodCall } /** * Holds if this callable calls `c` using @@ -161,13 +161,13 @@ class Callable extends StmtParent, Member, @callable { * Holds if field `f` may be assigned a value * within the body of this callable. */ - predicate writes(Field f) { f.getAnAccess().(LValue).getEnclosingCallable() = this } + predicate writes(Field f) { f.getAnAccess().(VarWrite).getEnclosingCallable() = this } /** * Holds if field `f` may be read * within the body of this callable. */ - predicate reads(Field f) { f.getAnAccess().(RValue).getEnclosingCallable() = this } + predicate reads(Field f) { f.getAnAccess().(VarRead).getEnclosingCallable() = this } /** * Holds if field `f` may be either read or written @@ -526,7 +526,7 @@ class Method extends Callable, @method { this.getSourceDeclaration().getAPossibleImplementationOfSrcMethod() = result } - override MethodAccess getAReference() { result = Callable.super.getAReference() } + override MethodCall getAReference() { result = Callable.super.getAReference() } override predicate isPublic() { Callable.super.isPublic() diff --git a/java/ql/lib/semmle/code/java/NumberFormatException.qll b/java/ql/lib/semmle/code/java/NumberFormatException.qll index e3b83811cf04..2c47eafaa5e4 100644 --- a/java/ql/lib/semmle/code/java/NumberFormatException.qll +++ b/java/ql/lib/semmle/code/java/NumberFormatException.qll @@ -3,7 +3,7 @@ import java /** A call to a string to number conversion. */ -private class SpecialMethodAccess extends MethodAccess { +private class SpecialMethodCall extends MethodCall { predicate isValueOfMethod(string klass) { this.getMethod().getName() = "valueOf" and this.getQualifier().getType().(RefType).hasQualifiedName("java.lang", klass) and @@ -78,7 +78,7 @@ deprecated predicate catchesNFE = catchesNfe/1; /** Holds if `java.lang.NumberFormatException` can be thrown. */ predicate throwsNfe(Expr e) { - e.(SpecialClassInstanceExpr).throwsNfe() or e.(SpecialMethodAccess).throwsNfe() + e.(SpecialClassInstanceExpr).throwsNfe() or e.(SpecialMethodCall).throwsNfe() } /** DEPRECATED: Alias for throwsNfe */ diff --git a/java/ql/lib/semmle/code/java/PrettyPrintAst.qll b/java/ql/lib/semmle/code/java/PrettyPrintAst.qll index 13fb3d85e74f..f7ddbee4abc8 100644 --- a/java/ql/lib/semmle/code/java/PrettyPrintAst.qll +++ b/java/ql/lib/semmle/code/java/PrettyPrintAst.qll @@ -300,7 +300,7 @@ private class PpCall extends PpAst, Call { or i = 2 and ( - result = this.(MethodAccess).getMethod().getName() + result = this.(MethodCall).getMethod().getName() or result = "this" and this instanceof ThisConstructorInvocationStmt or diff --git a/java/ql/lib/semmle/code/java/Reflection.qll b/java/ql/lib/semmle/code/java/Reflection.qll index 48f3d80822a3..d6449dca2230 100644 --- a/java/ql/lib/semmle/code/java/Reflection.qll +++ b/java/ql/lib/semmle/code/java/Reflection.qll @@ -62,8 +62,8 @@ private class ReflectiveClassIdentifierLiteral extends ReflectiveClassIdentifier /** * A call to a Java standard library method which constructs or returns a `Class` from a `String`. */ -class ReflectiveClassIdentifierMethodAccess extends ReflectiveClassIdentifier, MethodAccess { - ReflectiveClassIdentifierMethodAccess() { +class ReflectiveClassIdentifierMethodCall extends ReflectiveClassIdentifier, MethodCall { + ReflectiveClassIdentifierMethodCall() { // A call to `Class.forName(...)`, from which we can infer `T` in the returned type `Class`. this.getCallee().getDeclaringType() instanceof TypeClass and this.getCallee().hasName("forName") or @@ -83,6 +83,9 @@ class ReflectiveClassIdentifierMethodAccess extends ReflectiveClassIdentifier, M } } +/** DEPRECATED: Alias for `ReflectiveClassIdentifierMethodCall`. */ +deprecated class ReflectiveClassIdentifierMethodAccess = ReflectiveClassIdentifierMethodCall; + /** * Gets a `ReflectiveClassIdentifier` that we believe may represent the value of `expr`. */ @@ -92,7 +95,7 @@ private ReflectiveClassIdentifier pointsToReflectiveClassIdentifier(Expr expr) { or // Or if this is an access of a variable which was defined as an expression creating a `Class`, // return the inferred `T` from the definition expression. - exists(RValue use, VariableAssign assign | + exists(VarRead use, VariableAssign assign | use = expr and defUsePair(assign, use) and // The source of the assignment must be a `ReflectiveClassIdentifier`. @@ -211,7 +214,7 @@ private predicate expectsEnclosingInstance(RefType r) { /** * A call to `Class.newInstance()` or `Constructor.newInstance()`. */ -class NewInstance extends MethodAccess { +class NewInstance extends MethodCall { NewInstance() { ( this.getCallee().getDeclaringType() instanceof TypeClass or @@ -301,10 +304,10 @@ class NewInstance extends MethodAccess { } /** - * A `MethodAccess` on a `Class` element. + * A `MethodCall` on a `Class` instance. */ -class ClassMethodAccess extends MethodAccess { - ClassMethodAccess() { this.getCallee().getDeclaringType() instanceof TypeClass } +class ClassMethodCall extends MethodCall { + ClassMethodCall() { this.getCallee().getDeclaringType() instanceof TypeClass } /** * Gets an inferred type for the `Class` represented by this expression. @@ -317,31 +320,40 @@ class ClassMethodAccess extends MethodAccess { } } +/** DEPRECATED: Alias for `ClassMethodCall`. */ +deprecated class ClassMethodAccess = ClassMethodCall; + /** * A call to `Class.getConstructors(..)` or `Class.getDeclaredConstructors(..)`. */ -class ReflectiveConstructorsAccess extends ClassMethodAccess { - ReflectiveConstructorsAccess() { +class ReflectiveGetConstructorsCall extends ClassMethodCall { + ReflectiveGetConstructorsCall() { this.getCallee().hasName("getConstructors") or this.getCallee().hasName("getDeclaredConstructors") } } +/** DEPRECATED: Alias for `ReflectiveGetConstructorsCall`. */ +deprecated class ReflectiveConstructorsAccess = ReflectiveGetConstructorsCall; + /** * A call to `Class.getMethods(..)` or `Class.getDeclaredMethods(..)`. */ -class ReflectiveMethodsAccess extends ClassMethodAccess { - ReflectiveMethodsAccess() { +class ReflectiveGetMethodsCall extends ClassMethodCall { + ReflectiveGetMethodsCall() { this.getCallee().hasName("getMethods") or this.getCallee().hasName("getDeclaredMethods") } } +/** DEPRECATED: Alias for `ReflectiveGetMethodsCall`. */ +deprecated class ReflectiveMethodsAccess = ReflectiveGetMethodsCall; + /** * A call to `Class.getMethod(..)` or `Class.getDeclaredMethod(..)`. */ -class ReflectiveMethodAccess extends ClassMethodAccess { - ReflectiveMethodAccess() { +class ReflectiveGetMethodCall extends ClassMethodCall { + ReflectiveGetMethodCall() { this.getCallee().hasName("getMethod") or this.getCallee().hasName("getDeclaredMethod") } @@ -366,11 +378,14 @@ class ReflectiveMethodAccess extends ClassMethodAccess { } } +/** DEPRECATED: Alias for `ReflectiveGetMethodCall`. */ +deprecated class ReflectiveMethodAccess = ReflectiveGetMethodCall; + /** * A call to `Class.getAnnotation(..)`. */ -class ReflectiveAnnotationAccess extends ClassMethodAccess { - ReflectiveAnnotationAccess() { this.getCallee().hasName("getAnnotation") } +class ReflectiveGetAnnotationCall extends ClassMethodCall { + ReflectiveGetAnnotationCall() { this.getCallee().hasName("getAnnotation") } /** * Gets a possible annotation type for this reflective annotation access. @@ -380,11 +395,14 @@ class ReflectiveAnnotationAccess extends ClassMethodAccess { } } +/** DEPRECATED: Alias for `ReflectiveGetAnnotationCall`. */ +deprecated class ReflectiveAnnotationAccess = ReflectiveGetAnnotationCall; + /** * A call to `Class.getField(..)` that accesses a field. */ -class ReflectiveFieldAccess extends ClassMethodAccess { - ReflectiveFieldAccess() { +class ReflectiveGetFieldCall extends ClassMethodCall { + ReflectiveGetFieldCall() { this.getCallee().hasName("getField") or this.getCallee().hasName("getDeclaredField") } @@ -405,3 +423,6 @@ class ReflectiveFieldAccess extends ClassMethodAccess { result.hasName(this.getArgument(0).(StringLiteral).getValue()) } } + +/** DEPRECATED: Alias for `ReflectiveGetFieldCall`. */ +deprecated class ReflectiveFieldAccess = ReflectiveGetFieldCall; diff --git a/java/ql/lib/semmle/code/java/StringFormat.qll b/java/ql/lib/semmle/code/java/StringFormat.qll index f8ebac41d9ab..4ed39c02a841 100644 --- a/java/ql/lib/semmle/code/java/StringFormat.qll +++ b/java/ql/lib/semmle/code/java/StringFormat.qll @@ -242,7 +242,7 @@ predicate implicitToStringCall(Expr e) { or exists(AddExpr add | add.getType() instanceof TypeString and add.getAnOperand() = e) or - exists(MethodAccess ma, Method m, int i | + exists(MethodCall ma, Method m, int i | ma.getMethod() = m and ma.getArgument(i) = e and printMethod(m, i) @@ -253,7 +253,7 @@ predicate implicitToStringCall(Expr e) { /** * A call to a `format` or `printf` method. */ -class StringFormat extends MethodAccess, FormattingCall { +class StringFormat extends MethodCall, FormattingCall { StringFormat() { this.getCallee() instanceof StringFormatMethod } } diff --git a/java/ql/lib/semmle/code/java/Type.qll b/java/ql/lib/semmle/code/java/Type.qll index 1b1cb83e4f85..afe78d522f2a 100644 --- a/java/ql/lib/semmle/code/java/Type.qll +++ b/java/ql/lib/semmle/code/java/Type.qll @@ -1090,6 +1090,24 @@ class PrimitiveType extends Type, @primitive { override string getAPrimaryQlClass() { result = "PrimitiveType" } } +private int getByteSize(PrimitiveType t) { + t.hasName("boolean") and result = 1 + or + t.hasName("byte") and result = 1 + or + t.hasName("char") and result = 2 + or + t.hasName("short") and result = 2 + or + t.hasName("int") and result = 4 + or + t.hasName("float") and result = 4 + or + t.hasName("long") and result = 8 + or + t.hasName("double") and result = 8 +} + /** The type of the `null` literal. */ class NullType extends Type, @primitive { NullType() { this.hasName("") } @@ -1282,6 +1300,12 @@ class IntegralType extends Type { name = ["byte", "char", "short", "int", "long"] ) } + + /** Gets the size in bytes of this numeric type. */ + final int getByteSize() { + result = getByteSize(this) or + result = getByteSize(this.(BoxedType).getPrimitiveType()) + } } /** A boolean type, which may be either a primitive or a boxed type. */ diff --git a/java/ql/lib/semmle/code/java/controlflow/Guards.qll b/java/ql/lib/semmle/code/java/controlflow/Guards.qll index 7152c65191c2..25809f4c16af 100644 --- a/java/ql/lib/semmle/code/java/controlflow/Guards.qll +++ b/java/ql/lib/semmle/code/java/controlflow/Guards.qll @@ -187,14 +187,14 @@ private predicate switchCaseControls(SwitchCase sc, BasicBlock bb) { } private predicate preconditionBranchEdge( - MethodAccess ma, BasicBlock bb1, BasicBlock bb2, boolean branch + MethodCall ma, BasicBlock bb1, BasicBlock bb2, boolean branch ) { conditionCheckArgument(ma, _, branch) and bb1.getLastNode() = ma.getControlFlowNode() and bb2 = bb1.getLastNode().getANormalSuccessor() } -private predicate preconditionControls(MethodAccess ma, BasicBlock controlled, boolean branch) { +private predicate preconditionControls(MethodCall ma, BasicBlock controlled, boolean branch) { exists(BasicBlock check, BasicBlock succ | preconditionBranchEdge(ma, check, succ, branch) and dominatingEdge(check, succ) and @@ -249,7 +249,7 @@ private predicate equalityGuard(Guard g, Expr e1, Expr e2, boolean polarity) { eqtest.hasOperands(e1, e2) ) or - exists(MethodAccess ma | + exists(MethodCall ma | ma = g and ma.getMethod() instanceof EqualsMethod and polarity = true and @@ -257,7 +257,7 @@ private predicate equalityGuard(Guard g, Expr e1, Expr e2, boolean polarity) { ma.getQualifier() = e2 ) or - exists(MethodAccess ma, Method equals | + exists(MethodCall ma, Method equals | ma = g and ma.getMethod() = equals and polarity = true and diff --git a/java/ql/lib/semmle/code/java/controlflow/internal/GuardsLogic.qll b/java/ql/lib/semmle/code/java/controlflow/internal/GuardsLogic.qll index bc49f1d3a770..9fed7516ba31 100644 --- a/java/ql/lib/semmle/code/java/controlflow/internal/GuardsLogic.qll +++ b/java/ql/lib/semmle/code/java/controlflow/internal/GuardsLogic.qll @@ -59,7 +59,7 @@ predicate implies_v1(Guard g1, boolean b1, Guard g2, boolean b2) { or g1.(DefaultCase).getSwitchExpr().getAConstCase() = g2 and b1 = true and b2 = false or - exists(MethodAccess check, int argIndex | check = g1 | + exists(MethodCall check, int argIndex | check = g1 | conditionCheckArgument(check, argIndex, _) and g2 = check.getArgument(argIndex) and b1 = [true, false] and diff --git a/java/ql/lib/semmle/code/java/controlflow/internal/Preconditions.qll b/java/ql/lib/semmle/code/java/controlflow/internal/Preconditions.qll index 180d99e7e710..6e6c5ec47f9c 100644 --- a/java/ql/lib/semmle/code/java/controlflow/internal/Preconditions.qll +++ b/java/ql/lib/semmle/code/java/controlflow/internal/Preconditions.qll @@ -17,7 +17,7 @@ predicate conditionCheckMethodArgument(Method m, int argument, boolean checkTrue or condtionCheckMethodTestingFramework(m, argument, checkTrue) or - exists(Parameter p, MethodAccess ma, int argIndex, boolean ct, Expr arg | + exists(Parameter p, MethodCall ma, int argIndex, boolean ct, Expr arg | p = m.getParameter(argument) and not m.isOverridable() and m.getBody().getStmt(0).(ExprStmt).getExpr() = ma and @@ -100,6 +100,6 @@ private predicate condtionCheckMethodTestingFramework(Method m, int argument, bo * Holds if `ma` is an access to a non-overridable method that checks that its * zero-indexed `argument` is equal to `checkTrue` and throws otherwise. */ -predicate conditionCheckArgument(MethodAccess ma, int argument, boolean checkTrue) { +predicate conditionCheckArgument(MethodCall ma, int argument, boolean checkTrue) { conditionCheckMethodArgument(ma.getMethod().getSourceDeclaration(), argument, checkTrue) } diff --git a/java/ql/lib/semmle/code/java/dataflow/Bound.qll b/java/ql/lib/semmle/code/java/dataflow/Bound.qll index b881161f66f5..08826b7ae8f1 100644 --- a/java/ql/lib/semmle/code/java/dataflow/Bound.qll +++ b/java/ql/lib/semmle/code/java/dataflow/Bound.qll @@ -25,16 +25,8 @@ abstract class Bound extends TBound { /** Gets an expression that equals this bound. */ Expr getExpr() { result = this.getExpr(0) } - /** - * Holds if this element is at the specified location. - * The location spans column `sc` of line `sl` to - * column `ec` of line `el` in file `path`. - * For more information, see - * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). - */ - predicate hasLocationInfo(string path, int sl, int sc, int el, int ec) { - path = "" and sl = 0 and sc = 0 and el = 0 and ec = 0 - } + /** Gets the location of this bound. */ + abstract Location getLocation(); } /** @@ -45,6 +37,8 @@ class ZeroBound extends Bound, TBoundZero { override string toString() { result = "0" } override Expr getExpr(int delta) { result.(ConstantIntegerExpr).getIntValue() = delta } + + override Location getLocation() { result.hasLocationInfo("", 0, 0, 0, 0) } } /** @@ -58,9 +52,7 @@ class SsaBound extends Bound, TBoundSsa { override Expr getExpr(int delta) { result = this.getSsa().getAUse() and delta = 0 } - override predicate hasLocationInfo(string path, int sl, int sc, int el, int ec) { - this.getSsa().getLocation().hasLocationInfo(path, sl, sc, el, ec) - } + override Location getLocation() { result = this.getSsa().getLocation() } } /** @@ -72,7 +64,5 @@ class ExprBound extends Bound, TBoundExpr { override Expr getExpr(int delta) { this = TBoundExpr(result) and delta = 0 } - override predicate hasLocationInfo(string path, int sl, int sc, int el, int ec) { - this.getExpr().getLocation().hasLocationInfo(path, sl, sc, el, ec) - } + override Location getLocation() { result = this.getExpr().getLocation() } } diff --git a/java/ql/lib/semmle/code/java/dataflow/DefUse.qll b/java/ql/lib/semmle/code/java/dataflow/DefUse.qll index 3654425738cc..9fa08d62c27f 100644 --- a/java/ql/lib/semmle/code/java/dataflow/DefUse.qll +++ b/java/ql/lib/semmle/code/java/dataflow/DefUse.qll @@ -13,7 +13,7 @@ private import SSA * * This is the transitive closure of `adjacentUseUseSameVar`. */ -predicate useUsePairSameVar(RValue use1, RValue use2) { adjacentUseUseSameVar+(use1, use2) } +predicate useUsePairSameVar(VarRead use1, VarRead use2) { adjacentUseUseSameVar+(use1, use2) } /** * Holds if `use1` and `use2` form a use-use-pair of the same @@ -23,7 +23,7 @@ predicate useUsePairSameVar(RValue use1, RValue use2) { adjacentUseUseSameVar+(u * * This is the transitive closure of `adjacentUseUse`. */ -predicate useUsePair(RValue use1, RValue use2) { adjacentUseUse+(use1, use2) } +predicate useUsePair(VarRead use1, VarRead use2) { adjacentUseUse+(use1, use2) } /** * Holds if there exists a path from `def` to `use` without passing through another @@ -31,7 +31,7 @@ predicate useUsePair(RValue use1, RValue use2) { adjacentUseUse+(use1, use2) } * * Other paths may also exist, so the SSA variables in `def` and `use` can be different. */ -predicate defUsePair(VariableUpdate def, RValue use) { +predicate defUsePair(VariableUpdate def, VarRead use) { exists(SsaVariable v | v.getAUse() = use and v.getAnUltimateDefinition().(SsaExplicitUpdate).getDefiningExpr() = def ) @@ -43,7 +43,7 @@ predicate defUsePair(VariableUpdate def, RValue use) { * * Other paths may also exist, so the SSA variables can be different. */ -predicate parameterDefUsePair(Parameter p, RValue use) { +predicate parameterDefUsePair(Parameter p, VarRead use) { exists(SsaVariable v | v.getAUse() = use and v.getAnUltimateDefinition().(SsaImplicitInit).isParameterDefinition(p) ) diff --git a/java/ql/lib/semmle/code/java/dataflow/ExternalFlowConfiguration.qll b/java/ql/lib/semmle/code/java/dataflow/ExternalFlowConfiguration.qll deleted file mode 100644 index 0331da2477fe..000000000000 --- a/java/ql/lib/semmle/code/java/dataflow/ExternalFlowConfiguration.qll +++ /dev/null @@ -1,31 +0,0 @@ -/** - * INTERNAL use only. This is an experimental API subject to change without notice. - * - * This module provides extensible predicates for configuring which kinds of MaD models - * are applicable to generic queries. - */ - -private import ExternalFlowExtensions - -/** - * Holds if the specified kind of source model is supported for the current query. - */ -extensible private predicate supportedThreatModels(string kind); - -/** - * Holds if the specified kind of source model is containted within the specified group. - */ -extensible private predicate threatModelGrouping(string kind, string group); - -/** - * Gets the threat models that are direct descendants of the specified kind/group. - */ -private string getChildThreatModel(string group) { threatModelGrouping(result, group) } - -/** - * Holds if the source model kind `kind` is relevant for generic queries - * under the current threat model configuration. - */ -predicate currentThreatModel(string kind) { - exists(string group | supportedThreatModels(group) and kind = getChildThreatModel*(group)) -} diff --git a/java/ql/lib/semmle/code/java/dataflow/FlowSources.qll b/java/ql/lib/semmle/code/java/dataflow/FlowSources.qll index d135db168318..4a329e0cd193 100644 --- a/java/ql/lib/semmle/code/java/dataflow/FlowSources.qll +++ b/java/ql/lib/semmle/code/java/dataflow/FlowSources.qll @@ -29,7 +29,7 @@ import semmle.code.java.frameworks.struts.StrutsActions import semmle.code.java.frameworks.Thrift import semmle.code.java.frameworks.javaee.jsf.JSFRenderer private import semmle.code.java.dataflow.ExternalFlow -private import semmle.code.java.dataflow.ExternalFlowConfiguration +private import codeql.threatmodels.ThreatModels /** * A data flow source. @@ -47,10 +47,6 @@ abstract class SourceNode extends DataFlow::Node { */ class ThreatModelFlowSource extends DataFlow::Node { ThreatModelFlowSource() { - // Expansive threat model. - currentThreatModel("all") and - (this instanceof SourceNode or sourceNode(this, _)) - or exists(string kind | // Specific threat model. currentThreatModel(kind) and @@ -126,9 +122,9 @@ private predicate variableStep(Expr tracked, VarAccess sink) { private class ReverseDnsSource extends RemoteFlowSource { ReverseDnsSource() { // Try not to trigger on `localhost`. - exists(MethodAccess m | m = this.asExpr() | + exists(MethodCall m | m = this.asExpr() | m.getMethod() instanceof ReverseDnsMethod and - not exists(MethodAccess l | + not exists(MethodCall l | (variableStep(l, m.getQualifier()) or l = m.getQualifier()) and l.getMethod().getName() = "getLocalHost" ) @@ -325,7 +321,7 @@ class AndroidIntentInput extends DataFlow::Node { Type receiverType; AndroidIntentInput() { - exists(MethodAccess ma, AndroidGetIntentMethod m | + exists(MethodCall ma, AndroidGetIntentMethod m | ma.getMethod().overrides*(m) and this.asExpr() = ma and receiverType = ma.getReceiverType() diff --git a/java/ql/lib/semmle/code/java/dataflow/InstanceAccess.qll b/java/ql/lib/semmle/code/java/dataflow/InstanceAccess.qll index b21879dd717a..18bdb879c3cb 100644 --- a/java/ql/lib/semmle/code/java/dataflow/InstanceAccess.qll +++ b/java/ql/lib/semmle/code/java/dataflow/InstanceAccess.qll @@ -58,9 +58,7 @@ private predicate implicitEnclosingThisCopy(ConstructorCall cc, RefType t1, RefT private predicate enclosingInstanceAccess(ExprParent e, RefType t) { e.(InstanceAccess).isEnclosingInstanceAccess(t) or - exists(MethodAccess ma | - ma.isEnclosingMethodAccess(t) and ma = e and not exists(ma.getQualifier()) - ) + exists(MethodCall ma | ma.isEnclosingMethodCall(t) and ma = e and not exists(ma.getQualifier())) or exists(FieldAccess fa | fa.isEnclosingFieldAccess(t) and fa = e and not exists(fa.getQualifier())) or @@ -95,7 +93,7 @@ private newtype TInstanceAccessExt = or c instanceof SuperConstructorInvocationStmt or - c.(MethodAccess).isOwnMethodAccess() and not exists(c.getQualifier()) + c.(MethodCall).isOwnMethodCall() and not exists(c.getQualifier()) } or TThisEnclosingInstanceCapture(ConstructorCall cc) { implicitSetEnclosingInstanceToThis(cc) } or TEnclosingInstanceAccess(ExprParent e, RefType t) { @@ -113,7 +111,7 @@ private newtype TInstanceAccessExt = * - Implicit field qualifier: The implicit access associated with an * unqualified `FieldAccess` to a non-static field. * - Implicit method qualifier: The implicit access associated with an - * unqualified `MethodAccess` to a non-static method. + * unqualified `MethodCall` to a non-static method. * - Implicit this constructor argument: The implicit argument of the value of * `this` to a constructor call of the form `this()` or `super()`. * - Implicit enclosing instance capture: The implicit capture of the value of @@ -180,7 +178,7 @@ class InstanceAccessExt extends TInstanceAccessExt { } /** Holds if this is the implicit qualifier of `ma`. */ - predicate isImplicitMethodQualifier(MethodAccess ma) { + predicate isImplicitMethodQualifier(MethodCall ma) { this = TThisArgument(ma) or this = TEnclosingInstanceAccess(ma, _) } @@ -234,7 +232,7 @@ class InstanceAccessExt extends TInstanceAccessExt { e instanceof InstanceAccess and result = e or exists(FieldAccess fa | fa = e | - if fa instanceof RValue then fa = result else result.(AssignExpr).getDest() = fa + if fa instanceof VarRead then fa = result else result.(AssignExpr).getDest() = fa ) ) } diff --git a/java/ql/lib/semmle/code/java/dataflow/IntegerGuards.qll b/java/ql/lib/semmle/code/java/dataflow/IntegerGuards.qll index 150721b574c1..58d77b649788 100644 --- a/java/ql/lib/semmle/code/java/dataflow/IntegerGuards.qll +++ b/java/ql/lib/semmle/code/java/dataflow/IntegerGuards.qll @@ -15,10 +15,10 @@ private Expr exprWithIntValue(int i) { /** * An expression for which the predicate `integerGuard` is relevant. - * This includes `RValue` and `MethodAccess`. + * This includes `VarRead` and `MethodCall`. */ class IntComparableExpr extends Expr { - IntComparableExpr() { this instanceof RValue or this instanceof MethodAccess } + IntComparableExpr() { this instanceof VarRead or this instanceof MethodCall } /** Gets an integer that is directly assigned to the expression in case of a variable; or zero. */ int relevantInt() { @@ -132,7 +132,7 @@ Expr integerGuard(IntComparableExpr e, boolean branch, int k, boolean is_k) { * If `branch_with_lower_bound_k` is true then `result` is equivalent to `k <= x` * and if it is false then `result` is equivalent to `k > x`. */ -Expr intBoundGuard(RValue x, boolean branch_with_lower_bound_k, int k) { +Expr intBoundGuard(VarRead x, boolean branch_with_lower_bound_k, int k) { exists(ComparisonExpr comp, ConstantIntegerExpr c, int val | comp = result and comp.hasOperands(x, c) and diff --git a/java/ql/lib/semmle/code/java/dataflow/NullGuards.qll b/java/ql/lib/semmle/code/java/dataflow/NullGuards.qll index 011932bc48b2..353d92cadc3b 100644 --- a/java/ql/lib/semmle/code/java/dataflow/NullGuards.qll +++ b/java/ql/lib/semmle/code/java/dataflow/NullGuards.qll @@ -79,7 +79,7 @@ Expr clearlyNotNullExpr(Expr reason) { (reason = r1 or reason = r2) ) or - exists(SsaVariable v, boolean branch, RValue rval, Guard guard | + exists(SsaVariable v, boolean branch, VarRead rval, Guard guard | guard = directNullGuard(v, branch, false) and guard.controls(rval.getBasicBlock(), branch) and reason = guard and @@ -89,7 +89,7 @@ Expr clearlyNotNullExpr(Expr reason) { or exists(SsaVariable v | clearlyNotNull(v, reason) and result = v.getAUse()) or - exists(Method m | m = result.(MethodAccess).getMethod() and reason = result | + exists(Method m | m = result.(MethodCall).getMethod() and reason = result | m.getDeclaringType().hasQualifiedName("com.google.common.base", "Strings") and m.hasName("nullToEmpty") ) @@ -187,7 +187,7 @@ Expr basicNullGuard(Expr e, boolean branch, boolean isnull) { or result.(InstanceOfExpr).getExpr() = e and branch = true and isnull = false or - exists(MethodAccess call | + exists(MethodCall call | call = result and call.getAnArgument() = e and nullCheckMethod(call.getMethod(), branch, isnull) @@ -212,7 +212,7 @@ Expr basicNullGuard(Expr e, boolean branch, boolean isnull) { Expr basicOrCustomNullGuard(Expr e, boolean branch, boolean isnull) { result = basicNullGuard(e, branch, isnull) or - exists(MethodAccess call, Method m, int ix | + exists(MethodCall call, Method m, int ix | call = result and call.getArgument(ix) = e and call.getMethod().getSourceDeclaration() = m and diff --git a/java/ql/lib/semmle/code/java/dataflow/Nullness.qll b/java/ql/lib/semmle/code/java/dataflow/Nullness.qll index 507da2904f43..4a7596705063 100644 --- a/java/ql/lib/semmle/code/java/dataflow/Nullness.qll +++ b/java/ql/lib/semmle/code/java/dataflow/Nullness.qll @@ -106,7 +106,7 @@ predicate dereference(Expr e) { or exists(FieldAccess fa, Field f | fa.getQualifier() = e and fa.getField() = f and not f.isStatic()) or - exists(MethodAccess ma, Method m | + exists(MethodCall ma, Method m | ma.getQualifier() = e and ma.getMethod() = m and not m.isStatic() ) or @@ -149,10 +149,10 @@ private ControlFlowNode ensureNotNull(SsaVariable v) { or exists(AssertNotNullMethod m | result = m.getACheck(v.getAUse())) or - exists(AssertThatMethod m, MethodAccess ma | + exists(AssertThatMethod m, MethodCall ma | result = m.getACheck(v.getAUse()) and ma.getControlFlowNode() = result | - ma.getAnArgument().(MethodAccess).getMethod().getName() = "notNullValue" + ma.getAnArgument().(MethodCall).getMethod().getName() = "notNullValue" ) } @@ -195,7 +195,7 @@ private predicate varMaybeNull(SsaVariable v, string msg, Expr reason) { not exists(TryStmt try | try.getFinally() = e.getEnclosingStmt().getEnclosingStmt*()) and ( e = any(ConditionalExpr c).getCondition().getAChildExpr*() or - not exists(MethodAccess ma | ma.getAnArgument().getAChildExpr*() = e) + not exists(MethodCall ma | ma.getAnArgument().getAChildExpr*() = e) ) and // Don't use a guard as reason if there is a null assignment. not v.(SsaExplicitUpdate).getDefiningExpr().(VariableAssign).getSource() = nullExpr() @@ -250,7 +250,7 @@ private Expr nonEmptyExpr() { // ...it is guarded by a condition... cond.controls(result.getBasicBlock(), branch) and // ...and it isn't modified in the scope of the condition... - forall(MethodAccess ma, Method m | + forall(MethodCall ma, Method m | m = ma.getMethod() and ma.getQualifier() = v.getSourceVariable().getAnAccess() and cond.controls(ma.getBasicBlock(), branch) @@ -260,12 +260,12 @@ private Expr nonEmptyExpr() { cond.getCondition() = c | // ...and the condition proves that it is non-empty, either by using the `isEmpty` method... - c.(MethodAccess).getMethod().hasName("isEmpty") and + c.(MethodCall).getMethod().hasName("isEmpty") and branch = false and - c.(MethodAccess).getQualifier() = v.getAUse() + c.(MethodCall).getQualifier() = v.getAUse() or // ...or a check on its `size`. - exists(MethodAccess size | + exists(MethodCall size | c = integerGuard(size, branch, 0, false) and size.getMethod().hasName("size") and size.getQualifier() = v.getAUse() @@ -485,7 +485,7 @@ private predicate correlatedConditions( inverted = branch1.booleanXor(branch2) ) or - exists(SsaVariable v, RValue rv1, RValue rv2, int k, boolean branch1, boolean branch2 | + exists(SsaVariable v, VarRead rv1, VarRead rv2, int k, boolean branch1, boolean branch2 | rv1 = v.getAUse() and rv2 = v.getAUse() and cond1.getCondition() = integerGuard(rv1, branch1, k, true) and diff --git a/java/ql/lib/semmle/code/java/dataflow/RangeAnalysis.qll b/java/ql/lib/semmle/code/java/dataflow/RangeAnalysis.qll index 8cdef89c6abf..2b2b539d5488 100644 --- a/java/ql/lib/semmle/code/java/dataflow/RangeAnalysis.qll +++ b/java/ql/lib/semmle/code/java/dataflow/RangeAnalysis.qll @@ -75,865 +75,387 @@ private import semmle.code.java.Reflection private import semmle.code.java.Collections private import semmle.code.java.Maps import Bound +private import codeql.rangeanalysis.RangeAnalysis -cached -private module RangeAnalysisCache { - cached - module RangeAnalysisPublic { - /** - * Holds if `b + delta` is a valid bound for `e`. - * - `upper = true` : `e <= b + delta` - * - `upper = false` : `e >= b + delta` - * - * The reason for the bound is given by `reason` and may be either a condition - * or `NoReason` if the bound was proven directly without the use of a bounding - * condition. - */ - cached - predicate bounded(Expr e, Bound b, int delta, boolean upper, Reason reason) { - bounded(e, b, delta, upper, _, _, reason) and - bestBound(e, b, delta, upper) +module Sem implements Semantic { + private import java as J + private import SSA as SSA + private import RangeUtils as RU + private import semmle.code.java.dataflow.internal.rangeanalysis.SsaReadPositionCommon as SsaReadPos + private import semmle.code.java.controlflow.internal.GuardsLogic as GL + + class Expr = J::Expr; + + class ConstantIntegerExpr = RU::ConstantIntegerExpr; + + abstract class BinaryExpr extends Expr { + Expr getLeftOperand() { + result = this.(J::BinaryExpr).getLeftOperand() or result = this.(J::AssignOp).getDest() + } + + Expr getRightOperand() { + result = this.(J::BinaryExpr).getRightOperand() or result = this.(J::AssignOp).getRhs() + } + + final Expr getAnOperand() { result = this.getLeftOperand() or result = this.getRightOperand() } + + final predicate hasOperands(Expr e1, Expr e2) { + this.getLeftOperand() = e1 and this.getRightOperand() = e2 + or + this.getLeftOperand() = e2 and this.getRightOperand() = e1 } } - /** - * Holds if `guard = boundFlowCond(_, _, _, _, _) or guard = eqFlowCond(_, _, _, _, _)`. - */ - cached - predicate possibleReason(Guard guard) { - guard = boundFlowCond(_, _, _, _, _) or guard = eqFlowCond(_, _, _, _, _) + class AddExpr extends BinaryExpr { + AddExpr() { this instanceof J::AddExpr or this instanceof J::AssignAddExpr } } -} -private import RangeAnalysisCache -import RangeAnalysisPublic + class SubExpr extends BinaryExpr { + SubExpr() { this instanceof J::SubExpr or this instanceof J::AssignSubExpr } + } -/** - * Holds if `b + delta` is a valid bound for `e` and this is the best such delta. - * - `upper = true` : `e <= b + delta` - * - `upper = false` : `e >= b + delta` - */ -private predicate bestBound(Expr e, Bound b, int delta, boolean upper) { - delta = min(int d | bounded(e, b, d, upper, _, _, _)) and upper = true - or - delta = max(int d | bounded(e, b, d, upper, _, _, _)) and upper = false -} + class MulExpr extends BinaryExpr { + MulExpr() { this instanceof J::MulExpr or this instanceof J::AssignMulExpr } + } -/** - * Holds if `comp` corresponds to: - * - `upper = true` : `v <= e + delta` or `v < e + delta` - * - `upper = false` : `v >= e + delta` or `v > e + delta` - */ -private predicate boundCondition( - ComparisonExpr comp, SsaVariable v, Expr e, int delta, boolean upper -) { - comp.getLesserOperand() = ssaRead(v, delta) and e = comp.getGreaterOperand() and upper = true - or - comp.getGreaterOperand() = ssaRead(v, delta) and e = comp.getLesserOperand() and upper = false - or - exists(SubExpr sub, ConstantIntegerExpr c, int d | - // (v - d) - e < c - comp.getLesserOperand() = sub and - comp.getGreaterOperand() = c and - sub.getLeftOperand() = ssaRead(v, d) and - sub.getRightOperand() = e and - upper = true and - delta = d + c.getIntValue() - or - // (v - d) - e > c - comp.getGreaterOperand() = sub and - comp.getLesserOperand() = c and - sub.getLeftOperand() = ssaRead(v, d) and - sub.getRightOperand() = e and - upper = false and - delta = d + c.getIntValue() - or - // e - (v - d) < c - comp.getLesserOperand() = sub and - comp.getGreaterOperand() = c and - sub.getLeftOperand() = e and - sub.getRightOperand() = ssaRead(v, d) and - upper = false and - delta = d - c.getIntValue() - or - // e - (v - d) > c - comp.getGreaterOperand() = sub and - comp.getLesserOperand() = c and - sub.getLeftOperand() = e and - sub.getRightOperand() = ssaRead(v, d) and - upper = true and - delta = d - c.getIntValue() - ) -} + class DivExpr extends BinaryExpr { + DivExpr() { this instanceof J::DivExpr or this instanceof J::AssignDivExpr } + } -/** - * Holds if `comp` is a comparison between `x` and `y` for which `y - x` has a - * fixed value modulo some `mod > 1`, such that the comparison can be - * strengthened by `strengthen` when evaluating to `testIsTrue`. - */ -private predicate modulusComparison(ComparisonExpr comp, boolean testIsTrue, int strengthen) { - exists( - Bound b, int v1, int v2, int mod1, int mod2, int mod, boolean resultIsStrict, int d, int k - | - // If `x <= y` and `x =(mod) b + v1` and `y =(mod) b + v2` then - // `0 <= y - x =(mod) v2 - v1`. By choosing `k =(mod) v2 - v1` with - // `0 <= k < mod` we get `k <= y - x`. If the resulting comparison is - // strict then the strengthening amount is instead `k - 1` modulo `mod`: - // `x < y` means `0 <= y - x - 1 =(mod) k - 1` so `k - 1 <= y - x - 1` and - // thus `k - 1 < y - x` with `0 <= k - 1 < mod`. - exprModulus(comp.getLesserOperand(), b, v1, mod1) and - exprModulus(comp.getGreaterOperand(), b, v2, mod2) and - mod = mod1.gcd(mod2) and - mod != 1 and - (testIsTrue = true or testIsTrue = false) and - ( - if comp.isStrict() - then resultIsStrict = testIsTrue - else resultIsStrict = testIsTrue.booleanNot() - ) and - ( - resultIsStrict = true and d = 1 - or - resultIsStrict = false and d = 0 - ) and - ( - testIsTrue = true and k = v2 - v1 - or - testIsTrue = false and k = v1 - v2 - ) and - strengthen = (((k - d) % mod) + mod) % mod - ) -} + class RemExpr extends BinaryExpr { + RemExpr() { this instanceof J::RemExpr or this instanceof J::AssignRemExpr } + } -/** - * Gets a condition that tests whether `v` is bounded by `e + delta`. - * - * If the condition evaluates to `testIsTrue`: - * - `upper = true` : `v <= e + delta` - * - `upper = false` : `v >= e + delta` - */ -private Guard boundFlowCond(SsaVariable v, Expr e, int delta, boolean upper, boolean testIsTrue) { - exists( - ComparisonExpr comp, int d1, int d2, int d3, int strengthen, boolean compIsUpper, - boolean resultIsStrict - | - comp = result and - boundCondition(comp, v, e, d1, compIsUpper) and - (testIsTrue = true or testIsTrue = false) and - upper = compIsUpper.booleanXor(testIsTrue.booleanNot()) and - ( - if comp.isStrict() - then resultIsStrict = testIsTrue - else resultIsStrict = testIsTrue.booleanNot() - ) and - ( - if v.getSourceVariable().getType() instanceof IntegralType - then - upper = true and strengthen = -1 - or - upper = false and strengthen = 1 - else strengthen = 0 - ) and - ( - exists(int k | modulusComparison(comp, testIsTrue, k) and d2 = strengthen * k) - or - not modulusComparison(comp, testIsTrue, _) and d2 = 0 - ) and - // A strict inequality `x < y` can be strengthened to `x <= y - 1`. - ( - resultIsStrict = true and d3 = strengthen - or - resultIsStrict = false and d3 = 0 - ) and - delta = d1 + d2 + d3 - ) - or - exists(boolean testIsTrue0 | - implies_v2(result, testIsTrue, boundFlowCond(v, e, delta, upper, testIsTrue0), testIsTrue0) - ) - or - result = eqFlowCond(v, e, delta, true, testIsTrue) and - (upper = true or upper = false) - or - // guard that tests whether `v2` is bounded by `e + delta + d1 - d2` and - // exists a guard `guardEq` such that `v = v2 - d1 + d2`. - exists(SsaVariable v2, int d | - // equality needs to control guard - result.getBasicBlock() = eqSsaCondDirectlyControls(v, v2, d) and - result = boundFlowCond(v2, e, delta - d, upper, testIsTrue) - ) -} + class BitAndExpr extends BinaryExpr { + BitAndExpr() { this instanceof J::AndBitwiseExpr or this instanceof J::AssignAndExpr } + } -/** - * Gets a basic block in which `v1` equals `v2 + delta`. - */ -pragma[nomagic] -private BasicBlock eqSsaCondDirectlyControls(SsaVariable v1, SsaVariable v2, int delta) { - exists(Guard guardEq, int d1, int d2, boolean eqIsTrue | - guardEq = eqFlowCond(v1, ssaRead(v2, d1), d2, true, eqIsTrue) and - delta = d2 - d1 and - guardEq.directlyControls(result, eqIsTrue) - ) -} + class BitOrExpr extends BinaryExpr { + BitOrExpr() { this instanceof J::OrBitwiseExpr or this instanceof J::AssignOrExpr } + } -private newtype TReason = - TNoReason() or - TCondReason(Guard guard) { possibleReason(guard) } + class ShiftLeftExpr extends BinaryExpr { + ShiftLeftExpr() { this instanceof J::LeftShiftExpr or this instanceof J::AssignLeftShiftExpr } + } -/** - * A reason for an inferred bound. This can either be `CondReason` if the bound - * is due to a specific condition, or `NoReason` if the bound is inferred - * without going through a bounding condition. - */ -abstract class Reason extends TReason { - /** Gets a textual representation of this reason. */ - abstract string toString(); -} + class ShiftRightExpr extends BinaryExpr { + ShiftRightExpr() { + this instanceof J::RightShiftExpr or this instanceof J::AssignRightShiftExpr + } + } -/** - * A reason for an inferred bound that indicates that the bound is inferred - * without going through a bounding condition. - */ -class NoReason extends Reason, TNoReason { - override string toString() { result = "NoReason" } -} + class ShiftRightUnsignedExpr extends BinaryExpr { + ShiftRightUnsignedExpr() { + this instanceof J::UnsignedRightShiftExpr or this instanceof J::AssignUnsignedRightShiftExpr + } + } -/** A reason for an inferred bound pointing to a condition. */ -class CondReason extends Reason, TCondReason { - /** Gets the condition that is the reason for the bound. */ - Guard getCond() { this = TCondReason(result) } + class RelationalExpr = J::ComparisonExpr; - override string toString() { result = this.getCond().toString() } -} + abstract class UnaryExpr extends Expr { + abstract Expr getOperand(); + } -/** - * Holds if `e + delta` is a valid bound for `v` at `pos`. - * - `upper = true` : `v <= e + delta` - * - `upper = false` : `v >= e + delta` - */ -private predicate boundFlowStepSsa( - SsaVariable v, SsaReadPosition pos, Expr e, int delta, boolean upper, Reason reason -) { - ssaUpdateStep(v, e, delta) and - pos.hasReadOfVar(v) and - (upper = true or upper = false) and - reason = TNoReason() - or - exists(Guard guard, boolean testIsTrue | - pos.hasReadOfVar(v) and - guard = boundFlowCond(v, e, delta, upper, testIsTrue) and - guardDirectlyControlsSsaRead(guard, pos, testIsTrue) and - reason = TCondReason(guard) - ) -} + class ConvertExpr extends UnaryExpr instanceof CastingExpr { + override Expr getOperand() { result = super.getExpr() } + } -/** Holds if `v != e + delta` at `pos` and `v` is of integral type. */ -private predicate unequalFlowStepIntegralSsa( - SsaVariable v, SsaReadPosition pos, Expr e, int delta, Reason reason -) { - v.getSourceVariable().getType() instanceof IntegralType and - exists(Guard guard, boolean testIsTrue | - pos.hasReadOfVar(v) and - guard = eqFlowCond(v, e, delta, false, testIsTrue) and - guardDirectlyControlsSsaRead(guard, pos, testIsTrue) and - reason = TCondReason(guard) - ) -} + class BoxExpr extends UnaryExpr { + BoxExpr() { none() } -/** - * Holds if a cast from `fromtyp` to `totyp` can be ignored for the purpose of - * range analysis. - */ -private predicate safeCast(Type fromtyp, Type totyp) { - exists(PrimitiveType pfrom, PrimitiveType pto | pfrom = fromtyp and pto = totyp | - pfrom = pto - or - pfrom.hasName("char") and pto.hasName(["int", "long", "float", "double"]) - or - pfrom.hasName("byte") and pto.hasName(["short", "int", "long", "float", "double"]) - or - pfrom.hasName("short") and pto.hasName(["int", "long", "float", "double"]) - or - pfrom.hasName("int") and pto.hasName(["long", "float", "double"]) - or - pfrom.hasName("long") and pto.hasName(["float", "double"]) - or - pfrom.hasName("float") and pto.hasName("double") - or - pfrom.hasName("double") and pto.hasName("float") - ) - or - safeCast(fromtyp.(BoxedType).getPrimitiveType(), totyp) - or - safeCast(fromtyp, totyp.(BoxedType).getPrimitiveType()) -} + override Expr getOperand() { none() } + } -/** - * A cast that can be ignored for the purpose of range analysis. - */ -private class RangeAnalysisSafeCastingExpr extends CastingExpr { - RangeAnalysisSafeCastingExpr() { - safeCast(this.getExpr().getType(), this.getType()) or - this instanceof ImplicitCastExpr or - this instanceof ImplicitNotNullExpr or - this instanceof ImplicitCoercionToUnitExpr + class UnboxExpr extends UnaryExpr { + UnboxExpr() { none() } + + override Expr getOperand() { none() } } -} -/** - * Holds if `typ` is a small integral type with the given lower and upper bounds. - */ -private predicate typeBound(Type typ, int lowerbound, int upperbound) { - typ.(PrimitiveType).hasName("byte") and lowerbound = -128 and upperbound = 127 - or - typ.(PrimitiveType).hasName("short") and lowerbound = -32768 and upperbound = 32767 - or - typ.(PrimitiveType).hasName("char") and lowerbound = 0 and upperbound = 65535 - or - typeBound(typ.(BoxedType).getPrimitiveType(), lowerbound, upperbound) -} + class NegateExpr extends UnaryExpr instanceof MinusExpr { + override Expr getOperand() { result = super.getExpr() } + } -/** - * A cast to a small integral type that may overflow or underflow. - */ -private class NarrowingCastingExpr extends CastingExpr { - NarrowingCastingExpr() { - not this instanceof RangeAnalysisSafeCastingExpr and - typeBound(this.getType(), _, _) + // TODO: Implement once utils are properly shared + class AddOneExpr extends UnaryExpr { + AddOneExpr() { none() } + + override Expr getOperand() { none() } } - /** Gets the lower bound of the resulting type. */ - int getLowerBound() { typeBound(this.getType(), result, _) } + // TODO: Implement once utils are properly shared + class SubOneExpr extends UnaryExpr { + SubOneExpr() { none() } - /** Gets the upper bound of the resulting type. */ - int getUpperBound() { typeBound(this.getType(), _, result) } -} + override Expr getOperand() { none() } + } -/** Holds if `e >= 1` as determined by sign analysis. */ -private predicate strictlyPositiveIntegralExpr(Expr e) { - strictlyPositive(e) and e.getType() instanceof IntegralType -} + class ConditionalExpr = J::ConditionalExpr; + + class BasicBlock = J::BasicBlock; + + class Guard extends GL::Guard { + Expr asExpr() { result = this } + } + + predicate implies_v2(Guard g1, boolean b1, Guard g2, boolean b2) { + GL::implies_v2(g1, b1, g2, b2) + } + + predicate guardDirectlyControlsSsaRead(Guard guard, SsaReadPosition controlled, boolean testIsTrue) { + RU::guardDirectlyControlsSsaRead(guard, controlled, testIsTrue) + } + + class Type = J::Type; + + class IntegerType extends J::IntegralType { + predicate isSigned() { not this instanceof CharacterType } + } + + class FloatingPointType extends Type { + FloatingPointType() { none() } + } + + class AddressType extends Type { + AddressType() { none() } + } -/** Holds if `e <= -1` as determined by sign analysis. */ -private predicate strictlyNegativeIntegralExpr(Expr e) { - strictlyNegative(e) and e.getType() instanceof IntegralType + final private class FinalSsaVariable = SSA::SsaVariable; + + class SsaVariable extends FinalSsaVariable { + Expr getAUse() { result = super.getAUse() } + } + + class SsaPhiNode extends SsaVariable instanceof SSA::SsaPhiNode { } + + class SsaExplicitUpdate extends SsaVariable instanceof SSA::SsaExplicitUpdate { } + + final private class FinalSsaReadPosition = SsaReadPos::SsaReadPosition; + + class SsaReadPosition extends FinalSsaReadPosition { + predicate hasReadOfVar(SsaVariable v) { super.hasReadOfVar(v) } + } + + class SsaReadPositionPhiInputEdge extends SsaReadPosition instanceof SsaReadPos::SsaReadPositionPhiInputEdge + { + predicate phiInput(SsaPhiNode phi, SsaVariable inp) { super.phiInput(phi, inp) } + } + + class SsaReadPositionBlock extends SsaReadPosition instanceof SsaReadPos::SsaReadPositionBlock { + BasicBlock getBlock() { result = super.getBlock() } + } + + predicate backEdge(SsaPhiNode phi, SsaVariable inp, SsaReadPositionPhiInputEdge edge) { + RU::backEdge(phi, inp, edge) + } + + predicate conversionCannotOverflow = safeCast/2; } -/** - * Holds if `e1 + delta` is a valid bound for `e2`. - * - `upper = true` : `e2 <= e1 + delta` - * - `upper = false` : `e2 >= e1 + delta` - */ -private predicate boundFlowStep(Expr e2, Expr e1, int delta, boolean upper) { - valueFlowStep(e2, e1, delta) and - (upper = true or upper = false) - or - e2.(RangeAnalysisSafeCastingExpr).getExpr() = e1 and - delta = 0 and - (upper = true or upper = false) - or - exists(Expr x | - exists(SubExpr sub | - e2 = sub and - sub.getLeftOperand() = e1 and - sub.getRightOperand() = x - ) - or - exists(AssignSubExpr sub | - e2 = sub and - sub.getDest() = e1 and - sub.getRhs() = x - ) - | - // `x instanceof ConstantIntegerExpr` is covered by valueFlowStep - not x instanceof ConstantIntegerExpr and - if strictlyPositiveIntegralExpr(x) - then upper = true and delta = -1 - else - if positive(x) - then upper = true and delta = 0 - else - if strictlyNegativeIntegralExpr(x) - then upper = false and delta = 1 - else - if negative(x) - then upper = false and delta = 0 - else none() - ) - or - e2.(RemExpr).getRightOperand() = e1 and positive(e1) and delta = -1 and upper = true - or - e2.(RemExpr).getLeftOperand() = e1 and positive(e1) and delta = 0 and upper = true - or - e2.(AssignRemExpr).getRhs() = e1 and positive(e1) and delta = -1 and upper = true - or - e2.(AssignRemExpr).getDest() = e1 and positive(e1) and delta = 0 and upper = true - or - e2.(AndBitwiseExpr).getAnOperand() = e1 and positive(e1) and delta = 0 and upper = true - or - e2.(AssignAndExpr).getSource() = e1 and positive(e1) and delta = 0 and upper = true - or - e2.(OrBitwiseExpr).getAnOperand() = e1 and positive(e2) and delta = 0 and upper = false - or - e2.(AssignOrExpr).getSource() = e1 and positive(e2) and delta = 0 and upper = false - or - exists(RandomDataSource rds | - e2 = rds.getOutput() and - ( - e1 = rds.getUpperBoundExpr() and - delta = -1 and - upper = true - or - e1 = rds.getLowerBoundExpr() and - delta = 0 and - upper = false - ) - ) - or - exists(MethodAccess ma, Method m | - e2 = ma and - ma.getMethod() = m and - ( - m.hasName("max") and upper = false - or - m.hasName("min") and upper = true - ) and - m.getDeclaringType().hasQualifiedName("java.lang", "Math") and - e1 = ma.getAnArgument() and - delta = 0 - ) +module SignInp implements SignAnalysisSig { + private import SignAnalysis + private import internal.rangeanalysis.Sign + + predicate semPositive = positive/1; + + predicate semNegative = negative/1; + + predicate semStrictlyPositive = strictlyPositive/1; + + predicate semStrictlyNegative = strictlyNegative/1; + + predicate semMayBePositive(Sem::Expr e) { exprSign(e) = TPos() } + + predicate semMayBeNegative(Sem::Expr e) { exprSign(e) = TNeg() } } -/** Holds if `e2 = e1 * factor` and `factor > 0`. */ -private predicate boundFlowStepMul(Expr e2, Expr e1, int factor) { - exists(ConstantIntegerExpr c, int k | k = c.getIntValue() and k > 0 | - e2.(MulExpr).hasOperands(e1, c) and factor = k - or - exists(AssignMulExpr e | e = e2 and e.getDest() = e1 and e.getRhs() = c and factor = k) - or - exists(AssignMulExpr e | e = e2 and e.getDest() = c and e.getRhs() = e1 and factor = k) - or - exists(LeftShiftExpr e | - e = e2 and e.getLeftOperand() = e1 and e.getRightOperand() = c and factor = 2.pow(k) - ) - or - exists(AssignLeftShiftExpr e | - e = e2 and e.getDest() = e1 and e.getRhs() = c and factor = 2.pow(k) - ) - ) +module Modulus implements ModulusAnalysisSig { + class ModBound = Bound; + + predicate semExprModulus = exprModulus/4; } -/** - * Holds if `e2 = e1 / factor` and `factor > 0`. - * - * This conflates division, right shift, and unsigned right shift and is - * therefore only valid for non-negative numbers. - */ -private predicate boundFlowStepDiv(Expr e2, Expr e1, int factor) { - exists(ConstantIntegerExpr c, int k | k = c.getIntValue() and k > 0 | - exists(DivExpr e | - e = e2 and e.getLeftOperand() = e1 and e.getRightOperand() = c and factor = k - ) - or - exists(AssignDivExpr e | e = e2 and e.getDest() = e1 and e.getRhs() = c and factor = k) - or - exists(RightShiftExpr e | - e = e2 and e.getLeftOperand() = e1 and e.getRightOperand() = c and factor = 2.pow(k) - ) - or - exists(AssignRightShiftExpr e | - e = e2 and e.getDest() = e1 and e.getRhs() = c and factor = 2.pow(k) - ) - or - exists(UnsignedRightShiftExpr e | - e = e2 and e.getLeftOperand() = e1 and e.getRightOperand() = c and factor = 2.pow(k) - ) - or - exists(AssignUnsignedRightShiftExpr e | - e = e2 and e.getDest() = e1 and e.getRhs() = c and factor = 2.pow(k) - ) - ) +module IntDelta implements DeltaSig { + class Delta = int; + + bindingset[d] + bindingset[result] + float toFloat(Delta d) { result = d } + + bindingset[d] + bindingset[result] + int toInt(Delta d) { result = d } + + bindingset[n] + bindingset[result] + Delta fromInt(int n) { result = n } + + bindingset[f] + Delta fromFloat(float f) { result = f } } -/** - * Holds if `b + delta` is a valid bound for `v` at `pos`. - * - `upper = true` : `v <= b + delta` - * - `upper = false` : `v >= b + delta` - */ -private predicate boundedSsa( - SsaVariable v, SsaReadPosition pos, Bound b, int delta, boolean upper, boolean fromBackEdge, - int origdelta, Reason reason -) { - exists(Expr mid, int d1, int d2, Reason r1, Reason r2 | - boundFlowStepSsa(v, pos, mid, d1, upper, r1) and - bounded(mid, b, d2, upper, fromBackEdge, origdelta, r2) and - // upper = true: v <= mid + d1 <= b + d1 + d2 = b + delta - // upper = false: v >= mid + d1 >= b + d1 + d2 = b + delta - delta = d1 + d2 and - (if r1 instanceof NoReason then reason = r2 else reason = r1) - ) - or - exists(int d, Reason r1, Reason r2 | - boundedSsa(v, pos, b, d, upper, fromBackEdge, origdelta, r2) or - boundedPhi(v, b, d, upper, fromBackEdge, origdelta, r2) - | - unequalIntegralSsa(v, pos, b, d, r1) and +module JavaLangImpl implements LangSig { + predicate ignoreSsaReadCopy(Sem::Expr e) { none() } + + /** + * Holds if `e >= bound` (if `upper = false`) or `e <= bound` (if `upper = true`). + */ + predicate hasConstantBound(Sem::Expr e, int bound, boolean upper) { ( - upper = true and delta = d - 1 - or - upper = false and delta = d + 1 + e.(MethodCall).getMethod() instanceof StringLengthMethod or + e.(MethodCall).getMethod() instanceof CollectionSizeMethod or + e.(MethodCall).getMethod() instanceof MapSizeMethod or + e.(FieldRead).getField() instanceof ArrayLengthField ) and - ( - reason = r1 + bound = 0 and + upper = false + or + exists(Method read | + e.(MethodCall).getMethod().overrides*(read) and + read.getDeclaringType() instanceof TypeInputStream and + read.hasName("read") and + read.getNumberOfParameters() = 0 + | + upper = true and bound = 255 or - reason = r2 and not r2 instanceof NoReason + upper = false and bound = -1 ) - ) -} - -/** - * Holds if `v != b + delta` at `pos` and `v` is of integral type. - */ -private predicate unequalIntegralSsa( - SsaVariable v, SsaReadPosition pos, Bound b, int delta, Reason reason -) { - exists(Expr e, int d1, int d2 | - unequalFlowStepIntegralSsa(v, pos, e, d1, reason) and - bounded(e, b, d2, true, _, _, _) and - bounded(e, b, d2, false, _, _, _) and - delta = d2 + d1 - ) -} - -/** Weakens a delta to lie in the range `[-1..1]`. */ -bindingset[delta, upper] -private int weakenDelta(boolean upper, int delta) { - delta in [-1 .. 1] and result = delta - or - upper = true and result = -1 and delta < -1 - or - upper = false and result = 1 and delta > 1 -} + } -/** - * Holds if `b + delta` is a valid bound for `inp` when used as an input to - * `phi` along `edge`. - * - `upper = true` : `inp <= b + delta` - * - `upper = false` : `inp >= b + delta` - */ -private predicate boundedPhiInp( - SsaPhiNode phi, SsaVariable inp, SsaReadPositionPhiInputEdge edge, Bound b, int delta, - boolean upper, boolean fromBackEdge, int origdelta, Reason reason -) { - edge.phiInput(phi, inp) and - exists(int d, boolean fromBackEdge0 | - boundedSsa(inp, edge, b, d, upper, fromBackEdge0, origdelta, reason) - or - boundedPhi(inp, b, d, upper, fromBackEdge0, origdelta, reason) - or - b.(SsaBound).getSsa() = inp and - d = 0 and - (upper = true or upper = false) and - fromBackEdge0 = false and - origdelta = 0 and - reason = TNoReason() - | - if backEdge(phi, inp, edge) - then - fromBackEdge = true and + /** + * Holds if `e2 >= e1 + delta` (if `upper = false`) or `e2 <= e1 + delta` (if `upper = true`). + */ + predicate hasBound(Sem::Expr e2, Sem::Expr e1, int delta, boolean upper) { + exists(RandomDataSource rds | + e2 = rds.getOutput() and ( - fromBackEdge0 = true and delta = weakenDelta(upper, d - origdelta) + origdelta + e1 = rds.getUpperBoundExpr() and + delta = -1 and + upper = true or - fromBackEdge0 = false and delta = d + e1 = rds.getLowerBoundExpr() and + delta = 0 and + upper = false ) - else ( - delta = d and fromBackEdge = fromBackEdge0 ) - ) -} + or + exists(MethodCall ma, Method m | + e2 = ma and + ma.getMethod() = m and + ( + m.hasName("max") and upper = false + or + m.hasName("min") and upper = true + ) and + m.getDeclaringType().hasQualifiedName("java.lang", "Math") and + e1 = ma.getAnArgument() and + delta = 0 + ) + } -/** Holds if `boundedPhiInp(phi, inp, edge, b, delta, upper, _, _, _)`. */ -pragma[noinline] -private predicate boundedPhiInp1( - SsaPhiNode phi, Bound b, boolean upper, SsaVariable inp, SsaReadPositionPhiInputEdge edge, - int delta -) { - boundedPhiInp(phi, inp, edge, b, delta, upper, _, _, _) -} + predicate ignoreExprBound(Sem::Expr e) { none() } -/** - * Holds if `phi` is a valid bound for `inp` when used as an input to `phi` - * along `edge`. - * - `upper = true` : `inp <= phi` - * - `upper = false` : `inp >= phi` - */ -private predicate selfBoundedPhiInp( - SsaPhiNode phi, SsaVariable inp, SsaReadPositionPhiInputEdge edge, boolean upper -) { - exists(int d, SsaBound phibound | - phibound.getSsa() = phi and - boundedPhiInp(phi, inp, edge, phibound, d, upper, _, _, _) and - ( - upper = true and d <= 0 - or - upper = false and d >= 0 - ) - ) -} + predicate ignoreZeroLowerBound(Sem::Expr e) { none() } -/** - * Holds if `b + delta` is a valid bound for some input, `inp`, to `phi`, and - * thus a candidate bound for `phi`. - * - `upper = true` : `inp <= b + delta` - * - `upper = false` : `inp >= b + delta` - */ -pragma[noinline] -private predicate boundedPhiCand( - SsaPhiNode phi, boolean upper, Bound b, int delta, boolean fromBackEdge, int origdelta, - Reason reason -) { - boundedPhiInp(phi, _, _, b, delta, upper, fromBackEdge, origdelta, reason) -} + predicate ignoreSsaReadArithmeticExpr(Sem::Expr e) { none() } -/** - * Holds if the candidate bound `b + delta` for `phi` is valid for the phi input - * `inp` along `edge`. - */ -private predicate boundedPhiCandValidForEdge( - SsaPhiNode phi, Bound b, int delta, boolean upper, boolean fromBackEdge, int origdelta, - Reason reason, SsaVariable inp, SsaReadPositionPhiInputEdge edge -) { - boundedPhiCand(phi, upper, b, delta, fromBackEdge, origdelta, reason) and - ( - exists(int d | boundedPhiInp1(phi, b, upper, inp, edge, d) | upper = true and d <= delta) - or - exists(int d | boundedPhiInp1(phi, b, upper, inp, edge, d) | upper = false and d >= delta) - or - selfBoundedPhiInp(phi, inp, edge, upper) - ) -} + predicate ignoreSsaReadAssignment(Sem::SsaVariable v) { none() } -/** - * Holds if `b + delta` is a valid bound for `phi`'s `rix`th input edge. - * - `upper = true` : `phi <= b + delta` - * - `upper = false` : `phi >= b + delta` - */ -private predicate boundedPhiStep( - SsaPhiNode phi, Bound b, int delta, boolean upper, boolean fromBackEdge, int origdelta, - Reason reason, int rix -) { - exists(SsaVariable inp, SsaReadPositionPhiInputEdge edge | - rankedPhiInput(phi, inp, edge, rix) and - boundedPhiCandValidForEdge(phi, b, delta, upper, fromBackEdge, origdelta, reason, inp, edge) and - ( - rix = 1 - or - boundedPhiStep(phi, b, delta, upper, fromBackEdge, origdelta, reason, rix - 1) - ) - ) -} + Sem::Expr specificSsaRead(Sem::SsaVariable v, int delta) { none() } -/** - * Holds if `b + delta` is a valid bound for `phi`. - * - `upper = true` : `phi <= b + delta` - * - `upper = false` : `phi >= b + delta` - */ -private predicate boundedPhi( - SsaPhiNode phi, Bound b, int delta, boolean upper, boolean fromBackEdge, int origdelta, - Reason reason -) { - exists(int r | - boundedPhiStep(phi, b, delta, upper, fromBackEdge, origdelta, reason, r) and - maxPhiInputRank(phi, r) - ) -} + predicate additionalValueFlowStep(Sem::Expr dest, Sem::Expr src, int delta) { none() } -/** - * Holds if `e` has a lower bound of zero. - */ -private predicate lowerBoundZero(Expr e) { - e.(MethodAccess).getMethod() instanceof StringLengthMethod or - e.(MethodAccess).getMethod() instanceof CollectionSizeMethod or - e.(MethodAccess).getMethod() instanceof MapSizeMethod or - e.(FieldRead).getField() instanceof ArrayLengthField or - positive(e.(AndBitwiseExpr).getAnOperand()) + Sem::Type getAlternateType(Sem::Expr e) { none() } + + Sem::Type getAlternateTypeForSsaVariable(Sem::SsaVariable var) { none() } + + predicate javaCompatibility() { any() } } -/** - * Holds if `e` has an upper (for `upper = true`) or lower - * (for `upper = false`) bound of `b`. - */ -private predicate baseBound(Expr e, int b, boolean upper) { - lowerBoundZero(e) and b = 0 and upper = false - or - exists(Method read | - e.(MethodAccess).getMethod().overrides*(read) and - read.getDeclaringType() instanceof TypeInputStream and - read.hasName("read") and - read.getNumberOfParameters() = 0 - | - upper = true and b = 255 - or - upper = false and b = -1 - ) +module Utils implements UtilSig { + private import RangeUtils as RU + private import semmle.code.java.dataflow.internal.rangeanalysis.SsaReadPositionCommon as SsaReadPos + + Sem::Expr semSsaRead(Sem::SsaVariable v, int delta) { result = RU::ssaRead(v, delta) } + + Sem::Guard semEqFlowCond( + Sem::SsaVariable v, Sem::Expr e, int delta, boolean isEq, boolean testIsTrue + ) { + result = RU::eqFlowCond(v, e, delta, isEq, testIsTrue) + } + + predicate semSsaUpdateStep(Sem::SsaExplicitUpdate v, Sem::Expr e, int delta) { + RU::ssaUpdateStep(v, e, delta) + } + + predicate semValueFlowStep = RU::valueFlowStep/3; + + Sem::Type getTrackedTypeForSsaVariable(Sem::SsaVariable var) { + result = var.getSourceVariable().getType() + } + + Sem::Type getTrackedType(Sem::Expr e) { result = e.getType() } + + predicate rankedPhiInput( + Sem::SsaPhiNode phi, Sem::SsaVariable inp, Sem::SsaReadPositionPhiInputEdge edge, int r + ) { + SsaReadPos::rankedPhiInput(phi, inp, edge, r) + } + + predicate maxPhiInputRank(Sem::SsaPhiNode phi, int rix) { SsaReadPos::maxPhiInputRank(phi, rix) } } -/** - * Holds if the value being cast has an upper (for `upper = true`) or lower - * (for `upper = false`) bound within the bounds of the resulting type. - * For `upper = true` this means that the cast will not overflow and for - * `upper = false` this means that the cast will not underflow. - */ -private predicate safeNarrowingCast(NarrowingCastingExpr cast, boolean upper) { - exists(int bound | bounded(cast.getExpr(), any(ZeroBound zb), bound, upper, _, _, _) | - upper = true and bound <= cast.getUpperBound() - or - upper = false and bound >= cast.getLowerBound() - ) +module Bounds implements BoundSig { + class SemBound = Bound; + + class SemZeroBound = ZeroBound; + + class SemSsaBound extends SsaBound { + Sem::SsaVariable getAVariable() { result = super.getSsa() } + } } -pragma[noinline] -private predicate boundedCastExpr( - NarrowingCastingExpr cast, Bound b, int delta, boolean upper, boolean fromBackEdge, int origdelta, - Reason reason -) { - bounded(cast.getExpr(), b, delta, upper, fromBackEdge, origdelta, reason) +module Overflow implements OverflowSig { + predicate semExprDoesNotOverflow(boolean positively, Sem::Expr expr) { + positively = [true, false] and exists(expr) + } } +module Range = + RangeStage; + +predicate bounded = Range::semBounded/5; + +class Reason = Range::SemReason; + +class NoReason = Range::SemNoReason; + +class CondReason = Range::SemCondReason; + /** - * Holds if `b + delta` is a valid bound for `e`. - * - `upper = true` : `e <= b + delta` - * - `upper = false` : `e >= b + delta` + * Holds if a cast from `fromtyp` to `totyp` can be ignored for the purpose of + * range analysis. */ -private predicate bounded( - Expr e, Bound b, int delta, boolean upper, boolean fromBackEdge, int origdelta, Reason reason -) { - e = b.getExpr(delta) and - (upper = true or upper = false) and - fromBackEdge = false and - origdelta = delta and - reason = TNoReason() - or - baseBound(e, delta, upper) and - b instanceof ZeroBound and - fromBackEdge = false and - origdelta = delta and - reason = TNoReason() - or - exists(SsaVariable v, SsaReadPositionBlock bb | - boundedSsa(v, bb, b, delta, upper, fromBackEdge, origdelta, reason) and - e = v.getAUse() and - bb.getBlock() = e.getBasicBlock() - ) - or - exists(Expr mid, int d1, int d2 | - boundFlowStep(e, mid, d1, upper) and - // Constants have easy, base-case bounds, so let's not infer any recursive bounds. - not e instanceof ConstantIntegerExpr and - bounded(mid, b, d2, upper, fromBackEdge, origdelta, reason) and - // upper = true: e <= mid + d1 <= b + d1 + d2 = b + delta - // upper = false: e >= mid + d1 >= b + d1 + d2 = b + delta - delta = d1 + d2 - ) - or - exists(SsaPhiNode phi | - boundedPhi(phi, b, delta, upper, fromBackEdge, origdelta, reason) and - e = phi.getAUse() - ) - or - exists(Expr mid, int factor, int d | - boundFlowStepMul(e, mid, factor) and - not e instanceof ConstantIntegerExpr and - bounded(mid, b, d, upper, fromBackEdge, origdelta, reason) and - b instanceof ZeroBound and - delta = d * factor - ) - or - exists(Expr mid, int factor, int d | - boundFlowStepDiv(e, mid, factor) and - not e instanceof ConstantIntegerExpr and - bounded(mid, b, d, upper, fromBackEdge, origdelta, reason) and - b instanceof ZeroBound and - d >= 0 and - delta = d / factor - ) - or - exists(NarrowingCastingExpr cast | - cast = e and - safeNarrowingCast(cast, upper.booleanNot()) and - boundedCastExpr(cast, b, delta, upper, fromBackEdge, origdelta, reason) - ) - or - exists( - ConditionalExpr cond, int d1, int d2, boolean fbe1, boolean fbe2, int od1, int od2, Reason r1, - Reason r2 - | - cond = e and - boundedConditionalExpr(cond, b, upper, true, d1, fbe1, od1, r1) and - boundedConditionalExpr(cond, b, upper, false, d2, fbe2, od2, r2) and - ( - delta = d1 and fromBackEdge = fbe1 and origdelta = od1 and reason = r1 - or - delta = d2 and fromBackEdge = fbe2 and origdelta = od2 and reason = r2 - ) - | - upper = true and delta = d1.maximum(d2) +private predicate safeCast(Type fromtyp, Type totyp) { + exists(PrimitiveType pfrom, PrimitiveType pto | pfrom = fromtyp and pto = totyp | + pfrom = pto or - upper = false and delta = d1.minimum(d2) - ) - or - exists( - Bound b1, Bound b2, int d1, int d2, boolean fbe1, boolean fbe2, int od1, int od2, Reason r1, - Reason r2 - | - boundedAddition(e, upper, b1, true, d1, fbe1, od1, r1) and - boundedAddition(e, upper, b2, false, d2, fbe2, od2, r2) and - delta = d1 + d2 and - fromBackEdge = fbe1.booleanOr(fbe2) - | - b = b1 and origdelta = od1 and reason = r1 and b2 instanceof ZeroBound + pfrom.hasName("char") and pto.hasName(["int", "long", "float", "double"]) or - b = b2 and origdelta = od2 and reason = r2 and b1 instanceof ZeroBound - ) -} - -private predicate boundedConditionalExpr( - ConditionalExpr cond, Bound b, boolean upper, boolean branch, int delta, boolean fromBackEdge, - int origdelta, Reason reason -) { - bounded(cond.getBranchExpr(branch), b, delta, upper, fromBackEdge, origdelta, reason) -} - -private predicate nonConstAdd(Expr add, Expr operand, boolean isLeft) { - exists(Expr other | - add.(AddExpr).getLeftOperand() = operand and - add.(AddExpr).getRightOperand() = other and - isLeft = true + pfrom.hasName("byte") and pto.hasName(["short", "int", "long", "float", "double"]) or - add.(AddExpr).getLeftOperand() = other and - add.(AddExpr).getRightOperand() = operand and - isLeft = false + pfrom.hasName("short") and pto.hasName(["int", "long", "float", "double"]) or - add.(AssignAddExpr).getDest() = operand and - add.(AssignAddExpr).getRhs() = other and - isLeft = true + pfrom.hasName("int") and pto.hasName(["long", "float", "double"]) or - add.(AssignAddExpr).getDest() = other and - add.(AssignAddExpr).getRhs() = operand and - isLeft = false - | - // `ConstantIntegerExpr` is covered by valueFlowStep - not other instanceof ConstantIntegerExpr and - not operand instanceof ConstantIntegerExpr - ) -} - -private predicate boundedAddition( - Expr add, boolean upper, Bound b, boolean isLeft, int delta, boolean fromBackEdge, int origdelta, - Reason reason -) { - exists(Expr op | - nonConstAdd(add, op, isLeft) and - bounded(op, b, delta, upper, fromBackEdge, origdelta, reason) + pfrom.hasName("long") and pto.hasName(["float", "double"]) + or + pfrom.hasName("float") and pto.hasName("double") + or + pfrom.hasName("double") and pto.hasName("float") ) + or + safeCast(fromtyp.(BoxedType).getPrimitiveType(), totyp) + or + safeCast(fromtyp, totyp.(BoxedType).getPrimitiveType()) } diff --git a/java/ql/lib/semmle/code/java/dataflow/RangeUtils.qll b/java/ql/lib/semmle/code/java/dataflow/RangeUtils.qll index be7f12920914..1336caac6544 100644 --- a/java/ql/lib/semmle/code/java/dataflow/RangeUtils.qll +++ b/java/ql/lib/semmle/code/java/dataflow/RangeUtils.qll @@ -145,6 +145,9 @@ class ConstantStringExpr extends Expr { string getStringValue() { constantStringExpr(this, result) } } +bindingset[f] +private predicate okInt(float f) { -2.pow(31) <= f and f <= 2.pow(31) - 1 } + /** * Gets an expression that equals `v - d`. */ @@ -153,14 +156,16 @@ Expr ssaRead(SsaVariable v, int delta) { or exists(int d1, ConstantIntegerExpr c | result.(AddExpr).hasOperands(ssaRead(v, d1), c) and - delta = d1 - c.getIntValue() + delta = d1 - c.getIntValue() and + okInt(d1.(float) - c.getIntValue().(float)) ) or exists(SubExpr sub, int d1, ConstantIntegerExpr c | result = sub and sub.getLeftOperand() = ssaRead(v, d1) and sub.getRightOperand() = c and - delta = d1 + c.getIntValue() + delta = d1 + c.getIntValue() and + okInt(d1.(float) + c.getIntValue().(float)) ) or v.(SsaExplicitUpdate).getDefiningExpr().(PreIncExpr) = result and delta = 0 diff --git a/java/ql/lib/semmle/code/java/dataflow/SSA.qll b/java/ql/lib/semmle/code/java/dataflow/SSA.qll index fb2e87e9bc77..0fc0da8e8715 100644 --- a/java/ql/lib/semmle/code/java/dataflow/SSA.qll +++ b/java/ql/lib/semmle/code/java/dataflow/SSA.qll @@ -275,7 +275,7 @@ private module SsaImpl { } /** Holds if `VarAccess` `use` of `v` occurs in `b` at index `i`. */ - private predicate variableUse(TrackedVar v, RValue use, BasicBlock b, int i) { + private predicate variableUse(TrackedVar v, VarRead use, BasicBlock b, int i) { v.getAnAccess() = use and b.getNode(i) = use } @@ -381,7 +381,7 @@ private module SsaImpl { * ``` */ private predicate intraInstanceCallEdge(Callable c1, Method m2) { - exists(MethodAccess ma, RefType t1 | + exists(MethodCall ma, RefType t1 | ma.getCaller() = c1 and m2 = viableImpl_v2(ma) and not m2.isStatic() and @@ -652,7 +652,7 @@ private module SsaImpl { * Holds if the SSA definition of `v` at `def` reaches `use` in the same basic block * without crossing another SSA definition of `v`. */ - private predicate ssaDefReachesUseWithinBlock(TrackedVar v, TrackedSsaDef def, RValue use) { + private predicate ssaDefReachesUseWithinBlock(TrackedVar v, TrackedSsaDef def, VarRead use) { exists(BasicBlock b, int rankix, int i | ssaDefReachesRank(v, def, b, rankix) and defUseRank(v, b, rankix, i) and @@ -665,7 +665,7 @@ private module SsaImpl { * SSA definition of `v`. */ cached - predicate ssaDefReachesUse(TrackedVar v, TrackedSsaDef def, RValue use) { + predicate ssaDefReachesUse(TrackedVar v, TrackedSsaDef def, VarRead use) { ssaDefReachesUseWithinBlock(v, def, use) or exists(BasicBlock b | @@ -813,7 +813,7 @@ private module SsaImpl { * any other uses, but possibly through phi nodes and uncertain implicit updates. */ cached - predicate firstUse(TrackedSsaDef def, RValue use) { + predicate firstUse(TrackedSsaDef def, VarRead use) { exists(TrackedVar v, BasicBlock b1, int i1, BasicBlock b2, int i2 | adjacentVarRefs(v, b1, i1, b2, i2) and def.definesAt(v, b1, i1) and @@ -838,7 +838,7 @@ private module SsaImpl { * through any other use or any SSA definition of the variable. */ cached - predicate adjacentUseUseSameVar(RValue use1, RValue use2) { + predicate adjacentUseUseSameVar(VarRead use1, VarRead use2) { exists(TrackedVar v, BasicBlock b1, int i1, BasicBlock b2, int i2 | adjacentVarRefs(v, b1, i1, b2, i2) and variableUse(v, use1, b1, i1) and @@ -853,7 +853,7 @@ private module SsaImpl { * except for phi nodes and uncertain implicit updates. */ cached - predicate adjacentUseUse(RValue use1, RValue use2) { + predicate adjacentUseUse(VarRead use1, VarRead use2) { adjacentUseUseSameVar(use1, use2) or exists(TrackedVar v, TrackedSsaDef def, BasicBlock b1, int i1, BasicBlock b2, int i2 | @@ -938,7 +938,7 @@ class SsaVariable extends TSsaVariable { BasicBlock getBasicBlock() { result = this.getCfgNode().getBasicBlock() } /** Gets an access of this SSA variable. */ - RValue getAUse() { + VarRead getAUse() { ssaDefReachesUse(_, this, result) or this = TSsaUntracked(_, result) } @@ -952,7 +952,7 @@ class SsaVariable extends TSsaVariable { * Subsequent uses can be found by following the steps defined by * `adjacentUseUse`. */ - RValue getAFirstUse() { + VarRead getAFirstUse() { firstUse(this, result) or this = TSsaUntracked(_, result) } diff --git a/java/ql/lib/semmle/code/java/dataflow/StringPrefixes.qll b/java/ql/lib/semmle/code/java/dataflow/StringPrefixes.qll index 9c164f62d8b8..ed10d8aa4bb8 100644 --- a/java/ql/lib/semmle/code/java/dataflow/StringPrefixes.qll +++ b/java/ql/lib/semmle/code/java/dataflow/StringPrefixes.qll @@ -54,7 +54,7 @@ private Expr getAnInterestingPrefix(InterestingPrefix root) { result.(AddExpr).getAnOperand() = getAnInterestingPrefix(root) } -private class StringBuilderAppend extends MethodAccess { +private class StringBuilderAppend extends MethodCall { StringBuilderAppend() { this.getMethod().getDeclaringType() instanceof StringBuildingType and this.getMethod().hasName("append") @@ -68,7 +68,7 @@ private class StringBuilderConstructorOrAppend extends Call { } } -private Expr getQualifier(Expr e) { result = e.(MethodAccess).getQualifier() } +private Expr getQualifier(Expr e) { result = e.(MethodCall).getQualifier() } /** * An extension of `StringBuilderVar` that also accounts for strings appended in StringBuilder/Buffer's constructor diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/BaseSSA.qll b/java/ql/lib/semmle/code/java/dataflow/internal/BaseSSA.qll index f4af8f506d62..f33a6d7195f0 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/BaseSSA.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/BaseSSA.qll @@ -118,7 +118,7 @@ private module SsaImpl { } /** Holds if `VarAccess` `use` of `v` occurs in `b` at index `i`. */ - private predicate variableUse(BaseSsaSourceVariable v, RValue use, BasicBlock b, int i) { + private predicate variableUse(BaseSsaSourceVariable v, VarRead use, BasicBlock b, int i) { v.getAnAccess() = use and b.getNode(i) = use } @@ -243,7 +243,7 @@ private module SsaImpl { * without crossing another SSA definition of `v`. */ private predicate ssaDefReachesUseWithinBlock( - BaseSsaSourceVariable v, TrackedSsaDef def, RValue use + BaseSsaSourceVariable v, TrackedSsaDef def, VarRead use ) { exists(BasicBlock b, int rankix, int i | ssaDefReachesRank(v, def, b, rankix) and @@ -257,7 +257,7 @@ private module SsaImpl { * SSA definition of `v`. */ cached - predicate ssaDefReachesUse(BaseSsaSourceVariable v, TrackedSsaDef def, RValue use) { + predicate ssaDefReachesUse(BaseSsaSourceVariable v, TrackedSsaDef def, VarRead use) { ssaDefReachesUseWithinBlock(v, def, use) or exists(BasicBlock b | @@ -378,7 +378,7 @@ private module SsaImpl { * any other uses, but possibly through phi nodes. */ cached - predicate firstUse(TrackedSsaDef def, RValue use) { + predicate firstUse(TrackedSsaDef def, VarRead use) { exists(BaseSsaSourceVariable v, BasicBlock b1, int i1, BasicBlock b2, int i2 | adjacentVarRefs(v, b1, i1, b2, i2) and def.definesAt(v, b1, i1) and @@ -405,7 +405,7 @@ private module SsaImpl { * through any other use or any SSA definition of the variable. */ cached - predicate baseSsaAdjacentUseUseSameVar(RValue use1, RValue use2) { + predicate baseSsaAdjacentUseUseSameVar(VarRead use1, VarRead use2) { exists(BaseSsaSourceVariable v, BasicBlock b1, int i1, BasicBlock b2, int i2 | adjacentVarRefs(v, b1, i1, b2, i2) and variableUse(v, use1, b1, i1) and @@ -420,7 +420,7 @@ private module SsaImpl { * except for phi nodes. */ cached - predicate baseSsaAdjacentUseUse(RValue use1, RValue use2) { + predicate baseSsaAdjacentUseUse(VarRead use1, VarRead use2) { baseSsaAdjacentUseUseSameVar(use1, use2) or exists( @@ -490,7 +490,7 @@ class BaseSsaVariable extends TBaseSsaVariable { BasicBlock getBasicBlock() { result = this.getCfgNode().getBasicBlock() } /** Gets an access of this SSA variable. */ - RValue getAUse() { ssaDefReachesUse(_, this, result) } + VarRead getAUse() { ssaDefReachesUse(_, this, result) } /** * Gets an access of the SSA source variable underlying this SSA variable @@ -500,7 +500,7 @@ class BaseSsaVariable extends TBaseSsaVariable { * Subsequent uses can be found by following the steps defined by * `baseSsaAdjacentUseUse`. */ - RValue getAFirstUse() { firstUse(this, result) } + VarRead getAFirstUse() { firstUse(this, result) } /** Holds if this SSA variable is live at the end of `b`. */ predicate isLiveAtEndOfBlock(BasicBlock b) { ssaDefReachesEndOfBlock(_, this, b) } diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/ContainerFlow.qll b/java/ql/lib/semmle/code/java/dataflow/internal/ContainerFlow.qll index b53138c74219..70e3258566ce 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/ContainerFlow.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/ContainerFlow.qll @@ -184,13 +184,13 @@ private predicate taintPreservingQualifierToMethod(Method m) { m.(MapMethod).hasName(["elements", "search", "searchEntries", "searchValues"]) } -private predicate qualifierToMethodStep(Expr tracked, MethodAccess sink) { +private predicate qualifierToMethodStep(Expr tracked, MethodCall sink) { taintPreservingQualifierToMethod(sink.getMethod()) and tracked = sink.getQualifier() } private predicate qualifierToArgumentStep(Expr tracked, Expr sink) { - exists(MethodAccess ma, CollectionMethod method | + exists(MethodCall ma, CollectionMethod method | method = ma.getMethod() and ( // java.util.Vector @@ -350,7 +350,7 @@ private predicate taintPreservingArgToArg(Method method, int input, int output) } private predicate argToQualifierStep(Expr tracked, Expr sink) { - exists(Method m, int i, MethodAccess ma | + exists(Method m, int i, MethodCall ma | taintPreservingArgumentToQualifier(m, i) and ma.getMethod() = m and tracked = ma.getArgument(i) and @@ -359,7 +359,7 @@ private predicate argToQualifierStep(Expr tracked, Expr sink) { } /** Access to a method that passes taint from an argument. */ -private predicate argToMethodStep(Expr tracked, MethodAccess sink) { +private predicate argToMethodStep(Expr tracked, MethodCall sink) { exists(Method m | m = sink.getMethod() and ( @@ -383,7 +383,7 @@ private predicate argToMethodStep(Expr tracked, MethodAccess sink) { * between arguments. */ private predicate argToArgStep(Expr tracked, Expr sink) { - exists(MethodAccess ma, Method method, int input, int output | + exists(MethodCall ma, Method method, int input, int output | ma.getMethod() = method and ma.getArgument(input) = tracked and ma.getArgument(output) = sink and diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowDispatch.qll b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowDispatch.qll index e72cc75fc598..f5b437c83729 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowDispatch.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowDispatch.qll @@ -38,7 +38,7 @@ private module DispatchImpl { * might be improved by knowing the call context. This is the case if the * qualifier is the `i`th parameter of the enclosing callable `c`. */ - private predicate mayBenefitFromCallContext(MethodAccess ma, Callable c, int i) { + private predicate mayBenefitFromCallContext(MethodCall ma, Callable c, int i) { exists(Parameter p | 2 <= strictcount(sourceDispatch(ma)) and ma.getQualifier().(VarAccess).getVariable() = p and @@ -58,7 +58,7 @@ private module DispatchImpl { /** * Holds if the call `ctx` might act as a context that improves the set of - * dispatch targets of a `MethodAccess` that occurs in a viable target of + * dispatch targets of a `MethodCall` that occurs in a viable target of * `ctx`. */ pragma[nomagic] @@ -128,7 +128,7 @@ private module DispatchImpl { */ DataFlowCallable viableImplInCallContext(DataFlowCall call, DataFlowCall ctx) { result = viableCallable(call) and - exists(int i, Callable c, Method def, RefType t, boolean exact, MethodAccess ma | + exists(int i, Callable c, Method def, RefType t, boolean exact, MethodCall ma | ma = call.asCall() and mayBenefitFromCallContext(ma, c, i) and c = viableCallable(ctx).asCallable() and diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowNodes.qll b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowNodes.qll index 44061e1cd000..415929f4f72c 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowNodes.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowNodes.qll @@ -84,7 +84,7 @@ private module Cached { import Cached private predicate explicitInstanceArgument(Call call, Expr instarg) { - call instanceof MethodAccess and + call instanceof MethodCall and instarg = call.getQualifier() and not call.getCallee().isStatic() } @@ -463,7 +463,7 @@ module Private { /** A data flow node that represents the output of a call. */ class OutNode extends Node { OutNode() { - this.asExpr() instanceof MethodAccess + this.asExpr() instanceof MethodCall or this.(FlowSummaryNode).isOut(_) } diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowPrivate.qll b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowPrivate.qll index ce7a9ffa2b2d..01ba8cfd26aa 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowPrivate.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowPrivate.qll @@ -114,7 +114,7 @@ private module CaptureInput implements VariableCapture::InputSig { CapturedVariable getVariable() { result = v } } - class VariableRead extends Expr instanceof RValue { + class VariableRead extends Expr instanceof VarRead { CapturedVariable v; VariableRead() { super.getVariable() = v } @@ -246,7 +246,7 @@ predicate readStep(Node node1, ContentSet f, Node node2) { fr = node2.asExpr() ) or - exists(Record r, Method getter, Field recf, MethodAccess get | + exists(Record r, Method getter, Field recf, MethodCall get | getter.getDeclaringType() = r and recf.getDeclaringType() = r and getter.getNumberOfParameters() = 0 and diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowUtil.qll b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowUtil.qll index 1e8a3bbcb882..af86063caddf 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowUtil.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowUtil.qll @@ -169,7 +169,7 @@ predicate localMustFlowStep(Node node1, Node node2) { import Cached private predicate capturedVariableRead(Node n) { - n.asExpr().(RValue).getVariable() instanceof CapturedVariable + n.asExpr().(VarRead).getVariable() instanceof CapturedVariable } /** @@ -225,7 +225,7 @@ private predicate simpleLocalFlowStep0(Node node1, Node node2) { or simpleAstFlowStep(node1.asExpr(), node2.asExpr()) or - exists(MethodAccess ma, ValuePreservingMethod m, int argNo | + exists(MethodCall ma, ValuePreservingMethod m, int argNo | ma.getCallee().getSourceDeclaration() = m and m.returnsValue(argNo) | node2.asExpr() = ma and @@ -379,7 +379,7 @@ signature predicate guardChecksSig(Guard g, Expr e, boolean branch); module BarrierGuard { /** Gets a node that is safely guarded by the given guard check. */ Node getABarrierNode() { - exists(Guard g, SsaVariable v, boolean branch, RValue use | + exists(Guard g, SsaVariable v, boolean branch, VarRead use | guardChecks(g, v.getAUse(), branch) and use = v.getAUse() and g.controls(use.getBasicBlock(), branch) and diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/FlowSummaryImplSpecific.qll b/java/ql/lib/semmle/code/java/dataflow/internal/FlowSummaryImplSpecific.qll index fb260d5cdd69..996e791d4421 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/FlowSummaryImplSpecific.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/FlowSummaryImplSpecific.qll @@ -333,7 +333,7 @@ predicate interpretInputSpecific(string c, InterpretNode mid, InterpretNode n) { exists(FieldWrite fw | c = "" and fw.getField() = mid.asElement() and - n.asNode().asExpr() = fw.getRhs() + n.asNode().asExpr() = fw.getASource() ) } diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/ModelExclusions.qll b/java/ql/lib/semmle/code/java/dataflow/internal/ModelExclusions.qll index b797cf5d9391..b8c86badd4fa 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/ModelExclusions.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/ModelExclusions.qll @@ -53,10 +53,16 @@ private predicate isJdkInternal(CompilationUnit cu) { cu.getPackage().getName() = "" } +/** Holds if the given compilation unit's package is internal. */ +private predicate isInternal(CompilationUnit cu) { + isJdkInternal(cu) or + cu.getPackage().getName().matches("%internal%") +} + /** Holds if the given callable is not worth modeling. */ predicate isUninterestingForModels(Callable c) { isInTestFile(c.getCompilationUnit().getFile()) or - isJdkInternal(c.getCompilationUnit()) or + isInternal(c.getCompilationUnit()) or c instanceof MainMethod or c instanceof StaticInitializer or exists(FunctionalExpr funcExpr | c = funcExpr.asMethod()) or diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/TaintTrackingUtil.qll b/java/ql/lib/semmle/code/java/dataflow/internal/TaintTrackingUtil.qll index d08cb8df57ee..00415e93d534 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/TaintTrackingUtil.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/TaintTrackingUtil.qll @@ -290,7 +290,7 @@ private int argToParam(Call call, int argIdx) { /** Access to a method that passes taint from qualifier to argument. */ private predicate qualifierToArgumentStep(Expr tracked, Expr sink) { - exists(MethodAccess ma, int arg | + exists(MethodCall ma, int arg | ma.getMethod().(TaintPreservingCallable).transfersTaint(-1, argToParam(ma, arg)) and tracked = ma.getQualifier() and sink = ma.getArgument(arg) @@ -298,7 +298,7 @@ private predicate qualifierToArgumentStep(Expr tracked, Expr sink) { } /** Access to a method that passes taint from the qualifier. */ -private predicate qualifierToMethodStep(Expr tracked, MethodAccess sink) { +private predicate qualifierToMethodStep(Expr tracked, MethodCall sink) { taintPreservingQualifierToMethod(sink.getMethod()) and tracked = sink.getQualifier() } @@ -331,7 +331,7 @@ private predicate taintPreservingQualifierToMethod(Method m) { } /** Access to a method that passes taint from an argument. */ -private predicate argToMethodStep(Expr tracked, MethodAccess sink) { +private predicate argToMethodStep(Expr tracked, MethodCall sink) { exists(Method m, int i | m = sink.getMethod() and taintPreservingArgumentToMethod(m, argToParam(sink, i)) and @@ -375,7 +375,7 @@ private predicate taintPreservingArgumentToMethod(Method method, int arg) { * between arguments. */ private predicate argToArgStep(Expr tracked, Expr sink) { - exists(MethodAccess ma, Method method, int input, int output | + exists(MethodCall ma, Method method, int input, int output | method.(TaintPreservingCallable).transfersTaint(argToParam(ma, input), argToParam(ma, output)) and ma.getMethod() = method and ma.getArgument(input) = tracked and @@ -388,7 +388,7 @@ private predicate argToArgStep(Expr tracked, Expr sink) { * from the argument to the qualifier and `sink` is the qualifier. */ private predicate argToQualifierStep(Expr tracked, Expr sink) { - exists(Method m, int i, MethodAccess ma | + exists(Method m, int i, MethodCall ma | taintPreservingArgumentToQualifier(m, argToParam(ma, i)) and ma.getMethod() = m and tracked = ma.getArgument(i) and @@ -412,7 +412,7 @@ private predicate comparisonStep(Expr tracked, Expr sink) { e.hasOperands(tracked, other) ) or - exists(MethodAccess m | m.getMethod() instanceof EqualsMethod | + exists(MethodCall m | m.getMethod() instanceof EqualsMethod | m = sink and ( m.getQualifier() = tracked and m.getArgument(0) = other @@ -429,13 +429,13 @@ private predicate comparisonStep(Expr tracked, Expr sink) { private predicate serializationStep(Expr tracked, Expr sink) { exists(ObjectOutputStreamVar v, VariableAssign def | def = v.getADef() and - exists(MethodAccess ma, RValue use | + exists(MethodCall ma, VarRead use | ma.getArgument(0) = tracked and - ma = v.getAWriteObjectMethodAccess() and + ma = v.getAWriteObjectMethodCall() and use = ma.getQualifier() and defUsePair(def, use) ) and - exists(RValue outputstream, ClassInstanceExpr cie | + exists(VarRead outputstream, ClassInstanceExpr cie | cie = def.getSource() and outputstream = cie.getArgument(0) and adjacentUseUse(outputstream, sink) @@ -460,23 +460,27 @@ class ObjectOutputStreamVar extends LocalVariableDecl { result.getDestVar() = this } - MethodAccess getAWriteObjectMethodAccess() { + /** Gets a call to `writeObject` called against this variable. */ + MethodCall getAWriteObjectMethodCall() { result.getQualifier() = this.getAnAccess() and result.getMethod().hasName("writeObject") } + + /** DEPRECATED: Alias for `getAWriteObjectMethodCall`. */ + deprecated MethodCall getAWriteObjectMethodAccess() { result = this.getAWriteObjectMethodCall() } } /** Flow through string formatting. */ private predicate formatStep(Expr tracked, Expr sink) { exists(FormatterVar v, VariableAssign def | def = v.getADef() and - exists(MethodAccess ma, RValue use | + exists(MethodCall ma, VarRead use | ma.getAnArgument() = tracked and - ma = v.getAFormatMethodAccess() and + ma = v.getAFormatMethodCall() and use = ma.getQualifier() and defUsePair(def, use) ) and - exists(RValue output, ClassInstanceExpr cie | + exists(VarRead output, ClassInstanceExpr cie | cie = def.getSource() and output = cie.getArgument(0) and adjacentUseUse(output, sink) and @@ -505,7 +509,7 @@ private class FormatterVar extends LocalVariableDecl { result.getDestVar() = this } - MethodAccess getAFormatMethodAccess() { + MethodCall getAFormatMethodCall() { result.getQualifier() = this.getAnAccess() and result.getMethod().hasName("format") } @@ -555,7 +559,7 @@ module StringBuilderVarModule { /** * Gets a call that adds something to this string builder, from the argument at the given index. */ - MethodAccess getAnInput(int arg) { + MethodCall getAnInput(int arg) { result.getQualifier() = this.getAChainedReference() and ( result.getMethod().getName() = "append" and arg = 0 @@ -569,19 +573,19 @@ module StringBuilderVarModule { /** * Gets a call that appends something to this string builder. */ - MethodAccess getAnAppend() { + MethodCall getAnAppend() { result.getQualifier() = this.getAChainedReference() and result.getMethod().getName() = "append" } - MethodAccess getNextAppend(MethodAccess append) { + MethodCall getNextAppend(MethodCall append) { result = this.getAnAppend() and append = this.getAnAppend() and ( result.getQualifier() = append or - not exists(MethodAccess chainAccess | chainAccess.getQualifier() = append) and - exists(RValue sbva1, RValue sbva2 | + not exists(MethodCall chainAccess | chainAccess.getQualifier() = append) and + exists(VarRead sbva1, VarRead sbva2 | adjacentUseUse(sbva1, sbva2) and append.getQualifier() = this.getAChainedReference(sbva1) and result.getQualifier() = sbva2 @@ -592,7 +596,7 @@ module StringBuilderVarModule { /** * Gets a call that converts this string builder to a string. */ - MethodAccess getToStringCall() { + MethodCall getToStringCall() { result.getQualifier() = this.getAChainedReference() and result.getMethod().getName() = "toString" } @@ -612,7 +616,7 @@ module StringBuilderVarModule { } } -private MethodAccess callReturningSameType(Expr ref) { +private MethodCall callReturningSameType(Expr ref) { ref = result.getQualifier() and result.getMethod().getReturnType() = ref.getType() } diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/rangeanalysis/BoundSpecific.qll b/java/ql/lib/semmle/code/java/dataflow/internal/rangeanalysis/BoundSpecific.qll index f7fca3a184f6..0af549f1f7ee 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/rangeanalysis/BoundSpecific.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/rangeanalysis/BoundSpecific.qll @@ -10,6 +10,8 @@ class SsaVariable = Ssa::SsaVariable; class Expr = J::Expr; +class Location = J::Location; + class IntegralType = J::IntegralType; class ConstantIntegerExpr = RU::ConstantIntegerExpr; diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/rangeanalysis/SignAnalysisSpecific.qll b/java/ql/lib/semmle/code/java/dataflow/internal/rangeanalysis/SignAnalysisSpecific.qll index 59f7f4580a88..253506347f30 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/rangeanalysis/SignAnalysisSpecific.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/rangeanalysis/SignAnalysisSpecific.qll @@ -200,11 +200,11 @@ private module Impl { * `Collection`). */ predicate containerSizeAccess(Expr e) { - e.(MethodAccess).getMethod() instanceof StringLengthMethod + e.(MethodCall).getMethod() instanceof StringLengthMethod or - e.(MethodAccess).getMethod() instanceof CollectionSizeMethod + e.(MethodCall).getMethod() instanceof CollectionSizeMethod or - e.(MethodAccess).getMethod() instanceof MapSizeMethod + e.(MethodCall).getMethod() instanceof MapSizeMethod } /** Holds if `e` is by definition strictly positive. */ @@ -218,7 +218,7 @@ private module Impl { // types handled in `specificSubExprSign`. e instanceof ArrayAccess and e.getType() instanceof NumericOrCharType or - e instanceof MethodAccess and e.getType() instanceof NumericOrCharType + e instanceof MethodCall and e.getType() instanceof NumericOrCharType or e instanceof ClassInstanceExpr and e.getType() instanceof NumericOrCharType } @@ -267,7 +267,7 @@ private module Impl { /** Holds if `f` can have any sign. */ predicate fieldWithUnknownSign(Field f) { - exists(ReflectiveFieldAccess rfa | rfa.inferAccessedField() = f) + exists(ReflectiveGetFieldCall rfa | rfa.inferAccessedField() = f) } /** Holds if `f` is accessed in an increment operation. */ diff --git a/java/ql/lib/semmle/code/java/deadcode/DeadCode.qll b/java/ql/lib/semmle/code/java/deadcode/DeadCode.qll index 709911046568..cab159b18043 100644 --- a/java/ql/lib/semmle/code/java/deadcode/DeadCode.qll +++ b/java/ql/lib/semmle/code/java/deadcode/DeadCode.qll @@ -173,9 +173,9 @@ class LiveClass extends SourceClassOrInterface { exists(NestedType r | r.getEnclosingType() = this | r instanceof LiveClass) or // An annotation on the class is reflectively accessed. - exists(ReflectiveAnnotationAccess reflectiveAnnotationAccess | - this = reflectiveAnnotationAccess.getInferredClassType() and - isLive(reflectiveAnnotationAccess.getEnclosingCallable()) + exists(ReflectiveGetAnnotationCall reflectiveAnnotationCall | + this = reflectiveAnnotationCall.getInferredClassType() and + isLive(reflectiveAnnotationCall.getEnclosingCallable()) ) or this instanceof AnonymousClass diff --git a/java/ql/lib/semmle/code/java/deadcode/DeadEnumConstant.qll b/java/ql/lib/semmle/code/java/deadcode/DeadEnumConstant.qll index 506da3803f77..e87671dba714 100644 --- a/java/ql/lib/semmle/code/java/deadcode/DeadEnumConstant.qll +++ b/java/ql/lib/semmle/code/java/deadcode/DeadEnumConstant.qll @@ -19,7 +19,7 @@ VarAccess valueAccess(EnumConstant e) { ( exists(Call c | c.getAnArgument() = valueFlow+(result) or - c.(MethodAccess).getQualifier() = valueFlow+(result) + c.(MethodCall).getQualifier() = valueFlow+(result) ) or exists(Assignment a | a.getSource() = valueFlow+(result)) @@ -47,14 +47,14 @@ predicate exception(EnumConstant e) { ) or // A method iterates over the values of an enum. - exists(MethodAccess values | values.getMethod().getDeclaringType() = t | + exists(MethodCall values | values.getMethod().getDeclaringType() = t | values.getParent() instanceof EnhancedForStmt or - values.getParent().(MethodAccess).getMethod().hasName("findThisIn") + values.getParent().(MethodCall).getMethod().hasName("findThisIn") ) or // The `valueOf` method is called, meaning that depending on the string any constant // could be retrieved. - exists(MethodAccess valueOf | valueOf.getMethod().getDeclaringType() = t | + exists(MethodCall valueOf | valueOf.getMethod().getDeclaringType() = t | valueOf.getMethod().hasName("valueOf") ) or diff --git a/java/ql/lib/semmle/code/java/deadcode/DeadField.qll b/java/ql/lib/semmle/code/java/deadcode/DeadField.qll index e5bbb7e9ee32..231a81758048 100644 --- a/java/ql/lib/semmle/code/java/deadcode/DeadField.qll +++ b/java/ql/lib/semmle/code/java/deadcode/DeadField.qll @@ -130,7 +130,7 @@ class JUnitAnnotatedField extends ReflectivelyReadField { */ class ClassReflectivelyReadField extends ReflectivelyReadField { ClassReflectivelyReadField() { - exists(ReflectiveFieldAccess fieldAccess | this = fieldAccess.inferAccessedField()) + exists(ReflectiveGetFieldCall fieldAccess | this = fieldAccess.inferAccessedField()) } } diff --git a/java/ql/lib/semmle/code/java/deadcode/EntryPoints.qll b/java/ql/lib/semmle/code/java/deadcode/EntryPoints.qll index 8ee23098eefa..e2323e738eb5 100644 --- a/java/ql/lib/semmle/code/java/deadcode/EntryPoints.qll +++ b/java/ql/lib/semmle/code/java/deadcode/EntryPoints.qll @@ -142,7 +142,7 @@ deprecated class JAXAnnotationReflectivelyConstructedClass = class DeserializedClass extends ReflectivelyConstructedClass { DeserializedClass() { exists(CastingExpr cast, ReadObjectMethod readObject | - cast.getExpr().(MethodAccess).getMethod() = readObject + cast.getExpr().(MethodCall).getMethod() = readObject | hasDescendant(cast.getType(), this) ) @@ -164,7 +164,7 @@ class NewInstanceCall extends EntryPoint, NewInstance { /** * A call to either `Class.getMethod(...)` or `Class.getDeclaredMethod(...)`. */ -class ReflectiveMethodAccessEntryPoint extends EntryPoint, ReflectiveMethodAccess { +class ReflectiveGetMethodCallEntryPoint extends EntryPoint, ReflectiveGetMethodCall { override Method getALiveCallable() { result = this.inferAccessedMethod() and // The `getMethod(...)` call must be used in a live context. @@ -172,6 +172,9 @@ class ReflectiveMethodAccessEntryPoint extends EntryPoint, ReflectiveMethodAcces } } +/** DEPRECATED: Alias for `ReflectiveGetMethodCallEntryPoint`. */ +deprecated class ReflectiveMethodAccessEntryPoint = ReflectiveGetMethodCallEntryPoint; + /** * Classes that are entry points recognised by annotations. */ diff --git a/java/ql/lib/semmle/code/java/dispatch/DispatchFlow.qll b/java/ql/lib/semmle/code/java/dispatch/DispatchFlow.qll index e3eb298dd139..82bda033bc6d 100644 --- a/java/ql/lib/semmle/code/java/dispatch/DispatchFlow.qll +++ b/java/ql/lib/semmle/code/java/dispatch/DispatchFlow.qll @@ -19,7 +19,7 @@ private import codeql.typetracking.TypeTracking /** * Gets a viable dispatch target for `ma`. This is the input dispatch relation. */ -private Method viableImpl_inp(MethodAccess ma) { result = viableImpl_v2(ma) } +private Method viableImpl_inp(MethodCall ma) { result = viableImpl_v2(ma) } private Callable dispatchCand(Call c) { c instanceof ConstructorCall and result = c.getCallee().getSourceDeclaration() @@ -99,7 +99,7 @@ private predicate trackedMethodOnType(Method m, SrcRefType t) { * by the type constructed by `cie`. Thus the dispatch from `ma` to `m` will * only be included if `cie` flows to the qualifier of `ma`. */ -private predicate dispatchOrigin(ClassInstanceExpr cie, MethodAccess ma, Method m) { +private predicate dispatchOrigin(ClassInstanceExpr cie, MethodCall ma, Method m) { m = viableImpl_inp(ma) and not m = ma.getMethod().getSourceDeclaration() and trackedMethodOnType(m, cie.getConstructedType().getSourceDeclaration()) @@ -133,7 +133,7 @@ private module TypeTrackingSteps { class LocalSourceNode extends RelevantNode { LocalSourceNode() { this.asExpr() instanceof Call or - this.asExpr() instanceof RValue or + this.asExpr() instanceof VarRead or this instanceof DataFlow::ParameterNode or this instanceof DataFlow::ImplicitVarargsArray or this.asExpr() instanceof ArrayInit or @@ -197,10 +197,10 @@ private module TypeTrackingSteps { enum.getAnEnumConstant().getAnAssignedValue() = n1.asExpr() and getValue.getDeclaringType() = enum and getValue.hasName("valueOf") and - n2.asExpr().(MethodAccess).getMethod() = getValue + n2.asExpr().(MethodCall).getMethod() = getValue ) or - exists(Variable v, MethodAccess put, MethodAccess get | + exists(Variable v, MethodCall put, MethodCall get | put.getArgument(1) = n1.asExpr() and put.getMethod().(MapMethod).hasName("put") and put.getQualifier() = v.getAnAccess() and @@ -209,12 +209,12 @@ private module TypeTrackingSteps { n2.asExpr() = get ) or - exists(Variable v, MethodAccess add | + exists(Variable v, MethodCall add | add.getAnArgument() = n1.asExpr() and add.getMethod().(CollectionMethod).hasName("add") and add.getQualifier() = v.getAnAccess() | - exists(MethodAccess get | + exists(MethodCall get | get.getQualifier() = v.getAnAccess() and get.getMethod().(CollectionMethod).hasName("get") and n2.asExpr() = get @@ -236,7 +236,7 @@ private module TypeTrackingSteps { enum.getAnEnumConstant().getAnAssignedValue() = n1.asExpr() and getValue.getDeclaringType() = enum and getValue.hasName("values") and - n2.asExpr().(MethodAccess).getMethod() = getValue and + n2.asExpr().(MethodCall).getMethod() = getValue and f = ContentArray() ) or @@ -253,7 +253,7 @@ private module TypeTrackingSteps { exists(AssignExpr a, Variable v | a.getSource() = n1.asExpr() and a.getDest().(ArrayAccess).getArray() = v.getAnAccess() and - n2.asExpr() = v.getAnAccess().(RValue) and + n2.asExpr() = v.getAnAccess().(VarRead) and f = ContentArray() ) } @@ -300,10 +300,10 @@ private module TypeTrackingSteps { private predicate lambdaSource(RelevantNode n) { dispatchOrigin(n.asExpr(), _, _) } private predicate lambdaSink(RelevantNode n) { - exists(MethodAccess ma | dispatchOrigin(_, ma, _) | n = DataFlow::getInstanceArgument(ma)) + exists(MethodCall ma | dispatchOrigin(_, ma, _) | n = DataFlow::getInstanceArgument(ma)) } -private signature Method methodDispatchSig(MethodAccess ma); +private signature Method methodDispatchSig(MethodCall ma); private module TrackLambda { private Callable dispatch(Call c) { @@ -352,7 +352,7 @@ private module TrackLambda { private predicate edgePlus(PathNode n1, PathNode n2) = fastTC(edges/2)(n1, n2) - private predicate pairCand(PathNode p1, PathNode p2, Method m, MethodAccess ma) { + private predicate pairCand(PathNode p1, PathNode p2, Method m, MethodCall ma) { exists(ClassInstanceExpr cie | dispatchOrigin(cie, ma, m) and p1.getNode() = DataFlow::exprNode(cie) and @@ -367,7 +367,7 @@ private module TrackLambda { * declares or inherits the tracked method `result` to the qualifier of `ma` such * that `ma` may dispatch to `result`. */ - Method lambdaDispatch(MethodAccess ma) { + Method lambdaDispatch(MethodCall ma) { exists(PathNode p1, PathNode p2 | (p1 = p2 or edgePlus(p1, p2)) and pairCand(p1, p2, result, ma) @@ -375,30 +375,30 @@ private module TrackLambda { } } -private Method noDisp(MethodAccess ma) { none() } +private Method noDisp(MethodCall ma) { none() } pragma[nomagic] -private Method d1(MethodAccess ma) { result = TrackLambda::lambdaDispatch(ma) } +private Method d1(MethodCall ma) { result = TrackLambda::lambdaDispatch(ma) } pragma[nomagic] -private Method d2(MethodAccess ma) { result = TrackLambda::lambdaDispatch(ma) } +private Method d2(MethodCall ma) { result = TrackLambda::lambdaDispatch(ma) } pragma[nomagic] -private Method d3(MethodAccess ma) { result = TrackLambda::lambdaDispatch(ma) } +private Method d3(MethodCall ma) { result = TrackLambda::lambdaDispatch(ma) } pragma[nomagic] -private Method d4(MethodAccess ma) { result = TrackLambda::lambdaDispatch(ma) } +private Method d4(MethodCall ma) { result = TrackLambda::lambdaDispatch(ma) } pragma[nomagic] -private Method d5(MethodAccess ma) { result = TrackLambda::lambdaDispatch(ma) } +private Method d5(MethodCall ma) { result = TrackLambda::lambdaDispatch(ma) } pragma[nomagic] -private Method d6(MethodAccess ma) { result = TrackLambda::lambdaDispatch(ma) } +private Method d6(MethodCall ma) { result = TrackLambda::lambdaDispatch(ma) } /** * Gets a viable dispatch target for `ma`. This is the output dispatch relation. */ -Method viableImpl_out(MethodAccess ma) { +Method viableImpl_out(MethodCall ma) { result = viableImpl_inp(ma) and (result = d6(ma) or not dispatchOrigin(_, ma, result)) } diff --git a/java/ql/lib/semmle/code/java/dispatch/ObjFlow.qll b/java/ql/lib/semmle/code/java/dispatch/ObjFlow.qll index 14ea6e81718e..293ba894fdfb 100644 --- a/java/ql/lib/semmle/code/java/dispatch/ObjFlow.qll +++ b/java/ql/lib/semmle/code/java/dispatch/ObjFlow.qll @@ -20,7 +20,7 @@ private import semmle.code.java.dispatch.internal.Unification /** * Gets a viable dispatch target for `ma`. This is the input dispatch relation. */ -private Method viableImpl_inp(MethodAccess ma) { result = viableImpl_v3(ma) } +private Method viableImpl_inp(MethodCall ma) { result = viableImpl_v3(ma) } private Callable dispatchCand(Call c) { c instanceof ConstructorCall and result = c.getCallee().getSourceDeclaration() @@ -118,7 +118,7 @@ private predicate step(Node n1, Node n2) { exists(AssignExpr a, Field v | a.getSource() = n1.asExpr() and a.getDest().(ArrayAccess).getArray() = v.getAnAccess() and - n2.asExpr() = v.getAnAccess().(RValue) + n2.asExpr() = v.getAnAccess().(VarRead) ) or exists(AssignExpr a | @@ -193,7 +193,7 @@ private predicate source(RefType t, ObjNode n) { * Holds if `n` is the qualifier of an `Object.toString()` call. */ private predicate sink(ObjNode n) { - exists(MethodAccess toString | + exists(MethodCall toString | toString.getQualifier() = n.asExpr() and toString.getMethod() instanceof ToStringMethod ) and @@ -231,7 +231,7 @@ private predicate objType(ObjNode n, RefType t) { ) } -private VirtualMethodAccess objectToString(ObjNode n) { +private VirtualMethodCall objectToString(ObjNode n) { result.getQualifier() = n.asExpr() and sink(n) } @@ -239,16 +239,16 @@ private VirtualMethodAccess objectToString(ObjNode n) { * Holds if `ma` is an `Object.toString()` call taking possibly improved type * bounds into account. */ -predicate objectToStringCall(VirtualMethodAccess ma) { ma = objectToString(_) } +predicate objectToStringCall(VirtualMethodCall ma) { ma = objectToString(_) } /** * Holds if the qualifier of the `Object.toString()` call `ma` might have type `t`. */ -private predicate objectToStringQualType(MethodAccess ma, RefType t) { +private predicate objectToStringQualType(MethodCall ma, RefType t) { exists(ObjNode n | ma = objectToString(n) and objType(n, t)) } -private Method viableImplObjectToString(MethodAccess ma) { +private Method viableImplObjectToString(MethodCall ma) { exists(Method def, RefType t | objectToStringQualType(ma, t) and def = ma.getMethod() and @@ -265,7 +265,7 @@ private Method viableImplObjectToString(MethodAccess ma) { * The set of dispatch targets for `Object.toString()` calls are reduced based * on possible data flow from objects of more specific types to the qualifier. */ -Method viableImpl_out(MethodAccess ma) { +Method viableImpl_out(MethodCall ma) { result = viableImpl_inp(ma) and ( result = viableImplObjectToString(ma) or diff --git a/java/ql/lib/semmle/code/java/dispatch/VirtualDispatch.qll b/java/ql/lib/semmle/code/java/dispatch/VirtualDispatch.qll index 64f26685b681..3fe6f9ad303d 100644 --- a/java/ql/lib/semmle/code/java/dispatch/VirtualDispatch.qll +++ b/java/ql/lib/semmle/code/java/dispatch/VirtualDispatch.qll @@ -15,7 +15,7 @@ private import semmle.code.java.dispatch.internal.Unification * A conservative analysis that returns a single method - if we can establish * one - that will be the target of the virtual dispatch. */ -Method exactVirtualMethod(MethodAccess c) { +Method exactVirtualMethod(MethodCall c) { // If there are multiple potential implementations, return nothing. implCount(c, 1) and result = viableImpl(c) @@ -31,7 +31,7 @@ Callable exactCallable(Call c) { c instanceof ConstructorCall and result = c.getCallee() } -private predicate implCount(MethodAccess m, int c) { strictcount(viableImpl(m)) = c } +private predicate implCount(MethodCall m, int c) { strictcount(viableImpl(m)) = c } /** Gets a viable implementation of the target of the given `Call`. */ Callable viableCallable(Call c) { @@ -44,15 +44,14 @@ Callable viableCallable(Call c) { class VirtCalledSrcMethod extends SrcMethod { pragma[nomagic] VirtCalledSrcMethod() { - exists(VirtualMethodAccess ma | ma.getMethod().getSourceDeclaration() = this) + exists(VirtualMethodCall ma | ma.getMethod().getSourceDeclaration() = this) } } -cached private module Dispatch { /** Gets a viable implementation of the method called in the given method access. */ cached - Method viableImpl(MethodAccess ma) { result = ObjFlow::viableImpl_out(ma) } + Method viableImpl(MethodCall ma) { result = ObjFlow::viableImpl_out(ma) } /** * Holds if `m` is a viable implementation of the method called in `ma` for @@ -60,7 +59,7 @@ private module Dispatch { * the dispatch type is likely to yield implausible dispatch targets. */ cached - predicate lowConfidenceDispatchTarget(MethodAccess ma, Method m) { + predicate lowConfidenceDispatchTarget(MethodCall ma, Method m) { m = viableImpl(ma) and lowConfidenceDispatch(ma) } @@ -70,13 +69,13 @@ private module Dispatch { * Gets a viable implementation of the method called in the given method access. */ cached - Method viableImpl_v3(MethodAccess ma) { result = DispatchFlow::viableImpl_out(ma) } + Method viableImpl_v3(MethodCall ma) { result = DispatchFlow::viableImpl_out(ma) } /** * Holds if the best type bounds for the qualifier of `ma` are likely to * contain implausible dispatch targets. */ - private predicate lowConfidenceDispatch(VirtualMethodAccess ma) { + private predicate lowConfidenceDispatch(VirtualMethodCall ma) { exists(RefType t | hasQualifierType(ma, t, false) | lowConfidenceDispatchType(t.getSourceDeclaration()) ) and @@ -121,7 +120,7 @@ private module Dispatch { * Gets a viable implementation of the method called in the given method access. */ cached - Method viableImpl_v2(MethodAccess ma) { + Method viableImpl_v2(MethodCall ma) { result = viableImpl_v2_cand(pragma[only_bind_into](ma)) and exists(Method def, RefType t, boolean exact | qualUnionType(pragma[only_bind_into](ma), pragma[only_bind_into](t), @@ -141,7 +140,7 @@ private module Dispatch { not qualUnionType(ma, _, _) } - private predicate qualUnionType(VirtualMethodAccess ma, RefType t, boolean exact) { + private predicate qualUnionType(VirtualMethodCall ma, RefType t, boolean exact) { exprUnionTypeFlow(ma.getQualifier(), t, exact) } @@ -150,7 +149,7 @@ private module Dispatch { private module Unification_v2 = MkUnification; - private Method viableImpl_v2_cand(MethodAccess ma) { + private Method viableImpl_v2_cand(MethodCall ma) { result = viableImpl_v1(ma) and ( exists(Method def, RefType t, boolean exact | @@ -170,7 +169,7 @@ private module Dispatch { ) } - private predicate qualType(VirtualMethodAccess ma, RefType t, boolean exact) { + private predicate qualType(VirtualMethodCall ma, RefType t, boolean exact) { exprTypeFlow(ma.getQualifier(), t, exact) } @@ -185,7 +184,7 @@ private module Dispatch { * Gets a viable implementation of the method called in the given method access. */ cached - Method viableImpl_v1(MethodAccess source) { + Method viableImpl_v1(MethodCall source) { result = viableImpl_v1_cand(source) and not impossibleDispatchTarget(source, result) } @@ -193,7 +192,7 @@ private module Dispatch { /** * Holds if `source` cannot dispatch to `tgt` due to a negative `instanceof` guard. */ - private predicate impossibleDispatchTarget(MethodAccess source, Method tgt) { + private predicate impossibleDispatchTarget(MethodCall source, Method tgt) { tgt = viableImpl_v1_cand(source) and exists(InstanceOfExpr ioe, BaseSsaVariable v, Expr q, RefType t | source.getQualifier() = q and @@ -208,9 +207,9 @@ private module Dispatch { /** * Gets a viable implementation of the method called in the given method access. */ - private Method viableImpl_v1_cand(MethodAccess source) { + private Method viableImpl_v1_cand(MethodCall source) { not result.isAbstract() and - if source instanceof VirtualMethodAccess + if source instanceof VirtualMethodCall then exists(VirtCalledSrcMethod def, RefType t, boolean exact | source.getMethod().getSourceDeclaration() = def and @@ -242,7 +241,7 @@ private module Dispatch { not e instanceof FunctionalExpr and result = e.getType() } - private predicate hasQualifierType(VirtualMethodAccess ma, RefType t, boolean exact) { + private predicate hasQualifierType(VirtualMethodCall ma, RefType t, boolean exact) { exists(Expr src | src = ma.getQualifier() | // If we have a qualifier, then we take its type. exists(RefType srctype | srctype = getPreciseType(src) | @@ -264,9 +263,9 @@ private module Dispatch { not exists(ma.getQualifier()) and exact = false and ( - ma.isOwnMethodAccess() and t = ma.getEnclosingCallable().getDeclaringType() + ma.isOwnMethodCall() and t = ma.getEnclosingCallable().getDeclaringType() or - ma.isEnclosingMethodAccess(t) + ma.isEnclosingMethodCall(t) ) } diff --git a/java/ql/lib/semmle/code/java/dispatch/WrappedInvocation.qll b/java/ql/lib/semmle/code/java/dispatch/WrappedInvocation.qll index 77f3ff11291b..f41c79f92065 100644 --- a/java/ql/lib/semmle/code/java/dispatch/WrappedInvocation.qll +++ b/java/ql/lib/semmle/code/java/dispatch/WrappedInvocation.qll @@ -16,7 +16,7 @@ private predicate runner(Method m, int n, Method runmethod) { ( m.isNative() or - exists(Parameter p, MethodAccess ma, int j | + exists(Parameter p, MethodCall ma, int j | p = m.getParameter(n) and ma.getEnclosingCallable() = m and runner(pragma[only_bind_into](ma.getMethod().getSourceDeclaration()), @@ -31,7 +31,7 @@ private predicate runner(Method m, int n, Method runmethod) { * through a functional interface. The argument is traced backwards through * casts and variable assignments. */ -private Expr getRunnerArgument(MethodAccess ma, Method runmethod) { +private Expr getRunnerArgument(MethodCall ma, Method runmethod) { exists(Method runner, int param | runner(runner, param, runmethod) and viableImpl_v2(ma) = runner and @@ -50,7 +50,7 @@ private Expr getRunnerArgument(MethodAccess ma, Method runmethod) { * Gets a method that can be invoked through a functional interface as an * argument to `ma`. */ -Method getRunnerTarget(MethodAccess ma) { +Method getRunnerTarget(MethodCall ma) { exists(Expr action, Method runmethod | action = getRunnerArgument(ma, runmethod) | action.(FunctionalExpr).asMethod().getSourceDeclaration() = result or diff --git a/java/ql/lib/semmle/code/java/environment/SystemProperty.qll b/java/ql/lib/semmle/code/java/environment/SystemProperty.qll index 6a3ffde76ebe..63ded626c115 100644 --- a/java/ql/lib/semmle/code/java/environment/SystemProperty.qll +++ b/java/ql/lib/semmle/code/java/environment/SystemProperty.qll @@ -23,8 +23,8 @@ Expr getSystemProperty(string propertyName) { result = getSystemPropertyFromSpringProperties(propertyName) } -private MethodAccess getSystemPropertyFromSystem(string propertyName) { - result.(MethodAccessSystemGetProperty).hasCompileTimeConstantGetPropertyName(propertyName) +private MethodCall getSystemPropertyFromSystem(string propertyName) { + result.(MethodCallSystemGetProperty).hasCompileTimeConstantGetPropertyName(propertyName) or result.getMethod().hasName("lineSeparator") and propertyName = "line.separator" } @@ -34,7 +34,7 @@ private MethodAccess getSystemPropertyFromSystem(string propertyName) { * - `System.getProperties().getProperty(...)` * - `System.getProperties().get(...)` */ -private MethodAccess getSystemPropertyFromSystemGetProperties(string propertyName) { +private MethodCall getSystemPropertyFromSystemGetProperties(string propertyName) { exists(Method getMethod | getMethod instanceof PropertiesGetMethod or @@ -42,7 +42,7 @@ private MethodAccess getSystemPropertyFromSystemGetProperties(string propertyNam result.getMethod() = getMethod ) and result.getArgument(0).(CompileTimeConstantExpr).getStringValue() = propertyName and - localExprFlowPlusInitializers(any(MethodAccess m | + localExprFlowPlusInitializers(any(MethodCall m | m.getMethod().getDeclaringType() instanceof TypeSystem and m.getMethod().hasName("getProperties") ), result.getQualifier()) @@ -156,7 +156,7 @@ private FieldAccess getSystemPropertyFromApacheSystemUtils(string propertyName) ) } -private MethodAccess getSystemPropertyFromApacheFileUtils(string propertyName) { +private MethodCall getSystemPropertyFromApacheFileUtils(string propertyName) { exists(Method m | result.getMethod() = m and m.getDeclaringType().hasQualifiedName("org.apache.commons.io", "FileUtils") @@ -167,7 +167,7 @@ private MethodAccess getSystemPropertyFromApacheFileUtils(string propertyName) { ) } -private MethodAccess getSystemPropertyFromGuava(string propertyName) { +private MethodCall getSystemPropertyFromGuava(string propertyName) { exists(EnumConstant ec | ec.getDeclaringType().hasQualifiedName("com.google.common.base", "StandardSystemProperty") and // Example: `StandardSystemProperty.JAVA_IO_TMPDIR.value()` @@ -177,10 +177,10 @@ private MethodAccess getSystemPropertyFromGuava(string propertyName) { ) or // Example: `System.getProperty(StandardSystemProperty.JAVA_IO_TMPDIR.key())` - exists(MethodAccess keyMa | + exists(MethodCall keyMa | localExprFlowPlusInitializers(ec.getAnAccess(), keyMa.getQualifier()) and keyMa.getMethod().hasName("key") and - localExprFlowPlusInitializers(keyMa, result.(MethodAccessSystemGetProperty).getArgument(0)) + localExprFlowPlusInitializers(keyMa, result.(MethodCallSystemGetProperty).getArgument(0)) ) | ec.hasName("JAVA_VERSION") and propertyName = "java.version" @@ -241,7 +241,7 @@ private MethodAccess getSystemPropertyFromGuava(string propertyName) { ) } -private MethodAccess getSystemPropertyFromOperatingSystemMXBean(string propertyName) { +private MethodCall getSystemPropertyFromOperatingSystemMXBean(string propertyName) { exists(Method m | m = result.getMethod() and m.getDeclaringType().hasQualifiedName("java.lang.management", "OperatingSystemMXBean") @@ -254,7 +254,7 @@ private MethodAccess getSystemPropertyFromOperatingSystemMXBean(string propertyN ) } -private MethodAccess getSystemPropertyFromSpringProperties(string propertyName) { +private MethodCall getSystemPropertyFromSpringProperties(string propertyName) { exists(Method m | m = result.getMethod() and m.getDeclaringType().hasQualifiedName("org.springframework.core", "SpringProperties") and diff --git a/java/ql/lib/semmle/code/java/frameworks/Assertions.qll b/java/ql/lib/semmle/code/java/frameworks/Assertions.qll index 80126f107e9c..287346b85360 100644 --- a/java/ql/lib/semmle/code/java/frameworks/Assertions.qll +++ b/java/ql/lib/semmle/code/java/frameworks/Assertions.qll @@ -60,10 +60,10 @@ class AssertionMethod extends Method { AssertionMethod() { assertionMethod(this, _) } /** Gets a call to the assertion method. */ - MethodAccess getACheck() { result.getMethod().getSourceDeclaration() = this } + MethodCall getACheck() { result.getMethod().getSourceDeclaration() = this } /** Gets a call to the assertion method with `checkedArg` as argument. */ - MethodAccess getACheck(Expr checkedArg) { + MethodCall getACheck(Expr checkedArg) { result = this.getACheck() and checkedArg = result.getAnArgument() } } diff --git a/java/ql/lib/semmle/code/java/frameworks/FastJson.qll b/java/ql/lib/semmle/code/java/frameworks/FastJson.qll index 99eb47d76f03..c9f7d9e8b89d 100644 --- a/java/ql/lib/semmle/code/java/frameworks/FastJson.qll +++ b/java/ql/lib/semmle/code/java/frameworks/FastJson.qll @@ -24,7 +24,7 @@ class FastJsonParseMethod extends Method { /** * A call to `ParserConfig.setSafeMode`. */ -class FastJsonSetSafeMode extends MethodAccess { +class FastJsonSetSafeMode extends MethodCall { FastJsonSetSafeMode() { exists(Method m | this.getMethod() = m and diff --git a/java/ql/lib/semmle/code/java/frameworks/Jackson.qll b/java/ql/lib/semmle/code/java/frameworks/Jackson.qll index 39ee238fe355..605370ec594f 100644 --- a/java/ql/lib/semmle/code/java/frameworks/Jackson.qll +++ b/java/ql/lib/semmle/code/java/frameworks/Jackson.qll @@ -44,7 +44,7 @@ class ObjectMapperReadMethod extends Method { } /** A call that enables the default typing in `ObjectMapper`. */ -class EnableJacksonDefaultTyping extends MethodAccess { +class EnableJacksonDefaultTyping extends MethodCall { EnableJacksonDefaultTyping() { this.getMethod().getDeclaringType() instanceof ObjectMapper and this.getMethod().hasName("enableDefaultTyping") @@ -54,7 +54,7 @@ class EnableJacksonDefaultTyping extends MethodAccess { /** A qualifier of a call to one of the methods in `ObjectMapper` that deserialize data. */ class ObjectMapperReadQualifier extends DataFlow::ExprNode { ObjectMapperReadQualifier() { - exists(MethodAccess ma | ma.getQualifier() = this.asExpr() | + exists(MethodCall ma | ma.getQualifier() = this.asExpr() | ma.getMethod() instanceof ObjectMapperReadMethod ) } @@ -63,7 +63,7 @@ class ObjectMapperReadQualifier extends DataFlow::ExprNode { /** A source that sets a type validator. */ class SetPolymorphicTypeValidatorSource extends DataFlow::ExprNode { SetPolymorphicTypeValidatorSource() { - exists(MethodAccess ma, Method m | m = ma.getMethod() | + exists(MethodCall ma, Method m | m = ma.getMethod() | ( m.getDeclaringType() instanceof ObjectMapper and m.hasName("setPolymorphicTypeValidator") @@ -83,7 +83,7 @@ class SetPolymorphicTypeValidatorSource extends DataFlow::ExprNode { * if passed to an unsafely-configured `ObjectMapper`'s `readValue` method. */ predicate createJacksonJsonParserStep(DataFlow::Node fromNode, DataFlow::Node toNode) { - exists(MethodAccess ma, Method m | m = ma.getMethod() | + exists(MethodCall ma, Method m | m = ma.getMethod() | (m.getDeclaringType() instanceof ObjectMapper or m.getDeclaringType() instanceof JsonFactory) and m.hasName("createParser") and ma.getArgument(0) = fromNode.asExpr() and @@ -98,14 +98,14 @@ predicate createJacksonJsonParserStep(DataFlow::Node fromNode, DataFlow::Node to * if passed to an unsafely-configured `ObjectMapper`'s `treeToValue` method. */ predicate createJacksonTreeNodeStep(DataFlow::Node fromNode, DataFlow::Node toNode) { - exists(MethodAccess ma, Method m | m = ma.getMethod() | + exists(MethodCall ma, Method m | m = ma.getMethod() | m.getDeclaringType() instanceof ObjectMapper and m.hasName("readTree") and ma.getArgument(0) = fromNode.asExpr() and ma = toNode.asExpr() ) or - exists(MethodAccess ma, Method m | m = ma.getMethod() | + exists(MethodCall ma, Method m | m = ma.getMethod() | m.getDeclaringType() instanceof JsonParser and m.hasName("readValueAsTree") and ma.getQualifier() = fromNode.asExpr() and @@ -138,7 +138,7 @@ private predicate hasFieldWithJsonTypeAnnotation(RefType type) { * Holds if `call` is a method call to a Jackson deserialization method such as `ObjectMapper.readValue(String, Class)`, * and the target deserialized class has a field with a `JsonTypeInfo` annotation that enables polymorphic typing. */ -predicate hasArgumentWithUnsafeJacksonAnnotation(MethodAccess call) { +predicate hasArgumentWithUnsafeJacksonAnnotation(MethodCall call) { call.getMethod() instanceof ObjectMapperReadMethod and exists(RefType argType, int i | i > 0 and argType = call.getArgument(i).getType() | hasJsonTypeInfoAnnotation(argType.(ParameterizedType).getATypeArgument()) diff --git a/java/ql/lib/semmle/code/java/frameworks/JaxWS.qll b/java/ql/lib/semmle/code/java/frameworks/JaxWS.qll index 18a5d800df5a..f627a576c06b 100644 --- a/java/ql/lib/semmle/code/java/frameworks/JaxWS.qll +++ b/java/ql/lib/semmle/code/java/frameworks/JaxWS.qll @@ -437,7 +437,7 @@ private predicate isXssSafeContentTypeExpr(Expr e) { isXssSafeContentType(getCon private DataFlow::Node getABuilderWithExplicitContentType(Expr contentType) { // Base case: ResponseBuilder.type(contentType) result.asExpr() = - any(MethodAccess ma | + any(MethodCall ma | ma.getCallee().hasQualifiedName(getAJaxRsPackage("core"), "Response$ResponseBuilder", "type") and contentType = ma.getArgument(0) ) @@ -451,7 +451,7 @@ private DataFlow::Node getABuilderWithExplicitContentType(Expr contentType) { or // Base case: Variant[.VariantListBuilder].mediaTypes(...) result.asExpr() = - any(MethodAccess ma | + any(MethodCall ma | ma.getCallee() .hasQualifiedName(getAJaxRsPackage("core"), ["Variant", "Variant$VariantListBuilder"], "mediaTypes") and @@ -460,7 +460,7 @@ private DataFlow::Node getABuilderWithExplicitContentType(Expr contentType) { or // Recursive case: propagate through variant list building: result.asExpr() = - any(MethodAccess ma | + any(MethodCall ma | ( ma.getType() .(RefType) @@ -475,14 +475,14 @@ private DataFlow::Node getABuilderWithExplicitContentType(Expr contentType) { or // Recursive case: propagate through a List.get operation result.asExpr() = - any(MethodAccess ma | + any(MethodCall ma | ma.getMethod().hasQualifiedName("java.util", "List", "get") and ma.getQualifier() = getABuilderWithExplicitContentType(contentType).asExpr() ) or // Recursive case: propagate through Response.ResponseBuilder operations, including the `variant(...)` operation. result.asExpr() = - any(MethodAccess ma | + any(MethodCall ma | ma.getType().(RefType).hasQualifiedName(getAJaxRsPackage("core"), "Response$ResponseBuilder") and [ma.getQualifier(), ma.getArgument(0)] = getABuilderWithExplicitContentType(contentType).asExpr() @@ -518,7 +518,7 @@ private class SanitizedResponseBuilder extends XssSanitizer { this = getASanitizedBuilder() or this.asExpr() = - any(MethodAccess ma | + any(MethodCall ma | ma.getMethod().hasQualifiedName(getAJaxRsPackage("core"), "Response", "ok") and ( // e.g. Response.ok(sanitizeMe, new Variant("application/json", ...)) @@ -542,19 +542,19 @@ private class SanitizedResponseBuilder extends XssSanitizer { private class VulnerableEntity extends XssSinkBarrier { VulnerableEntity() { this.asExpr() = - any(MethodAccess ma | + any(MethodCall ma | ( // Vulnerable content-type already set: ma.getQualifier() = getAVulnerableBuilder().asExpr() or // Vulnerable content-type set in the future: - getAVulnerableBuilder().asExpr().(MethodAccess).getQualifier*() = ma + getAVulnerableBuilder().asExpr().(MethodCall).getQualifier*() = ma ) and ma.getMethod().hasName("entity") ).getArgument(0) or this.asExpr() = - any(MethodAccess ma | + any(MethodCall ma | ( isXssVulnerableContentTypeExpr(ma.getArgument(1)) or diff --git a/java/ql/lib/semmle/code/java/frameworks/JsonIo.qll b/java/ql/lib/semmle/code/java/frameworks/JsonIo.qll index aa332bd78ed5..19a4c4d2a634 100644 --- a/java/ql/lib/semmle/code/java/frameworks/JsonIo.qll +++ b/java/ql/lib/semmle/code/java/frameworks/JsonIo.qll @@ -33,7 +33,7 @@ class JsonIoReadObjectMethod extends Method { /** * A call to `Map.put` method, set the value of the `USE_MAPS` key to `true`. */ -class JsonIoUseMapsSetter extends MethodAccess { +class JsonIoUseMapsSetter extends MethodCall { JsonIoUseMapsSetter() { this.getMethod().getDeclaringType().getASourceSupertype*() instanceof MapType and this.getMethod().hasName("put") and @@ -51,14 +51,14 @@ deprecated class SafeJsonIoConfig extends DataFlow2::Configuration { SafeJsonIoConfig() { this = "UnsafeDeserialization::SafeJsonIoConfig" } override predicate isSource(DataFlow::Node src) { - exists(MethodAccess ma | + exists(MethodCall ma | ma instanceof JsonIoUseMapsSetter and src.asExpr() = ma.getQualifier() ) } override predicate isSink(DataFlow::Node sink) { - exists(MethodAccess ma | + exists(MethodCall ma | ma.getMethod() instanceof JsonIoJsonToJavaMethod and sink.asExpr() = ma.getArgument(1) ) @@ -75,14 +75,14 @@ deprecated class SafeJsonIoConfig extends DataFlow2::Configuration { */ module SafeJsonIoConfig implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node src) { - exists(MethodAccess ma | + exists(MethodCall ma | ma instanceof JsonIoUseMapsSetter and src.asExpr() = ma.getQualifier() ) } predicate isSink(DataFlow::Node sink) { - exists(MethodAccess ma | + exists(MethodCall ma | ma.getMethod() instanceof JsonIoJsonToJavaMethod and sink.asExpr() = ma.getArgument(1) ) diff --git a/java/ql/lib/semmle/code/java/frameworks/Kryo.qll b/java/ql/lib/semmle/code/java/frameworks/Kryo.qll index 057b10de6327..7dde62c4ba4b 100644 --- a/java/ql/lib/semmle/code/java/frameworks/Kryo.qll +++ b/java/ql/lib/semmle/code/java/frameworks/Kryo.qll @@ -76,7 +76,7 @@ class KryoReadObjectMethod extends Method { /** * A call to `Kryo.setRegistrationRequired` that enables white-listing. */ -class KryoEnableWhiteListing extends MethodAccess { +class KryoEnableWhiteListing extends MethodCall { KryoEnableWhiteListing() { exists(Method m | m = this.getMethod() and diff --git a/java/ql/lib/semmle/code/java/frameworks/Mockito.qll b/java/ql/lib/semmle/code/java/frameworks/Mockito.qll index 47074f9547bc..38af7eb8575f 100644 --- a/java/ql/lib/semmle/code/java/frameworks/Mockito.qll +++ b/java/ql/lib/semmle/code/java/frameworks/Mockito.qll @@ -17,14 +17,17 @@ class MockitoVerifyMethod extends Method { } /** - * A MethodAccess which is called as part of a Mockito verification setup. + * A MethodCall which is called as part of a Mockito verification setup. */ -class MockitoVerifiedMethodAccess extends MethodAccess { - MockitoVerifiedMethodAccess() { - this.getQualifier().(MethodAccess).getMethod() instanceof MockitoVerifyMethod +class MockitoVerifiedMethodCall extends MethodCall { + MockitoVerifiedMethodCall() { + this.getQualifier().(MethodCall).getMethod() instanceof MockitoVerifyMethod } } +/** DEPRECATED: Alias for `MockitoVerifiedMethodCall`. */ +deprecated class MockitoVerifiedMethodAccess = MockitoVerifiedMethodCall; + /** * A type that can be mocked by Mockito. */ @@ -75,9 +78,7 @@ class MockitoInitedTest extends Class { m.calls*(initMocks) ) or - exists(MethodAccess call | call.getCallee() = initMocks | - call.getArgument(0).getType() = this - ) + exists(MethodCall call | call.getCallee() = initMocks | call.getArgument(0).getType() = this) ) } } @@ -383,12 +384,12 @@ class MockitoMockMethod extends Method { class MockitoMockedObject extends Expr { MockitoMockedObject() { - this.(MethodAccess).getMethod() instanceof MockitoMockMethod + this.(MethodCall).getMethod() instanceof MockitoMockMethod or this.(VarAccess).getVariable().getAnAssignedValue() instanceof MockitoMockedObject or exists(ReturnStmt ret | - this.(MethodAccess).getMethod() = ret.getEnclosingCallable() and + this.(MethodCall).getMethod() = ret.getEnclosingCallable() and ret.getResult() instanceof MockitoMockedObject ) } diff --git a/java/ql/lib/semmle/code/java/frameworks/MyBatis.qll b/java/ql/lib/semmle/code/java/frameworks/MyBatis.qll index 4c1244ca1d5d..01c8b829de6b 100644 --- a/java/ql/lib/semmle/code/java/frameworks/MyBatis.qll +++ b/java/ql/lib/semmle/code/java/frameworks/MyBatis.qll @@ -114,7 +114,7 @@ class MyBatisInjectionSink extends DataFlow::Node { private class MyBatisProviderStep extends TaintTracking::AdditionalValueStep { override predicate step(DataFlow::Node n1, DataFlow::Node n2) { - exists(MethodAccess ma, Annotation a, Method providerMethod | + exists(MethodCall ma, Annotation a, Method providerMethod | exists(int i | ma.getArgument(pragma[only_bind_into](i)) = n1.asExpr() and providerMethod.getParameter(pragma[only_bind_into](i)) = n2.asParameter() diff --git a/java/ql/lib/semmle/code/java/frameworks/Selenium.qll b/java/ql/lib/semmle/code/java/frameworks/Selenium.qll index e3e98738fd6d..0ea61ae0ecfe 100644 --- a/java/ql/lib/semmle/code/java/frameworks/Selenium.qll +++ b/java/ql/lib/semmle/code/java/frameworks/Selenium.qll @@ -16,7 +16,7 @@ class SeleniumPageFactory extends Class { /** * A call to the Selenium `PageFactory.initElements` method, to construct a page object. */ -class SeleniumInitElementsAccess extends MethodAccess { +class SeleniumInitElementsAccess extends MethodCall { SeleniumInitElementsAccess() { this.getMethod().getDeclaringType() instanceof SeleniumPageFactory and this.getMethod().hasName("initElements") diff --git a/java/ql/lib/semmle/code/java/frameworks/Servlets.qll b/java/ql/lib/semmle/code/java/frameworks/Servlets.qll index 9c195ecea8dd..88b8c5c5d976 100644 --- a/java/ql/lib/semmle/code/java/frameworks/Servlets.qll +++ b/java/ql/lib/semmle/code/java/frameworks/Servlets.qll @@ -345,7 +345,7 @@ predicate isServletRequestMethod(Method m) { } /** Holds if `ma` is a call that gets a request parameter. */ -predicate isRequestGetParamMethod(MethodAccess ma) { +predicate isRequestGetParamMethod(MethodCall ma) { ma.getMethod() instanceof ServletRequestGetParameterMethod or ma.getMethod() instanceof ServletRequestGetParameterMapMethod or ma.getMethod() instanceof HttpServletRequestGetQueryStringMethod diff --git a/java/ql/lib/semmle/code/java/frameworks/SnakeYaml.qll b/java/ql/lib/semmle/code/java/frameworks/SnakeYaml.qll index f21b95520619..3bde32912180 100644 --- a/java/ql/lib/semmle/code/java/frameworks/SnakeYaml.qll +++ b/java/ql/lib/semmle/code/java/frameworks/SnakeYaml.qll @@ -53,7 +53,7 @@ private class SafeYaml extends ClassInstanceExpr { } /** A call to a parse method of `Yaml`. */ -private class SnakeYamlParse extends MethodAccess { +private class SnakeYamlParse extends MethodCall { SnakeYamlParse() { exists(Method m | m.getDeclaringType() instanceof Yaml and diff --git a/java/ql/lib/semmle/code/java/frameworks/Stream.qll b/java/ql/lib/semmle/code/java/frameworks/Stream.qll index f68cd6c844e1..96d74d1473a7 100644 --- a/java/ql/lib/semmle/code/java/frameworks/Stream.qll +++ b/java/ql/lib/semmle/code/java/frameworks/Stream.qll @@ -2,7 +2,7 @@ private import semmle.code.java.dataflow.FlowSummary -private class CollectCall extends MethodAccess { +private class CollectCall extends MethodCall { CollectCall() { this.getMethod() .getSourceDeclaration() @@ -10,7 +10,7 @@ private class CollectCall extends MethodAccess { } } -private class Collector extends MethodAccess { +private class Collector extends MethodCall { Collector() { this.getMethod().getDeclaringType().hasQualifiedName("java.util.stream", "Collectors") } diff --git a/java/ql/lib/semmle/code/java/frameworks/XStream.qll b/java/ql/lib/semmle/code/java/frameworks/XStream.qll index facc4a67914d..0e62459e13d8 100644 --- a/java/ql/lib/semmle/code/java/frameworks/XStream.qll +++ b/java/ql/lib/semmle/code/java/frameworks/XStream.qll @@ -27,7 +27,7 @@ class XStreamReadObjectMethod extends Method { /** * A call to `XStream.addPermission(NoTypePermission.NONE)`, which enables white-listing. */ -class XStreamEnableWhiteListing extends MethodAccess { +class XStreamEnableWhiteListing extends MethodCall { XStreamEnableWhiteListing() { exists(Method m | m = this.getMethod() and diff --git a/java/ql/lib/semmle/code/java/frameworks/android/AsyncTask.qll b/java/ql/lib/semmle/code/java/frameworks/android/AsyncTask.qll index 1e739bcba2b7..226a80709456 100644 --- a/java/ql/lib/semmle/code/java/frameworks/android/AsyncTask.qll +++ b/java/ql/lib/semmle/code/java/frameworks/android/AsyncTask.qll @@ -15,7 +15,7 @@ private import semmle.code.java.dataflow.FlowSteps */ private class AsyncTaskExecuteAdditionalValueStep extends AdditionalTaintStep { override predicate step(DataFlow::Node node1, DataFlow::Node node2) { - exists(ExecuteAsyncTaskMethodAccess ma, AsyncTaskRunInBackgroundMethod m | + exists(ExecuteAsyncTaskMethodCall ma, AsyncTaskRunInBackgroundMethod m | DataFlow::getInstanceArgument(ma).getType() = m.getDeclaringType() | node1.asExpr() = ma.getParamsArgument() and @@ -76,8 +76,8 @@ private class AsyncTaskInit extends Callable { } /** A call to the `execute` or `executeOnExecutor` methods of the `android.os.AsyncTask` class. */ -private class ExecuteAsyncTaskMethodAccess extends MethodAccess { - ExecuteAsyncTaskMethodAccess() { +private class ExecuteAsyncTaskMethodCall extends MethodCall { + ExecuteAsyncTaskMethodCall() { this.getMethod().hasName(["execute", "executeOnExecutor"]) and this.getMethod().getDeclaringType().getSourceDeclaration().getASourceSupertype*() instanceof AsyncTask diff --git a/java/ql/lib/semmle/code/java/frameworks/android/Compose.qll b/java/ql/lib/semmle/code/java/frameworks/android/Compose.qll index c511d3601a55..0e6399cba1f0 100644 --- a/java/ql/lib/semmle/code/java/frameworks/android/Compose.qll +++ b/java/ql/lib/semmle/code/java/frameworks/android/Compose.qll @@ -8,7 +8,7 @@ import java * A call to a live literal method. * This always returns a constant expression and can be considered as such. */ -class LiveLiteral extends MethodAccess { +class LiveLiteral extends MethodCall { LiveLiteral() { this.getMethod() instanceof LiveLiteralMethod and not this.getEnclosingCallable() instanceof LiveLiteralMethod @@ -25,7 +25,7 @@ class LiveLiteral extends MethodAccess { * This predicate gets the constant value held by the private field. */ CompileTimeConstantExpr getValue() { - exists(MethodAccess getterCall, VarAccess va | + exists(MethodCall getterCall, VarAccess va | methodReturns(this.getMethod(), getterCall) and methodReturns(getterCall.getMethod(), va) and result = va.getVariable().getInitializer() diff --git a/java/ql/lib/semmle/code/java/frameworks/android/Intent.qll b/java/ql/lib/semmle/code/java/frameworks/android/Intent.qll index 104fd74b5f2c..1aba2be33c06 100644 --- a/java/ql/lib/semmle/code/java/frameworks/android/Intent.qll +++ b/java/ql/lib/semmle/code/java/frameworks/android/Intent.qll @@ -154,7 +154,7 @@ class AndroidBundle extends Class { */ class ExplicitIntent extends Expr { ExplicitIntent() { - exists(MethodAccess ma, Method m | + exists(MethodCall ma, Method m | ma.getMethod() = m and m.getDeclaringType() instanceof TypeIntent and m.hasName(["setPackage", "setClass", "setClassName", "setComponent"]) and @@ -237,8 +237,8 @@ private class NewIntent extends ClassInstanceExpr { } /** A call to a method that starts an Android component. */ -private class StartComponentMethodAccess extends MethodAccess { - StartComponentMethodAccess() { +private class StartComponentMethodCall extends MethodCall { + StartComponentMethodCall() { this.getMethod().overrides*(any(StartActivityMethod m)) or this.getMethod().overrides*(any(StartServiceMethod m)) or this.getMethod().overrides*(any(SendBroadcastMethod m)) @@ -263,11 +263,11 @@ private class StartComponentMethodAccess extends MethodAccess { } /** - * Holds if `src` reaches the intent argument `arg` of `StartComponentMethodAccess` + * Holds if `src` reaches the intent argument `arg` of `StartComponentMethodCall` * through intra-procedural steps. */ private predicate reaches(Expr src, Argument arg) { - any(StartComponentMethodAccess ma).getIntentArg() = arg and + any(StartComponentMethodCall ma).getIntentArg() = arg and src = arg or exists(Expr mid, BaseSsa::BaseSsaVariable ssa, BaseSsa::BaseSsaUpdate upd | @@ -298,7 +298,7 @@ private predicate reaches(Expr src, Argument arg) { */ private class StartActivityIntentStep extends AdditionalValueStep { override predicate step(DataFlow::Node n1, DataFlow::Node n2) { - exists(StartComponentMethodAccess startActivity, MethodAccess getIntent | + exists(StartComponentMethodCall startActivity, MethodCall getIntent | startActivity.getMethod().overrides*(any(StartActivityMethod m)) and getIntent.getMethod().overrides*(any(AndroidGetIntentMethod m)) and startActivity.targetsComponentType(getIntent.getReceiverType()) and @@ -309,11 +309,11 @@ private class StartActivityIntentStep extends AdditionalValueStep { } /** - * Holds if `targetType` is targeted by an existing `StartComponentMethodAccess` call + * Holds if `targetType` is targeted by an existing `StartComponentMethodCall` call * and it's identified by `id`. */ private predicate isTargetableType(AndroidComponent targetType, string id) { - exists(StartComponentMethodAccess ma | ma.targetsComponentType(targetType)) and + exists(StartComponentMethodCall ma | ma.targetsComponentType(targetType)) and targetType.getQualifiedName() = id } @@ -327,7 +327,7 @@ private class StartActivitiesSyntheticCallable extends SyntheticCallable { ) } - override StartComponentMethodAccess getACall() { + override StartComponentMethodCall getACall() { result.getMethod().hasName("startActivities") and result.targetsComponentType(targetType) } @@ -396,7 +396,7 @@ private class RequiredComponentStackForStartActivities extends RequiredSummaryCo */ private class SendBroadcastReceiverIntentStep extends AdditionalValueStep { override predicate step(DataFlow::Node n1, DataFlow::Node n2) { - exists(StartComponentMethodAccess sendBroadcast, Method onReceive | + exists(StartComponentMethodCall sendBroadcast, Method onReceive | sendBroadcast.getMethod().overrides*(any(SendBroadcastMethod m)) and onReceive.overrides*(any(AndroidReceiveIntentMethod m)) and sendBroadcast.targetsComponentType(onReceive.getDeclaringType()) and @@ -413,7 +413,7 @@ private class SendBroadcastReceiverIntentStep extends AdditionalValueStep { */ private class StartServiceIntentStep extends AdditionalValueStep { override predicate step(DataFlow::Node n1, DataFlow::Node n2) { - exists(StartComponentMethodAccess startService, Method serviceIntent | + exists(StartComponentMethodCall startService, Method serviceIntent | startService.getMethod().overrides*(any(StartServiceMethod m)) and serviceIntent.overrides*(any(AndroidServiceIntentMethod m)) and startService.targetsComponentType(serviceIntent.getDeclaringType()) and diff --git a/java/ql/lib/semmle/code/java/frameworks/android/OnActivityResultSource.qll b/java/ql/lib/semmle/code/java/frameworks/android/OnActivityResultSource.qll index c487c6cecc26..5253526f0fd1 100644 --- a/java/ql/lib/semmle/code/java/frameworks/android/OnActivityResultSource.qll +++ b/java/ql/lib/semmle/code/java/frameworks/android/OnActivityResultSource.qll @@ -37,7 +37,7 @@ class OnActivityResultIncomingIntent extends DataFlow::Node { or // A fragment calls `startActivityForResult` // and the activity it belongs to defines `onActivityResult`. - exists(MethodAccess ma | + exists(MethodCall ma | ma.getMethod().hasName(["add", "attach", "replace"]) and ma.getMethod() .getDeclaringType() @@ -71,7 +71,7 @@ private module ImplicitStartActivityForResultConfig implements DataFlow::ConfigS } predicate isSink(DataFlow::Node sink) { - exists(MethodAccess startActivityForResult | + exists(MethodCall startActivityForResult | startActivityForResult.getMethod().hasName("startActivityForResult") and startActivityForResult.getMethod().getDeclaringType().getAnAncestor() instanceof ActivityOrFragment and @@ -83,7 +83,7 @@ private module ImplicitStartActivityForResultConfig implements DataFlow::ConfigS predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) { // Wrapping the Intent in a chooser - exists(MethodAccess ma, Method m | + exists(MethodCall ma, Method m | ma.getMethod() = m and m.hasName("createChooser") and m.getDeclaringType() instanceof TypeIntent diff --git a/java/ql/lib/semmle/code/java/frameworks/android/PendingIntent.qll b/java/ql/lib/semmle/code/java/frameworks/android/PendingIntent.qll index 544097061511..1c17d3c9b8df 100644 --- a/java/ql/lib/semmle/code/java/frameworks/android/PendingIntent.qll +++ b/java/ql/lib/semmle/code/java/frameworks/android/PendingIntent.qll @@ -8,7 +8,7 @@ class PendingIntent extends Class { } /** A call to a method that creates a `PendingIntent`. */ -class PendingIntentCreation extends MethodAccess { +class PendingIntentCreation extends MethodCall { PendingIntentCreation() { exists(Method m | this.getMethod() = m and diff --git a/java/ql/lib/semmle/code/java/frameworks/android/Widget.qll b/java/ql/lib/semmle/code/java/frameworks/android/Widget.qll index 9cb39ed83a73..9a2729f5b794 100644 --- a/java/ql/lib/semmle/code/java/frameworks/android/Widget.qll +++ b/java/ql/lib/semmle/code/java/frameworks/android/Widget.qll @@ -6,7 +6,7 @@ private import semmle.code.java.dataflow.FlowSources private class EditableToStringStep extends AdditionalTaintStep { override predicate step(DataFlow::Node n1, DataFlow::Node n2) { - exists(MethodAccess ma | + exists(MethodCall ma | ma.getMethod().hasName("toString") and ma.getReceiverType().getASourceSupertype*().hasQualifiedName("android.text", "Editable") and n1.asExpr() = ma.getQualifier() and diff --git a/java/ql/lib/semmle/code/java/frameworks/apache/CommonsXml.qll b/java/ql/lib/semmle/code/java/frameworks/apache/CommonsXml.qll index 42ecc946e504..5e72b26e009b 100644 --- a/java/ql/lib/semmle/code/java/frameworks/apache/CommonsXml.qll +++ b/java/ql/lib/semmle/code/java/frameworks/apache/CommonsXml.qll @@ -79,7 +79,7 @@ private module SafeDigesterFlowConfig implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node src) { src.asExpr() instanceof SafeDigester } predicate isSink(DataFlow::Node sink) { - exists(MethodAccess ma | + exists(MethodCall ma | sink.asExpr() = ma.getQualifier() and ma.getMethod().getDeclaringType() instanceof Digester ) } diff --git a/java/ql/lib/semmle/code/java/frameworks/camel/CamelJavaDSL.qll b/java/ql/lib/semmle/code/java/frameworks/camel/CamelJavaDSL.qll index ab72d80d2e51..a7747857fdd6 100644 --- a/java/ql/lib/semmle/code/java/frameworks/camel/CamelJavaDSL.qll +++ b/java/ql/lib/semmle/code/java/frameworks/camel/CamelJavaDSL.qll @@ -21,7 +21,7 @@ import semmle.code.java.frameworks.spring.Spring /** * A method call to a ProcessorDefinition element. */ -class ProcessorDefinitionElement extends MethodAccess { +class ProcessorDefinitionElement extends MethodCall { ProcessorDefinitionElement() { this.getMethod() .getDeclaringType() @@ -114,7 +114,7 @@ deprecated class CamelJavaDSLBeanRefDecl = CamelJavaDslBeanRefDecl; * * An expression that represents a call to a bean, or particular method on a bean. */ -class CamelJavaDslMethodDecl extends MethodAccess { +class CamelJavaDslMethodDecl extends MethodCall { CamelJavaDslMethodDecl() { this.getMethod() .getDeclaringType() diff --git a/java/ql/lib/semmle/code/java/frameworks/google/GoogleHttpClientApi.qll b/java/ql/lib/semmle/code/java/frameworks/google/GoogleHttpClientApi.qll index 2793f1980c5c..db8bc2574c13 100644 --- a/java/ql/lib/semmle/code/java/frameworks/google/GoogleHttpClientApi.qll +++ b/java/ql/lib/semmle/code/java/frameworks/google/GoogleHttpClientApi.qll @@ -14,7 +14,7 @@ private module TypeLiteralToParseAsFlowConfig implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node source) { source.asExpr() instanceof TypeLiteral } predicate isSink(DataFlow::Node sink) { - exists(MethodAccess ma | + exists(MethodCall ma | ma.getAnArgument() = sink.asExpr() and ma.getMethod() instanceof ParseAsMethod ) diff --git a/java/ql/lib/semmle/code/java/frameworks/google/Gson.qll b/java/ql/lib/semmle/code/java/frameworks/google/Gson.qll index b9329182ec9a..9dc38a529415 100644 --- a/java/ql/lib/semmle/code/java/frameworks/google/Gson.qll +++ b/java/ql/lib/semmle/code/java/frameworks/google/Gson.qll @@ -26,7 +26,7 @@ class GsonDeserializeMethod extends Method { * where `T` is a concrete type implementing `Parcelable`. */ predicate intentFlowsToParcel(DataFlow::Node intentNode, DataFlow::Node parcelNode) { - exists(MethodAccess getParcelableExtraCall, CreateFromParcelMethod cfpm, Type createdType | + exists(MethodCall getParcelableExtraCall, CreateFromParcelMethod cfpm, Type createdType | intentNode.asExpr() = getParcelableExtraCall.getQualifier() and getParcelableExtraCall.getMethod() instanceof IntentGetParcelableExtraMethod and DataFlow::localExprFlow(getParcelableExtraCall, any(Expr e | e.getType() = createdType)) and diff --git a/java/ql/lib/semmle/code/java/frameworks/google/GsonSerializability.qll b/java/ql/lib/semmle/code/java/frameworks/google/GsonSerializability.qll index 8a286c93a16f..6abaee8ff720 100644 --- a/java/ql/lib/semmle/code/java/frameworks/google/GsonSerializability.qll +++ b/java/ql/lib/semmle/code/java/frameworks/google/GsonSerializability.qll @@ -22,7 +22,7 @@ abstract class GsonDeserializableType extends Type { } /** A type whose values are explicitly deserialized in a call to a Gson method. */ private class ExplicitlyReadGsonDeserializableType extends GsonDeserializableType { ExplicitlyReadGsonDeserializableType() { - exists(MethodAccess ma | + exists(MethodCall ma | // A call to a Gson read method... ma.getMethod() instanceof GsonReadValueMethod and // ...where `this` is used in the final argument, indicating that this type will be deserialized. diff --git a/java/ql/lib/semmle/code/java/frameworks/hudson/Hudson.qll b/java/ql/lib/semmle/code/java/frameworks/hudson/Hudson.qll index c2a7272a9f5d..ae316cf649e5 100644 --- a/java/ql/lib/semmle/code/java/frameworks/hudson/Hudson.qll +++ b/java/ql/lib/semmle/code/java/frameworks/hudson/Hudson.qll @@ -16,7 +16,7 @@ class HudsonWebMethod extends Method { private class HudsonUtilXssSanitizer extends XssSanitizer { HudsonUtilXssSanitizer() { this.asExpr() - .(MethodAccess) + .(MethodCall) .getMethod() // Not including xmlEscape because it only accounts for >, <, and &. // It does not account for ", or ', which makes it an incomplete XSS sanitizer. diff --git a/java/ql/lib/semmle/code/java/frameworks/jackson/JacksonSerializability.qll b/java/ql/lib/semmle/code/java/frameworks/jackson/JacksonSerializability.qll index 4f857afb6608..8e1077d8bc01 100644 --- a/java/ql/lib/semmle/code/java/frameworks/jackson/JacksonSerializability.qll +++ b/java/ql/lib/semmle/code/java/frameworks/jackson/JacksonSerializability.qll @@ -68,7 +68,7 @@ private class JacksonReadValueMethod extends Method, TaintPreservingCallable { /** A type whose values are explicitly serialized in a call to a Jackson method. */ private class ExplicitlyWrittenJacksonSerializableType extends JacksonSerializableType { ExplicitlyWrittenJacksonSerializableType() { - exists(MethodAccess ma | + exists(MethodCall ma | // A call to a Jackson write method... ma.getMethod() instanceof JacksonWriteValueMethod and // ...where `this` is used in the final argument, indicating that this type will be serialized. @@ -91,7 +91,7 @@ private module TypeLiteralToJacksonDatabindFlowConfig implements DataFlow::Confi predicate isSource(DataFlow::Node source) { source.asExpr() instanceof TypeLiteral } predicate isSink(DataFlow::Node sink) { - exists(MethodAccess ma, Method m, int i | + exists(MethodCall ma, Method m, int i | ma.getArgument(i) = sink.asExpr() and m = ma.getMethod() and m.getParameterType(i) instanceof TypeClass and @@ -116,7 +116,7 @@ private class ExplicitlyReadJacksonDeserializableType extends JacksonDeserializa ExplicitlyReadJacksonDeserializableType() { usesType(getSourceWithFlowToJacksonDatabind().getReferencedType(), this) or - exists(MethodAccess ma | + exists(MethodCall ma | // A call to a Jackson read method... ma.getMethod() instanceof JacksonReadValueMethod and // ...where `this` is used in the final argument, indicating that this type will be deserialized. @@ -177,7 +177,7 @@ private class JacksonDeserializedTaintStep extends AdditionalTaintStep { * This informs Jackson to treat the annotations on the second class argument as if they were on * the first class argument. This allows adding annotations to library classes, for example. */ -class JacksonAddMixinCall extends MethodAccess { +class JacksonAddMixinCall extends MethodCall { JacksonAddMixinCall() { exists(Method m | m = this.getMethod() and diff --git a/java/ql/lib/semmle/code/java/frameworks/javaee/Xml.qll b/java/ql/lib/semmle/code/java/frameworks/javaee/Xml.qll index 590b172bffa8..c1a0b08d8e7c 100644 --- a/java/ql/lib/semmle/code/java/frameworks/javaee/Xml.qll +++ b/java/ql/lib/semmle/code/java/frameworks/javaee/Xml.qll @@ -52,7 +52,7 @@ private module SafeValidatorFlowConfig implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node src) { src.asExpr() instanceof SafeValidator } predicate isSink(DataFlow::Node sink) { - exists(MethodAccess ma | + exists(MethodCall ma | sink.asExpr() = ma.getQualifier() and ma.getMethod().getDeclaringType() instanceof Validator ) diff --git a/java/ql/lib/semmle/code/java/frameworks/javaee/ejb/EJBRestrictions.qll b/java/ql/lib/semmle/code/java/frameworks/javaee/ejb/EJBRestrictions.qll index 461a7dc8208f..f5a52490768c 100644 --- a/java/ql/lib/semmle/code/java/frameworks/javaee/ejb/EJBRestrictions.qll +++ b/java/ql/lib/semmle/code/java/frameworks/javaee/ejb/EJBRestrictions.qll @@ -135,7 +135,7 @@ class ForbiddenThisCallable extends ForbiddenCallable { ThisAccess forbiddenThisUse(Callable c) { result.getEnclosingCallable() = c and ( - exists(MethodAccess ma | ma.getAnArgument() = result) or + exists(MethodCall ma | ma.getAnArgument() = result) or exists(ReturnStmt rs | rs.getResult() = result) ) } diff --git a/java/ql/lib/semmle/code/java/frameworks/kotlin/Kotlin.qll b/java/ql/lib/semmle/code/java/frameworks/kotlin/Kotlin.qll index 71e0af2018dd..206996af321d 100644 --- a/java/ql/lib/semmle/code/java/frameworks/kotlin/Kotlin.qll +++ b/java/ql/lib/semmle/code/java/frameworks/kotlin/Kotlin.qll @@ -3,7 +3,7 @@ import java /** A call to Kotlin's `apply` method. */ -class KotlinApply extends MethodAccess { +class KotlinApply extends MethodCall { ExtensionMethod m; KotlinApply() { diff --git a/java/ql/lib/semmle/code/java/frameworks/kotlin/Text.qll b/java/ql/lib/semmle/code/java/frameworks/kotlin/Text.qll index 62eafa9565ec..8521b2847848 100644 --- a/java/ql/lib/semmle/code/java/frameworks/kotlin/Text.qll +++ b/java/ql/lib/semmle/code/java/frameworks/kotlin/Text.qll @@ -8,7 +8,7 @@ class StringsKt extends RefType { } /** A call to the extension method `String.toRegex` from `kotlin.text`. */ -class KtToRegex extends MethodAccess { +class KtToRegex extends MethodCall { KtToRegex() { this.getMethod().getDeclaringType() instanceof StringsKt and this.getMethod().hasName("toRegex") diff --git a/java/ql/lib/semmle/code/java/frameworks/play/Play.qll b/java/ql/lib/semmle/code/java/frameworks/play/Play.qll index 695f64f53d19..7b99b23704e3 100644 --- a/java/ql/lib/semmle/code/java/frameworks/play/Play.qll +++ b/java/ql/lib/semmle/code/java/frameworks/play/Play.qll @@ -126,7 +126,7 @@ class PlayMvcHttpRequestHeaderMethods extends Method { /** * Gets a reference to the `getQueryString` method. */ - MethodAccess getAQueryStringAccess() { + MethodCall getAQueryStringAccess() { this.hasName("getQueryString") and result = this.getAReference() } } @@ -140,10 +140,10 @@ class PlayMvcResultsMethods extends Method { /** * Gets a reference to the `play.mvc.Results.ok` method. */ - MethodAccess getAnOkAccess() { this.hasName("ok") and result = this.getAReference() } + MethodCall getAnOkAccess() { this.hasName("ok") and result = this.getAReference() } /** * Gets a reference to the `play.mvc.Results.redirect` method. */ - MethodAccess getARedirectAccess() { this.hasName("redirect") and result = this.getAReference() } + MethodCall getARedirectAccess() { this.hasName("redirect") and result = this.getAReference() } } diff --git a/java/ql/lib/semmle/code/java/frameworks/spring/SpringController.qll b/java/ql/lib/semmle/code/java/frameworks/spring/SpringController.qll index f2611d6e2d10..9195a3878342 100644 --- a/java/ql/lib/semmle/code/java/frameworks/spring/SpringController.qll +++ b/java/ql/lib/semmle/code/java/frameworks/spring/SpringController.qll @@ -307,7 +307,7 @@ class SpringModelPlainMap extends SpringModel { SpringModelPlainMap() { this.getType() instanceof MapType } override RefType getATypeInModel() { - exists(MethodAccess methodCall | + exists(MethodCall methodCall | methodCall.getQualifier() = this.getAnAccess() and methodCall.getCallee().hasName("put") | @@ -327,7 +327,7 @@ class SpringModelModel extends SpringModel { } override RefType getATypeInModel() { - exists(MethodAccess methodCall | + exists(MethodCall methodCall | methodCall.getQualifier() = this.getAnAccess() and methodCall.getCallee().hasName("addAttribute") | diff --git a/java/ql/lib/semmle/code/java/frameworks/spring/SpringHttp.qll b/java/ql/lib/semmle/code/java/frameworks/spring/SpringHttp.qll index 4e91c1f18a2f..84c428e6fefa 100644 --- a/java/ql/lib/semmle/code/java/frameworks/spring/SpringHttp.qll +++ b/java/ql/lib/semmle/code/java/frameworks/spring/SpringHttp.qll @@ -164,14 +164,14 @@ private predicate isXssSafeContentTypeExpr(Expr e) { private DataFlow::Node getABodyBuilderWithExplicitContentType(Expr contentType) { result.asExpr() = - any(MethodAccess ma | + any(MethodCall ma | ma.getCallee() .hasQualifiedName("org.springframework.http", "ResponseEntity$BodyBuilder", "contentType") and contentType = ma.getArgument(0) ) or result.asExpr() = - any(MethodAccess ma | + any(MethodCall ma | ma.getQualifier() = getABodyBuilderWithExplicitContentType(contentType).asExpr() and ma.getType() .(RefType) @@ -192,7 +192,7 @@ private DataFlow::Node getAVulnerableBodyBuilder() { private class SanitizedBodyCall extends XSS::XssSanitizer { SanitizedBodyCall() { this.asExpr() = - any(MethodAccess ma | + any(MethodCall ma | ma.getQualifier() = getASanitizedBodyBuilder().asExpr() and ma.getCallee().hasName("body") ).getArgument(0) @@ -210,7 +210,7 @@ private class SanitizedBodyCall extends XSS::XssSanitizer { private class ExplicitlyVulnerableBodyArgument extends XSS::XssSinkBarrier { ExplicitlyVulnerableBodyArgument() { this.asExpr() = - any(MethodAccess ma | + any(MethodCall ma | ma.getQualifier() = getAVulnerableBodyBuilder().asExpr() and ma.getCallee().hasName("body") ).getArgument(0) diff --git a/java/ql/lib/semmle/code/java/frameworks/spring/SpringWeb.qll b/java/ql/lib/semmle/code/java/frameworks/spring/SpringWeb.qll index faa6b75853da..88db87e7e21e 100644 --- a/java/ql/lib/semmle/code/java/frameworks/spring/SpringWeb.qll +++ b/java/ql/lib/semmle/code/java/frameworks/spring/SpringWeb.qll @@ -31,7 +31,7 @@ class ModelAndView extends Class { } /** A call to the Spring `ModelAndView.setViewName` method. */ -class SpringModelAndViewSetViewNameCall extends MethodAccess { +class SpringModelAndViewSetViewNameCall extends MethodCall { SpringModelAndViewSetViewNameCall() { this.getMethod().getDeclaringType() instanceof ModelAndView and this.getMethod().hasName("setViewName") diff --git a/java/ql/lib/semmle/code/java/os/OSCheck.qll b/java/ql/lib/semmle/code/java/os/OSCheck.qll index eade97a6e53b..19dd15b0b894 100644 --- a/java/ql/lib/semmle/code/java/os/OSCheck.qll +++ b/java/ql/lib/semmle/code/java/os/OSCheck.qll @@ -40,7 +40,7 @@ abstract class IsSpecificUnixVariant extends Guard { } /** * Holds when `ma` compares the current OS against the string constant `osString`. */ -private predicate isOsFromSystemProp(MethodAccess ma, string osString) { +private predicate isOsFromSystemProp(MethodCall ma, string osString) { TaintTracking::localExprTaint(getSystemProperty("os.name"), ma.getQualifier()) and // Call from System.getProperty (or equivalent) to some partial match method exists(StringPartialMatchMethod m, CompileTimeConstantExpr matchedStringConstant | m = ma.getMethod() and @@ -50,7 +50,7 @@ private predicate isOsFromSystemProp(MethodAccess ma, string osString) { ) } -private class IsWindowsFromSystemProp extends IsWindowsGuard instanceof MethodAccess { +private class IsWindowsFromSystemProp extends IsWindowsGuard instanceof MethodCall { IsWindowsFromSystemProp() { isOsFromSystemProp(this, any(string s | s.regexpMatch("windows?"))) } } @@ -97,7 +97,7 @@ private class IsUnixFromFileSeparator extends IsUnixGuard { } } -private class IsUnixFromSystemProp extends IsSpecificUnixVariant instanceof MethodAccess { +private class IsUnixFromSystemProp extends IsSpecificUnixVariant instanceof MethodCall { IsUnixFromSystemProp() { isOsFromSystemProp(this, any(string s | s.regexpMatch(["mac.*", "linux.*"]))) } @@ -144,7 +144,7 @@ private class IsSpecificUnixVariantFromApacheCommons extends IsSpecificUnixVaria * ([source](https://en.wikipedia.org/wiki/POSIX#POSIX-oriented_operating_systems)). * Looks for calls to `contains("posix")` on the `supportedFileAttributeViews()` method returned by `FileSystem`. */ -private class IsUnixFromPosixFromFileSystem extends IsUnixGuard instanceof MethodAccess { +private class IsUnixFromPosixFromFileSystem extends IsUnixGuard instanceof MethodCall { IsUnixFromPosixFromFileSystem() { exists(Method m | m = this.getMethod() | m.getDeclaringType() @@ -158,9 +158,8 @@ private class IsUnixFromPosixFromFileSystem extends IsUnixGuard instanceof Metho supportedFileAttributeViewsMethod.hasName("supportedFileAttributeViews") and supportedFileAttributeViewsMethod.getDeclaringType() instanceof TypeFileSystem | - DataFlow::localExprFlow(any(MethodAccess ma | - ma.getMethod() = supportedFileAttributeViewsMethod - ), super.getQualifier()) + DataFlow::localExprFlow(any(MethodCall ma | ma.getMethod() = supportedFileAttributeViewsMethod), + super.getQualifier()) ) } } diff --git a/java/ql/lib/semmle/code/java/regex/RegexFlowConfigs.qll b/java/ql/lib/semmle/code/java/regex/RegexFlowConfigs.qll index a2db234bd36e..2af0a4e63c56 100644 --- a/java/ql/lib/semmle/code/java/regex/RegexFlowConfigs.qll +++ b/java/ql/lib/semmle/code/java/regex/RegexFlowConfigs.qll @@ -54,14 +54,14 @@ private class RegexFlowSink extends DataFlow::Node { /** Gets the string expression that a regex that flows here is matched against, if any. */ Expr getStringArgument() { - exists(MethodAccess ma | + exists(MethodCall ma | this.asExpr() = argOf(ma, _) and result = argOf(ma, strArg) ) } } -private Expr argOf(MethodAccess ma, int arg) { +private Expr argOf(MethodCall ma, int arg) { arg = -1 and result = ma.getQualifier() or result = ma.getArgument(arg) @@ -83,7 +83,7 @@ class RegexAdditionalFlowStep extends Unit { // TODO: This may be able to be done with models-as-data if query-specific flow steps beome supported. private class JdkRegexFlowStep extends RegexAdditionalFlowStep { override predicate step(DataFlow::Node node1, DataFlow::Node node2) { - exists(MethodAccess ma, Method m, string package, string type, string name, int arg | + exists(MethodCall ma, Method m, string package, string type, string name, int arg | ma.getMethod().getSourceDeclaration().overrides*(m) and m.hasQualifiedName(package, type, name) and node1.asExpr() = argOf(ma, arg) and @@ -109,7 +109,7 @@ private class JdkRegexFlowStep extends RegexAdditionalFlowStep { private class GuavaRegexFlowStep extends RegexAdditionalFlowStep { override predicate step(DataFlow::Node node1, DataFlow::Node node2) { - exists(MethodAccess ma, Method m, string package, string type, string name, int arg | + exists(MethodCall ma, Method m, string package, string type, string name, int arg | ma.getMethod().getSourceDeclaration().overrides*(m) and m.hasQualifiedName(package, type, name) and node1.asExpr() = argOf(ma, arg) and diff --git a/java/ql/lib/semmle/code/java/security/AndroidCertificatePinningQuery.qll b/java/ql/lib/semmle/code/java/security/AndroidCertificatePinningQuery.qll index 86779a4a9116..4c42e5a39032 100644 --- a/java/ql/lib/semmle/code/java/security/AndroidCertificatePinningQuery.qll +++ b/java/ql/lib/semmle/code/java/security/AndroidCertificatePinningQuery.qll @@ -40,7 +40,7 @@ private predicate trustedDomainViaXml(string domainName) { /** Holds if the given domain name is trusted by an OkHttp `CertificatePinner`. */ private predicate trustedDomainViaOkHttp(string domainName) { - exists(CompileTimeConstantExpr domainExpr, MethodAccess certPinnerAdd | + exists(CompileTimeConstantExpr domainExpr, MethodCall certPinnerAdd | domainExpr.getStringValue().replaceAll("*.", "") = domainName and // strip wildcard patterns like *.example.com certPinnerAdd.getMethod().hasQualifiedName("okhttp3", "CertificatePinner$Builder", "add") and DataFlow::localExprFlow(domainExpr, certPinnerAdd.getArgument(0)) @@ -59,8 +59,8 @@ predicate trustedDomain(string domainName) { * that uses a socket factory derived from a `TrustManager`. * `default` is true if the default SSL socket factory for all URLs is being set. */ -private predicate trustedSocketFactory(MethodAccess setSocketFactory, boolean default) { - exists(MethodAccess getSocketFactory, MethodAccess initSslContext | +private predicate trustedSocketFactory(MethodCall setSocketFactory, boolean default) { + exists(MethodCall getSocketFactory, MethodCall initSslContext | exists(Method m | setSocketFactory.getMethod() = m | default = true and m instanceof SetDefaultConnectionFactoryMethod or @@ -80,17 +80,17 @@ private predicate trustedSocketFactory(MethodAccess setSocketFactory, boolean de * that is trusted due to its SSL socket factory being set. */ private predicate trustedUrlConnection(Expr url) { - exists(MethodAccess openCon | + exists(MethodCall openCon | openCon.getMethod().getASourceOverriddenMethod*() instanceof UrlOpenConnectionMethod and url = openCon.getQualifier() and - exists(MethodAccess setSocketFactory | + exists(MethodCall setSocketFactory | trustedSocketFactory(setSocketFactory, false) and TaintTracking::localExprTaint(openCon, setSocketFactory.getQualifier()) ) ) or trustedSocketFactory(_, true) and - exists(MethodAccess open, Method m | + exists(MethodCall open, Method m | m instanceof UrlOpenConnectionMethod or m instanceof UrlOpenStreamMethod | open.getMethod().getASourceOverriddenMethod*() = m and diff --git a/java/ql/lib/semmle/code/java/security/AndroidIntentRedirection.qll b/java/ql/lib/semmle/code/java/security/AndroidIntentRedirection.qll index ef5f84001f00..56c45611b142 100644 --- a/java/ql/lib/semmle/code/java/security/AndroidIntentRedirection.qll +++ b/java/ql/lib/semmle/code/java/security/AndroidIntentRedirection.qll @@ -41,14 +41,14 @@ private class DefaultIntentRedirectionSink extends IntentRedirectionSink { private class DefaultIntentRedirectionSanitizer extends IntentRedirectionSanitizer { DefaultIntentRedirectionSanitizer() { this.getType() instanceof TypeIntent and - exists(MethodAccess ma, Method m, Guard g, boolean branch | + exists(MethodCall ma, Method m, Guard g, boolean branch | ma.getMethod() = m and m.getDeclaringType() instanceof TypeComponentName and m.hasName("getPackageName") and g.isEquality(ma, _, branch) and g.controls(this.asExpr().getBasicBlock(), branch) ) and - exists(MethodAccess ma, Method m, Guard g, boolean branch | + exists(MethodCall ma, Method m, Guard g, boolean branch | ma.getMethod() = m and m.getDeclaringType() instanceof TypeComponentName and m.hasName("getClassName") and diff --git a/java/ql/lib/semmle/code/java/security/AndroidIntentRedirectionQuery.qll b/java/ql/lib/semmle/code/java/security/AndroidIntentRedirectionQuery.qll index ed47b6df8c95..f049995b15ca 100644 --- a/java/ql/lib/semmle/code/java/security/AndroidIntentRedirectionQuery.qll +++ b/java/ql/lib/semmle/code/java/security/AndroidIntentRedirectionQuery.qll @@ -103,7 +103,7 @@ private module TaintedIntentComponentConfig implements DataFlow::ConfigSig { private module TaintedIntentComponentFlow = TaintTracking::Global; /** A call to a method that changes the component of an `Intent`. */ -private class IntentSetComponent extends MethodAccess { +private class IntentSetComponent extends MethodCall { int sinkArg; IntentSetComponent() { diff --git a/java/ql/lib/semmle/code/java/security/AndroidSensitiveCommunicationQuery.qll b/java/ql/lib/semmle/code/java/security/AndroidSensitiveCommunicationQuery.qll index e8d5a6d42d11..53adc7132c5e 100644 --- a/java/ql/lib/semmle/code/java/security/AndroidSensitiveCommunicationQuery.qll +++ b/java/ql/lib/semmle/code/java/security/AndroidSensitiveCommunicationQuery.qll @@ -20,7 +20,7 @@ private class SensitiveInfoExpr extends Expr { } private predicate maybeNullArg(Expr ex) { - exists(DataFlow::Node src, DataFlow::Node sink, MethodAccess ma | + exists(DataFlow::Node src, DataFlow::Node sink, MethodCall ma | ex = ma.getAnArgument() and sink.asExpr() = ex and src.asExpr() instanceof NullLiteral @@ -30,7 +30,7 @@ private predicate maybeNullArg(Expr ex) { } private predicate maybeEmptyArrayArg(Expr ex) { - exists(DataFlow::Node src, DataFlow::Node sink, MethodAccess ma | + exists(DataFlow::Node src, DataFlow::Node sink, MethodCall ma | ex = ma.getAnArgument() and sink.asExpr() = ex and src.asExpr().(ArrayCreationExpr).getFirstDimensionSize() = 0 @@ -43,7 +43,7 @@ private predicate maybeEmptyArrayArg(Expr ex) { * Holds if a `sendBroadcast` call doesn't specify receiver permission. */ private predicate isSensitiveBroadcastSink(DataFlow::Node sendBroadcastCallArg) { - exists(MethodAccess ma, string name | ma.getMethod().hasName(name) | + exists(MethodCall ma, string name | ma.getMethod().hasName(name) | ma.getMethod().getDeclaringType().getASourceSupertype*() instanceof TypeContext and sendBroadcastCallArg.asExpr() = ma.getAnArgument() and ( @@ -105,7 +105,7 @@ private predicate isSensitiveBroadcastSink(DataFlow::Node sendBroadcastCallArg) * Holds if `arg` is an argument in a use of a `startActivity` or `startService` method that sends an Intent to another application. */ private predicate isStartActivityOrServiceSink(DataFlow::Node arg) { - exists(MethodAccess ma, string name | ma.getMethod().hasName(name) | + exists(MethodCall ma, string name | ma.getMethod().hasName(name) | arg.asExpr() = ma.getArgument(0) and ma.getMethod().getDeclaringType().getASourceSupertype*() instanceof TypeContext and // startActivity(Intent intent) diff --git a/java/ql/lib/semmle/code/java/security/AndroidWebViewCertificateValidationQuery.qll b/java/ql/lib/semmle/code/java/security/AndroidWebViewCertificateValidationQuery.qll index 3d47f77a2bbb..8e6a9c30141f 100644 --- a/java/ql/lib/semmle/code/java/security/AndroidWebViewCertificateValidationQuery.qll +++ b/java/ql/lib/semmle/code/java/security/AndroidWebViewCertificateValidationQuery.qll @@ -15,7 +15,7 @@ class OnReceivedSslErrorMethod extends Method { } /** A call to `SslErrorHandler.proceed` */ -private class SslProceedCall extends MethodAccess { +private class SslProceedCall extends MethodCall { SslProceedCall() { this.getMethod().hasQualifiedName("android.webkit", "SslErrorHandler", "proceed") } diff --git a/java/ql/lib/semmle/code/java/security/ArbitraryApkInstallation.qll b/java/ql/lib/semmle/code/java/security/ArbitraryApkInstallation.qll index d91910b546cb..3aa59286fcd0 100644 --- a/java/ql/lib/semmle/code/java/security/ArbitraryApkInstallation.qll +++ b/java/ql/lib/semmle/code/java/security/ArbitraryApkInstallation.qll @@ -50,7 +50,7 @@ class SetDataMethod extends Method { /** A dataflow sink for the URI of an intent. */ class SetDataSink extends DataFlow::ExprNode { SetDataSink() { - exists(MethodAccess ma | + exists(MethodCall ma | this.getExpr() = ma.getQualifier() and ma.getMethod() instanceof SetDataMethod ) @@ -72,7 +72,7 @@ class UriConstructorMethod extends Method { class ExternalApkSource extends DataFlow::Node { ExternalApkSource() { sourceNode(this, "android-external-storage-dir") or - this.asExpr().(MethodAccess).getMethod() instanceof UriConstructorMethod or + this.asExpr().(MethodCall).getMethod() instanceof UriConstructorMethod or this.asExpr().(StringLiteral).getValue().matches("file://%") or this instanceof ThreatModelFlowSource } diff --git a/java/ql/lib/semmle/code/java/security/ArbitraryApkInstallationQuery.qll b/java/ql/lib/semmle/code/java/security/ArbitraryApkInstallationQuery.qll index fa3dbdb44746..be8eea879c50 100644 --- a/java/ql/lib/semmle/code/java/security/ArbitraryApkInstallationQuery.qll +++ b/java/ql/lib/semmle/code/java/security/ArbitraryApkInstallationQuery.qll @@ -13,7 +13,7 @@ module ApkInstallationConfig implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node node) { node instanceof ExternalApkSource } predicate isSink(DataFlow::Node node) { - exists(MethodAccess ma | + exists(MethodCall ma | ma.getMethod() instanceof SetDataMethod and ma.getArgument(0) = node.asExpr() and ( @@ -57,7 +57,7 @@ private module InstallPackageActionConfig implements DataFlow::StateConfigSig { node2.asExpr() = cc ) or - exists(MethodAccess ma | + exists(MethodCall ma | ma.getMethod() instanceof SetActionMethod and node1.asExpr() = ma.getArgument(0) and node2.asExpr() = ma.getQualifier() @@ -95,7 +95,7 @@ private module PackageArchiveMimeTypeConfig implements DataFlow::StateConfigSig ) { state1 instanceof MimeTypeUnset and state2 instanceof HasPackageArchiveMimeType and - exists(MethodAccess ma | + exists(MethodCall ma | ma.getQualifier() = node2.asExpr() and ( ma.getMethod() instanceof SetTypeMethod and diff --git a/java/ql/lib/semmle/code/java/security/ArithmeticCommon.qll b/java/ql/lib/semmle/code/java/security/ArithmeticCommon.qll index ab0f7afd2aa4..785dce3da7ed 100644 --- a/java/ql/lib/semmle/code/java/security/ArithmeticCommon.qll +++ b/java/ql/lib/semmle/code/java/security/ArithmeticCommon.qll @@ -35,7 +35,7 @@ private Guard sizeGuard(SsaVariable v, boolean branch, boolean upper) { branch = false and upper = true ) or - exists(MethodAccess ma | + exists(MethodCall ma | ma.getMethod() instanceof MethodAbs and ma.getArgument(0) = ssaRead(v, 0) and ( @@ -47,7 +47,7 @@ private Guard sizeGuard(SsaVariable v, boolean branch, boolean upper) { ) or // overflow test - exists(AddExpr add, RValue use, Expr pos | + exists(AddExpr add, VarRead use, Expr pos | use = ssaRead(v, 0) and add.hasOperands(use, pos) and positive(use) and @@ -67,7 +67,7 @@ private Guard sizeGuard(SsaVariable v, boolean branch, boolean upper) { result.isEquality(ssaRead(v, 0), _, branch) and (upper = true or upper = false) or - exists(MethodAccess call, Method m, int ix | + exists(MethodCall call, Method m, int ix | call = result and call.getArgument(ix) = ssaRead(v, 0) and call.getMethod().getSourceDeclaration() = m and @@ -112,7 +112,7 @@ predicate guardedLessThanSomething(Expr e) { or negative(e) or - e.(MethodAccess).getMethod() instanceof MethodMathMin + e.(MethodCall).getMethod() instanceof MethodMathMin } /** @@ -127,7 +127,7 @@ predicate guardedGreaterThanSomething(Expr e) { or positive(e) or - e.(MethodAccess).getMethod() instanceof MethodMathMax + e.(MethodCall).getMethod() instanceof MethodMathMax } /** Holds if `e` occurs in a context where it will be upcast to a wider type. */ diff --git a/java/ql/lib/semmle/code/java/security/CleartextStorageAndroidDatabaseQuery.qll b/java/ql/lib/semmle/code/java/security/CleartextStorageAndroidDatabaseQuery.qll index d995d11ce5bd..b42389a1df6e 100644 --- a/java/ql/lib/semmle/code/java/security/CleartextStorageAndroidDatabaseQuery.qll +++ b/java/ql/lib/semmle/code/java/security/CleartextStorageAndroidDatabaseQuery.qll @@ -12,9 +12,9 @@ private class LocalDatabaseCleartextStorageSink extends CleartextStorageSink { } /** The creation of an object that can be used to store data in a local database. */ -class LocalDatabaseOpenMethodAccess extends Storable, Call { - LocalDatabaseOpenMethodAccess() { - exists(Method m | this.(MethodAccess).getMethod() = m | +class LocalDatabaseOpenMethodCall extends Storable, Call { + LocalDatabaseOpenMethodCall() { + exists(Method m | this.(MethodCall).getMethod() = m | m.getDeclaringType().getASupertype*() instanceof TypeSQLiteOpenHelper and m.hasName("getWritableDatabase") or @@ -43,6 +43,9 @@ class LocalDatabaseOpenMethodAccess extends Storable, Call { } } +/** DEPRECATED: Alias for `LocalDatabaseOpenMethodCall`. */ +deprecated class LocalDatabaseOpenMethodAccess = LocalDatabaseOpenMethodCall; + /** A method that is both a database input and a database store. */ private class LocalDatabaseInputStoreMethod extends Method { LocalDatabaseInputStoreMethod() { @@ -77,7 +80,7 @@ private predicate localDatabaseInput(DataFlow::Node database, Argument input) { * either through the use of prepared statements, via the `ContentValues` class, or * directly executing a raw SQL query. */ -private predicate localDatabaseStore(DataFlow::Node database, MethodAccess store) { +private predicate localDatabaseStore(DataFlow::Node database, MethodCall store) { exists(Method m | store.getMethod() = m | m instanceof LocalDatabaseInputStoreMethod and database.asExpr() = store.getQualifier() @@ -95,7 +98,7 @@ private predicate localDatabaseStore(DataFlow::Node database, MethodAccess store private module LocalDatabaseFlowConfig implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node source) { - source.asExpr() instanceof LocalDatabaseOpenMethodAccess + source.asExpr() instanceof LocalDatabaseOpenMethodCall } predicate isSink(DataFlow::Node sink) { diff --git a/java/ql/lib/semmle/code/java/security/CleartextStorageClassQuery.qll b/java/ql/lib/semmle/code/java/security/CleartextStorageClassQuery.qll index 41e5c0608164..65e7aeb256bb 100644 --- a/java/ql/lib/semmle/code/java/security/CleartextStorageClassQuery.qll +++ b/java/ql/lib/semmle/code/java/security/CleartextStorageClassQuery.qll @@ -88,7 +88,7 @@ private module ClassStoreFlowConfig implements DataFlow::ConfigSig { private module ClassStoreFlow = DataFlow::Global; private predicate serializableStore(DataFlow::Node instance, Expr store) { - exists(MethodAccess m | + exists(MethodCall m | store = m and m.getMethod() instanceof WriteObjectMethod and instance.asExpr() = m.getArgument(0) @@ -96,7 +96,7 @@ private predicate serializableStore(DataFlow::Node instance, Expr store) { } private predicate marshallableStore(DataFlow::Node instance, Expr store) { - exists(MethodAccess m | + exists(MethodCall m | store = m and m.getMethod() instanceof JaxbMarshalMethod and instance.asExpr() = m.getArgument(0) diff --git a/java/ql/lib/semmle/code/java/security/CleartextStorageCookieQuery.qll b/java/ql/lib/semmle/code/java/security/CleartextStorageCookieQuery.qll index 59c098281f12..3e327c6dc5fe 100644 --- a/java/ql/lib/semmle/code/java/security/CleartextStorageCookieQuery.qll +++ b/java/ql/lib/semmle/code/java/security/CleartextStorageCookieQuery.qll @@ -28,7 +28,7 @@ class Cookie extends Storable, ClassInstanceExpr { } private predicate cookieStore(DataFlow::Node cookie, Expr store) { - exists(MethodAccess m, Method def | + exists(MethodCall m, Method def | m.getMethod() = def and def.getName() = "addCookie" and def.getDeclaringType().hasQualifiedName("javax.servlet.http", "HttpServletResponse") and diff --git a/java/ql/lib/semmle/code/java/security/CleartextStoragePropertiesQuery.qll b/java/ql/lib/semmle/code/java/security/CleartextStoragePropertiesQuery.qll index f262104078e1..d0531f4b1c27 100644 --- a/java/ql/lib/semmle/code/java/security/CleartextStoragePropertiesQuery.qll +++ b/java/ql/lib/semmle/code/java/security/CleartextStoragePropertiesQuery.qll @@ -7,7 +7,7 @@ import semmle.code.java.security.CleartextStorageQuery private class PropertiesCleartextStorageSink extends CleartextStorageSink { PropertiesCleartextStorageSink() { - exists(MethodAccess m | + exists(MethodCall m | m.getMethod() instanceof PropertiesSetPropertyMethod and this.asExpr() = m.getArgument(1) ) } @@ -35,7 +35,7 @@ class Properties extends Storable, ClassInstanceExpr { } private predicate propertiesInput(DataFlow::Node prop, Expr input) { - exists(MethodAccess m | + exists(MethodCall m | m.getMethod() instanceof PropertiesSetPropertyMethod and input = m.getArgument(1) and prop.asExpr() = m.getQualifier() @@ -43,7 +43,7 @@ private predicate propertiesInput(DataFlow::Node prop, Expr input) { } private predicate propertiesStore(DataFlow::Node prop, Expr store) { - exists(MethodAccess m | + exists(MethodCall m | m.getMethod() instanceof PropertiesStoreMethod and store = m and prop.asExpr() = m.getQualifier() diff --git a/java/ql/lib/semmle/code/java/security/CleartextStorageQuery.qll b/java/ql/lib/semmle/code/java/security/CleartextStorageQuery.qll index 0fdf69eb8a3c..e68398c098e9 100644 --- a/java/ql/lib/semmle/code/java/security/CleartextStorageQuery.qll +++ b/java/ql/lib/semmle/code/java/security/CleartextStorageQuery.qll @@ -65,15 +65,15 @@ private class DefaultCleartextStorageSanitizer extends CleartextStorageSanitizer * encryption (reversible and non-reversible) from both JDK and third parties, this class simply * checks method name to take a best guess to reduce false positives. */ -private class EncryptedSensitiveMethodAccess extends MethodAccess { - EncryptedSensitiveMethodAccess() { +private class EncryptedSensitiveMethodCall extends MethodCall { + EncryptedSensitiveMethodCall() { this.getMethod().getName().toLowerCase().matches(["%encrypt%", "%hash%", "%digest%"]) } } /** Flow configuration for encryption methods flowing to inputs of persistent storage. */ private module EncryptedValueFlowConfig implements DataFlow::ConfigSig { - predicate isSource(DataFlow::Node src) { src.asExpr() instanceof EncryptedSensitiveMethodAccess } + predicate isSource(DataFlow::Node src) { src.asExpr() instanceof EncryptedSensitiveMethodCall } predicate isSink(DataFlow::Node sink) { sink.asExpr() instanceof SensitiveExpr } } diff --git a/java/ql/lib/semmle/code/java/security/CleartextStorageSharedPrefsQuery.qll b/java/ql/lib/semmle/code/java/security/CleartextStorageSharedPrefsQuery.qll index 07764a251f71..39e1ffa3c75d 100644 --- a/java/ql/lib/semmle/code/java/security/CleartextStorageSharedPrefsQuery.qll +++ b/java/ql/lib/semmle/code/java/security/CleartextStorageSharedPrefsQuery.qll @@ -7,7 +7,7 @@ import semmle.code.java.security.CleartextStorageQuery private class SharedPrefsCleartextStorageSink extends CleartextStorageSink { SharedPrefsCleartextStorageSink() { - exists(MethodAccess m | + exists(MethodCall m | m.getMethod() instanceof PutSharedPreferenceMethod and this.asExpr() = m.getArgument(1) ) @@ -18,10 +18,10 @@ private class SharedPrefsCleartextStorageSink extends CleartextStorageSink { * The call to get a `SharedPreferences.Editor` object, which can set shared preferences and be * stored to the device. */ -class SharedPreferencesEditorMethodAccess extends Storable, MethodAccess { - SharedPreferencesEditorMethodAccess() { +class SharedPreferencesEditorMethodCall extends Storable, MethodCall { + SharedPreferencesEditorMethodCall() { this.getMethod() instanceof GetSharedPreferencesEditorMethod and - not DataFlow::localExprFlow(any(MethodAccess ma | + not DataFlow::localExprFlow(any(MethodCall ma | ma.getMethod() instanceof CreateEncryptedSharedPreferencesMethod ), this.getQualifier()) } @@ -43,12 +43,15 @@ class SharedPreferencesEditorMethodAccess extends Storable, MethodAccess { } } +/** DEPRECATED: Alias for `SharedPreferencesEditorMethodCall`. */ +deprecated class SharedPreferencesEditorMethodAccess = SharedPreferencesEditorMethodCall; + /** * Holds if `input` is the second argument of a setter method * called on `editor`, which is an instance of `SharedPreferences$Editor`. */ private predicate sharedPreferencesInput(DataFlow::Node editor, Expr input) { - exists(MethodAccess m | + exists(MethodCall m | m.getMethod() instanceof PutSharedPreferenceMethod and input = m.getArgument(1) and editor.asExpr() = m.getQualifier().getUnderlyingExpr() @@ -59,7 +62,7 @@ private predicate sharedPreferencesInput(DataFlow::Node editor, Expr input) { * Holds if `m` is a store method called on `editor`, * which is an instance of `SharedPreferences$Editor`. */ -private predicate sharedPreferencesStore(DataFlow::Node editor, MethodAccess m) { +private predicate sharedPreferencesStore(DataFlow::Node editor, MethodCall m) { m.getMethod() instanceof StoreSharedPreferenceMethod and editor.asExpr() = m.getQualifier().getUnderlyingExpr() } @@ -67,7 +70,7 @@ private predicate sharedPreferencesStore(DataFlow::Node editor, MethodAccess m) /** Flow from `SharedPreferences.Editor` to either a setter or a store method. */ private module SharedPreferencesFlowConfig implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node src) { - src.asExpr() instanceof SharedPreferencesEditorMethodAccess + src.asExpr() instanceof SharedPreferencesEditorMethodCall } predicate isSink(DataFlow::Node sink) { diff --git a/java/ql/lib/semmle/code/java/security/CommandArguments.qll b/java/ql/lib/semmle/code/java/security/CommandArguments.qll index 45bbe94dfc71..eb4f589ac7f7 100644 --- a/java/ql/lib/semmle/code/java/security/CommandArguments.qll +++ b/java/ql/lib/semmle/code/java/security/CommandArguments.qll @@ -68,13 +68,13 @@ private class CommandArgumentList extends SsaExplicitUpdate { } /** Gets a use of the variable for which the list could be empty. */ - private RValue getAUseBeforeFirstAdd() { + private VarRead getAUseBeforeFirstAdd() { result = this.getAFirstUse() or - exists(RValue mid | + exists(VarRead mid | mid = this.getAUseBeforeFirstAdd() and adjacentUseUse(mid, result) and - not exists(MethodAccess ma | + not exists(MethodCall ma | mid = ma.getQualifier() and ma.getMethod().hasName("add") ) @@ -84,26 +84,26 @@ private class CommandArgumentList extends SsaExplicitUpdate { /** * Gets an addition to this list, i.e. a call to an `add` or `addAll` method. */ - MethodAccess getAnAdd() { + MethodCall getAnAdd() { result.getQualifier() = this.getAUse() and result.getMethod().getName().matches("add%") } /** Gets an addition to this list which could be its first element. */ - MethodAccess getAFirstAdd() { + MethodCall getAFirstAdd() { result = this.getAnAdd() and result.getQualifier() = this.getAUseBeforeFirstAdd() } /** Gets an addition to this list which is not the first element. */ - MethodAccess getASubsequentAdd() { + MethodCall getASubsequentAdd() { result = this.getAnAdd() and not result = this.getAFirstAdd() } /** Holds if the first element of this list is a shell command. */ predicate isShell() { - exists(MethodAccess ma | ma = this.getAFirstAdd() and isShell(ma.getArgument(0))) + exists(MethodCall ma | ma = this.getAFirstAdd() and isShell(ma.getArgument(0))) } } @@ -114,7 +114,7 @@ private class ArrayOfStringType extends Array { ArrayOfStringType() { this.getElementType() instanceof TypeString } } -private predicate arrayLValue(ArrayAccess acc) { exists(Assignment a | a.getDest() = acc) } +private predicate arrayVarWrite(ArrayAccess acc) { exists(Assignment a | a.getDest() = acc) } /** * A variable that could be an array of arguments to a command. @@ -122,13 +122,13 @@ private predicate arrayLValue(ArrayAccess acc) { exists(Assignment a | a.getDest private class CommandArgumentArray extends SsaExplicitUpdate { CommandArgumentArray() { this.getSourceVariable().getType() instanceof ArrayOfStringType and - forall(ArrayAccess a | a.getArray() = this.getAUse() and arrayLValue(a) | + forall(ArrayAccess a | a.getArray() = this.getAUse() and arrayVarWrite(a) | a.getIndexExpr() instanceof CompileTimeConstantExpr ) } /** Gets an expression that is written to the given index of this array at the given use. */ - Expr getAWrite(int index, RValue use) { + Expr getAWrite(int index, VarRead use) { exists(Assignment a, ArrayAccess acc | acc.getArray() = use and use = this.getAUse() and @@ -148,7 +148,7 @@ private class CommandArgumentArray extends SsaExplicitUpdate { private class CommandArgArrayImmutableFirst extends CommandArgumentArray { CommandArgArrayImmutableFirst() { (exists(this.getAWrite(0)) or exists(firstElementOf(this.getDefiningExpr()))) and - forall(RValue use | exists(this.getAWrite(0, use)) | use = this.getAFirstUse()) + forall(VarRead use | exists(this.getAWrite(0, use)) | use = this.getAFirstUse()) } /** Gets the first element of this array. */ @@ -173,7 +173,7 @@ private Expr firstElementOf(Expr arr) { or exists(CommandArgArrayImmutableFirst caa | arr = caa.getAUse() | result = caa.getFirstElement()) or - exists(MethodAccess ma, Method m | + exists(MethodCall ma, Method m | arr = ma and ma.getMethod() = m and m.getDeclaringType().hasQualifiedName("java.util", "Arrays") and diff --git a/java/ql/lib/semmle/code/java/security/ConditionalBypassQuery.qll b/java/ql/lib/semmle/code/java/security/ConditionalBypassQuery.qll index 705e9527944e..63a931345120 100644 --- a/java/ql/lib/semmle/code/java/security/ConditionalBypassQuery.qll +++ b/java/ql/lib/semmle/code/java/security/ConditionalBypassQuery.qll @@ -11,7 +11,7 @@ import semmle.code.java.controlflow.Guards /** * Holds if `ma` is controlled by the condition expression `e`. */ -predicate conditionControlsMethod(MethodAccess ma, Expr e) { +predicate conditionControlsMethod(MethodCall ma, Expr e) { exists(ConditionBlock cb, SensitiveExecutionMethod m, boolean cond | ma.getMethod() = m and cb.controls(ma.getBasicBlock(), cond) and @@ -28,7 +28,7 @@ predicate conditionControlsMethod(MethodAccess ma, Expr e) { * `endsWith` method of the `java.lang.String` class. */ private predicate endsWithStep(DataFlow::Node node1, DataFlow::Node node2) { - exists(MethodAccess ma | + exists(MethodCall ma | ma.getMethod().getDeclaringType() instanceof TypeString and ma.getMethod().getName() = "endsWith" and ma.getQualifier() = node1.asExpr() and diff --git a/java/ql/lib/semmle/code/java/security/ControlledString.qll b/java/ql/lib/semmle/code/java/security/ControlledString.qll index 4d808f3a0a2a..c760bf14e855 100644 --- a/java/ql/lib/semmle/code/java/security/ControlledString.qll +++ b/java/ql/lib/semmle/code/java/security/ControlledString.qll @@ -35,7 +35,7 @@ private predicate controlledStringProp(Expr src, Expr dest) { exists(Variable var | var.getAnAccess() = dest | src = var.getAnAssignedValue()) or // Propagation through method parameters. - exists(Parameter param, MethodAccess call, int i | + exists(Parameter param, MethodCall call, int i | src = call.getArgument(i) and param = call.getMethod().getParameter(i) and dest = param.getAnAccess() @@ -45,7 +45,7 @@ private predicate controlledStringProp(Expr src, Expr dest) { exists(AddExpr concatOp | concatOp = dest | src = concatOp.getAnOperand()) or // `toString()` on a safe string is safe. - exists(MethodAccess toStringCall | + exists(MethodCall toStringCall | src = toStringCall.getQualifier() and toStringCall.getMethod() instanceof ToStringMethod and dest = toStringCall @@ -83,7 +83,7 @@ predicate controlledString(Expr expr) { or expr.getType() instanceof BoxedType or - exists(Method method | method = expr.(MethodAccess).getMethod() | + exists(Method method | method = expr.(MethodCall).getMethod() | method instanceof ClassNameMethod or method instanceof ClassSimpleNameMethod or boxedToString(method) diff --git a/java/ql/lib/semmle/code/java/security/Encryption.qll b/java/ql/lib/semmle/code/java/security/Encryption.qll index 28d1f8c1f499..3ed66bf4d28b 100644 --- a/java/ql/lib/semmle/code/java/security/Encryption.qll +++ b/java/ql/lib/semmle/code/java/security/Encryption.qll @@ -310,7 +310,7 @@ class JavaxCryptoCipher extends JavaxCryptoAlgoSpec { ) } - override Expr getAlgoSpec() { result = this.(MethodAccess).getArgument(0) } + override Expr getAlgoSpec() { result = this.(MethodCall).getArgument(0) } } class JavaxCryptoSecretKey extends JavaxCryptoAlgoSpec { @@ -335,7 +335,7 @@ class JavaxCryptoKeyGenerator extends JavaxCryptoAlgoSpec { ) } - override Expr getAlgoSpec() { result = this.(MethodAccess).getArgument(0) } + override Expr getAlgoSpec() { result = this.(MethodCall).getArgument(0) } } class JavaxCryptoKeyAgreement extends JavaxCryptoAlgoSpec { @@ -346,7 +346,7 @@ class JavaxCryptoKeyAgreement extends JavaxCryptoAlgoSpec { ) } - override Expr getAlgoSpec() { result = this.(MethodAccess).getArgument(0) } + override Expr getAlgoSpec() { result = this.(MethodCall).getArgument(0) } } class JavaxCryptoKeyFactory extends JavaxCryptoAlgoSpec { @@ -357,7 +357,7 @@ class JavaxCryptoKeyFactory extends JavaxCryptoAlgoSpec { ) } - override Expr getAlgoSpec() { result = this.(MethodAccess).getArgument(0) } + override Expr getAlgoSpec() { result = this.(MethodCall).getArgument(0) } } abstract class JavaSecurityAlgoSpec extends CryptoAlgoSpec { } @@ -396,7 +396,7 @@ class JavaSecurityKeyPairGenerator extends JavaSecurityAlgoSpec { ) } - override Expr getAlgoSpec() { result = this.(MethodAccess).getArgument(0) } + override Expr getAlgoSpec() { result = this.(MethodCall).getArgument(0) } } /** The Java class `java.security.AlgorithmParameterGenerator`. */ @@ -423,7 +423,7 @@ class JavaSecurityAlgoParamGenerator extends JavaSecurityAlgoSpec { ) } - override Expr getAlgoSpec() { result = this.(MethodAccess).getArgument(0) } + override Expr getAlgoSpec() { result = this.(MethodCall).getArgument(0) } } /** An implementation of the `java.security.spec.AlgorithmParameterSpec` interface. */ diff --git a/java/ql/lib/semmle/code/java/security/FileReadWrite.qll b/java/ql/lib/semmle/code/java/security/FileReadWrite.qll index dce63384b0c6..34d7ca1f2014 100644 --- a/java/ql/lib/semmle/code/java/security/FileReadWrite.qll +++ b/java/ql/lib/semmle/code/java/security/FileReadWrite.qll @@ -13,9 +13,7 @@ private predicate directFileRead(Expr fileAccess, Expr fileReadingExpr) { .hasQualifiedName("java.io", ["RandomAccessFile", "FileReader", "FileInputStream"]) ) or - exists(MethodAccess ma, Method filesMethod | - ma = fileReadingExpr and filesMethod = ma.getMethod() - | + exists(MethodCall ma, Method filesMethod | ma = fileReadingExpr and filesMethod = ma.getMethod() | ( // Identify all method calls on the `Files` class that imply that we are reading the file // represented by the first argument. diff --git a/java/ql/lib/semmle/code/java/security/FileWritable.qll b/java/ql/lib/semmle/code/java/security/FileWritable.qll index ace123db5bf9..bb5d952802d1 100644 --- a/java/ql/lib/semmle/code/java/security/FileWritable.qll +++ b/java/ql/lib/semmle/code/java/security/FileWritable.qll @@ -22,7 +22,7 @@ private EnumConstant getAContainedEnumConstant(Expr enumSetRef) { .hasQualifiedName("java.util", "Set") and ( // The set is defined inline using `EnumSet.of(...)`. - exists(MethodAccess enumSetOf | + exists(MethodCall enumSetOf | enumSetOf = enumSetRef and enumSetOf.getMethod().hasName("of") and enumSetOf @@ -41,7 +41,7 @@ private EnumConstant getAContainedEnumConstant(Expr enumSetRef) { result = getAContainedEnumConstant(enumSetAccess.getVariable().getAnAssignedValue()) or // ...or the value is added to the set. - exists(MethodAccess addToSet | + exists(MethodCall addToSet | addToSet.getQualifier() = enumSetAccess.getVariable().getAnAccess() | // Call to `add(..)` on the enum set variable. @@ -63,7 +63,7 @@ private VarAccess getFileForPathConversion(Expr pathExpr) { pathExpr.getType().(RefType).hasQualifiedName("java.nio.file", "Path") and ( // Look for conversion from `File` to `Path` using `file.toPath()`. - exists(MethodAccess fileToPath | + exists(MethodCall fileToPath | fileToPath = pathExpr and result = fileToPath.getQualifier() and fileToPath.getMethod().hasName("toPath") and @@ -71,7 +71,7 @@ private VarAccess getFileForPathConversion(Expr pathExpr) { ) or // Look for the pattern `Paths.get(file.get*Path())` for converting between a `File` and a `Path`. - exists(MethodAccess pathsGet, MethodAccess fileGetPath | + exists(MethodCall pathsGet, MethodCall fileGetPath | pathsGet = pathExpr and pathsGet.getMethod().hasName("get") and pathsGet.getMethod().getDeclaringType().hasQualifiedName("java.nio.file", "Paths") and @@ -90,7 +90,7 @@ private VarAccess getFileForPathConversion(Expr pathExpr) { */ private predicate fileSetWorldWritable(VarAccess fileAccess, Expr setWorldWritable) { // Calls to `File.setWritable(.., false)`. - exists(MethodAccess fileSetWritable | + exists(MethodCall fileSetWritable | // A call to the `setWritable` method. fileSetWritable.getMethod() instanceof SetWritable and // Where we may be setting `writable` to `true`. @@ -102,7 +102,7 @@ private predicate fileSetWorldWritable(VarAccess fileAccess, Expr setWorldWritab ) or // Calls to `Files.setPosixFilePermissions(...)`. - exists(MethodAccess setPosixPerms | + exists(MethodCall setPosixPerms | setPosixPerms = setWorldWritable and setPosixPerms.getMethod().hasName("setPosixFilePermissions") and setPosixPerms.getMethod().getDeclaringType().hasQualifiedName("java.nio.file", "Files") and diff --git a/java/ql/lib/semmle/code/java/security/FragmentInjection.qll b/java/ql/lib/semmle/code/java/security/FragmentInjection.qll index aa2a5f3dbfa3..a22fad4d85e7 100644 --- a/java/ql/lib/semmle/code/java/security/FragmentInjection.qll +++ b/java/ql/lib/semmle/code/java/security/FragmentInjection.qll @@ -50,7 +50,7 @@ private class DefaultFragmentInjectionSink extends FragmentInjectionSink { private class DefaultFragmentInjectionAdditionalTaintStep extends FragmentInjectionAdditionalTaintStep { override predicate step(DataFlow::Node n1, DataFlow::Node n2) { - exists(ReflectiveClassIdentifierMethodAccess ma | + exists(ReflectiveClassIdentifierMethodCall ma | ma.getArgument(0) = n1.asExpr() and ma = n2.asExpr() ) or @@ -59,7 +59,7 @@ private class DefaultFragmentInjectionAdditionalTaintStep extends FragmentInject ni = n2.asExpr() ) or - exists(MethodAccess ma | + exists(MethodCall ma | ma.getMethod() instanceof FragmentInstantiateMethod and ma.getArgument(1) = n1.asExpr() and ma = n2.asExpr() diff --git a/java/ql/lib/semmle/code/java/security/GroovyInjection.qll b/java/ql/lib/semmle/code/java/security/GroovyInjection.qll index b4fe2fd5e841..ea688a26f6ec 100644 --- a/java/ql/lib/semmle/code/java/security/GroovyInjection.qll +++ b/java/ql/lib/semmle/code/java/security/GroovyInjection.qll @@ -51,7 +51,7 @@ private predicate groovyCodeSourceTaintStep(DataFlow::Node fromNode, DataFlow::N * a `CompilationUnit` instance by calling `compilationUnit.addSource(..., tainted)`. */ private predicate groovyCompilationUnitTaintStep(DataFlow::Node fromNode, DataFlow::Node toNode) { - exists(MethodAccess ma, Method m | + exists(MethodCall ma, Method m | ma.getMethod() = m and m.hasName("addSource") and m.getDeclaringType() instanceof TypeGroovyCompilationUnit @@ -84,7 +84,7 @@ private predicate groovySourceUnitTaintStep(DataFlow::Node fromNode, DataFlow::N toNode.asExpr() = cie ) or - exists(MethodAccess ma, Method m | + exists(MethodCall ma, Method m | ma.getMethod() = m and m.hasName("create") and m.getDeclaringType() instanceof TypeGroovySourceUnit diff --git a/java/ql/lib/semmle/code/java/security/HardcodedCredentialsApiCallQuery.qll b/java/ql/lib/semmle/code/java/security/HardcodedCredentialsApiCallQuery.qll index 6080cd188b30..92d4f2a22aa1 100644 --- a/java/ql/lib/semmle/code/java/security/HardcodedCredentialsApiCallQuery.qll +++ b/java/ql/lib/semmle/code/java/security/HardcodedCredentialsApiCallQuery.qll @@ -24,7 +24,7 @@ deprecated class HardcodedCredentialApiCallConfiguration extends DataFlow::Confi override predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) { node1.asExpr().getType() instanceof TypeString and ( - exists(MethodAccess ma | ma.getMethod().hasName(["getBytes", "toCharArray"]) | + exists(MethodCall ma | ma.getMethod().hasName(["getBytes", "toCharArray"]) | node2.asExpr() = ma and ma.getQualifier() = node1.asExpr() ) @@ -32,7 +32,7 @@ deprecated class HardcodedCredentialApiCallConfiguration extends DataFlow::Confi // These base64 routines are usually taint propagators, and this is not a general // TaintTracking::Configuration, so we must specifically include them here // as a common transform applied to a constant before passing to a remote API. - exists(MethodAccess ma | + exists(MethodCall ma | ma.getMethod() .hasQualifiedName([ "java.util", "cn.hutool.core.codec", "org.apache.shiro.codec", @@ -51,7 +51,7 @@ deprecated class HardcodedCredentialApiCallConfiguration extends DataFlow::Confi } override predicate isBarrier(DataFlow::Node n) { - n.asExpr().(MethodAccess).getMethod() instanceof MethodSystemGetenv + n.asExpr().(MethodCall).getMethod() instanceof MethodSystemGetenv } } @@ -69,7 +69,7 @@ module HardcodedCredentialApiCallConfig implements DataFlow::ConfigSig { predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) { node1.asExpr().getType() instanceof TypeString and ( - exists(MethodAccess ma | ma.getMethod().hasName(["getBytes", "toCharArray"]) | + exists(MethodCall ma | ma.getMethod().hasName(["getBytes", "toCharArray"]) | node2.asExpr() = ma and ma.getQualifier() = node1.asExpr() ) @@ -77,7 +77,7 @@ module HardcodedCredentialApiCallConfig implements DataFlow::ConfigSig { // These base64 routines are usually taint propagators, and this is not a general // TaintTracking::Configuration, so we must specifically include them here // as a common transform applied to a constant before passing to a remote API. - exists(MethodAccess ma | + exists(MethodCall ma | ma.getMethod() .hasQualifiedName([ "java.util", "cn.hutool.core.codec", "org.apache.shiro.codec", @@ -96,7 +96,7 @@ module HardcodedCredentialApiCallConfig implements DataFlow::ConfigSig { } predicate isBarrier(DataFlow::Node n) { - n.asExpr().(MethodAccess).getMethod() instanceof MethodSystemGetenv + n.asExpr().(MethodCall).getMethod() instanceof MethodSystemGetenv } } diff --git a/java/ql/lib/semmle/code/java/security/HardcodedCredentialsComparison.qll b/java/ql/lib/semmle/code/java/security/HardcodedCredentialsComparison.qll index 3302fd7445a9..f76385ecb68a 100644 --- a/java/ql/lib/semmle/code/java/security/HardcodedCredentialsComparison.qll +++ b/java/ql/lib/semmle/code/java/security/HardcodedCredentialsComparison.qll @@ -8,16 +8,17 @@ import HardcodedCredentials /** * A call to a method that is or overrides `java.lang.Object.equals`. */ -class EqualsAccess extends MethodAccess { - EqualsAccess() { this.getMethod() instanceof EqualsMethod } +class EqualsCall extends MethodCall { + EqualsCall() { this.getMethod() instanceof EqualsMethod } } +/** DEPRECATED: Alias for `EqualsCall`. */ +deprecated class EqualsAccess = EqualsCall; + /** * Holds if `sink` compares password `p` against a hardcoded expression `source`. */ -predicate isHardcodedCredentialsComparison( - EqualsAccess sink, HardcodedExpr source, PasswordVariable p -) { +predicate isHardcodedCredentialsComparison(EqualsCall sink, HardcodedExpr source, PasswordVariable p) { source = sink.getQualifier() and p.getAnAccess() = sink.getArgument(0) or diff --git a/java/ql/lib/semmle/code/java/security/HttpsUrls.qll b/java/ql/lib/semmle/code/java/security/HttpsUrls.qll index 07435889fd9c..b56b8ba9c9f5 100644 --- a/java/ql/lib/semmle/code/java/security/HttpsUrls.qll +++ b/java/ql/lib/semmle/code/java/security/HttpsUrls.qll @@ -84,7 +84,7 @@ private predicate createUrlStep(DataFlow::Node node1, DataFlow::Node node2) { /** Method call of `HttpURLOpenMethod` */ private predicate urlOpenStep(DataFlow::Node node1, DataFlow::Node node2) { - exists(MethodAccess ma | + exists(MethodCall ma | ma.getMethod() instanceof UrlOpenConnectionMethod and node1.asExpr() = ma.getQualifier() and ma = node2.asExpr() diff --git a/java/ql/lib/semmle/code/java/security/ImplicitPendingIntents.qll b/java/ql/lib/semmle/code/java/security/ImplicitPendingIntents.qll index 41985affc0e5..f26cef372511 100644 --- a/java/ql/lib/semmle/code/java/security/ImplicitPendingIntents.qll +++ b/java/ql/lib/semmle/code/java/security/ImplicitPendingIntents.qll @@ -57,7 +57,7 @@ private class SendPendingIntent extends ImplicitPendingIntentSink { // intent redirection sinks are method calls that start Android components sinkNode(this, "intent-redirection") and // implicit intents can't be started as services since API 21 - not exists(MethodAccess ma, Method m | + not exists(MethodCall ma, Method m | ma.getMethod() = m and m.getDeclaringType().getAnAncestor() instanceof TypeContext and m.getName().matches(["start%Service%", "bindService%"]) and diff --git a/java/ql/lib/semmle/code/java/security/ImproperIntentVerificationQuery.qll b/java/ql/lib/semmle/code/java/security/ImproperIntentVerificationQuery.qll index db59c5c5291c..bca045bc8e42 100644 --- a/java/ql/lib/semmle/code/java/security/ImproperIntentVerificationQuery.qll +++ b/java/ql/lib/semmle/code/java/security/ImproperIntentVerificationQuery.qll @@ -20,7 +20,7 @@ private module VerifiedIntentConfig implements DataFlow::ConfigSig { } predicate isSink(DataFlow::Node sink) { - exists(MethodAccess ma | + exists(MethodCall ma | ma.getMethod().hasQualifiedName("android.content", "Intent", "getAction") and sink.asExpr() = ma.getQualifier() ) diff --git a/java/ql/lib/semmle/code/java/security/InsecureBasicAuth.qll b/java/ql/lib/semmle/code/java/security/InsecureBasicAuth.qll index 93722eb01e6f..df9b6bdf4a11 100644 --- a/java/ql/lib/semmle/code/java/security/InsecureBasicAuth.qll +++ b/java/ql/lib/semmle/code/java/security/InsecureBasicAuth.qll @@ -25,7 +25,7 @@ abstract class InsecureBasicAuthSink extends DataFlow::Node { } /** A default sink representing methods that set an Authorization header. */ private class DefaultInsecureBasicAuthSink extends InsecureBasicAuthSink { DefaultInsecureBasicAuthSink() { - exists(MethodAccess ma | + exists(MethodCall ma | ma.getMethod().hasName("addHeader") or ma.getMethod().hasName("setHeader") or ma.getMethod().hasName("setRequestProperty") diff --git a/java/ql/lib/semmle/code/java/security/InsecureBeanValidationQuery.qll b/java/ql/lib/semmle/code/java/security/InsecureBeanValidationQuery.qll index 4e2b85d56c2b..1ad0677ca615 100644 --- a/java/ql/lib/semmle/code/java/security/InsecureBeanValidationQuery.qll +++ b/java/ql/lib/semmle/code/java/security/InsecureBeanValidationQuery.qll @@ -19,7 +19,7 @@ private class ELMessageInterpolatorType extends RefType { /** * A method call that sets the application's default message interpolator. */ -class SetMessageInterpolatorCall extends MethodAccess { +class SetMessageInterpolatorCall extends MethodCall { SetMessageInterpolatorCall() { exists(Method m, RefType t | this.getMethod() = m and diff --git a/java/ql/lib/semmle/code/java/security/InsecureCookieQuery.qll b/java/ql/lib/semmle/code/java/security/InsecureCookieQuery.qll index aacfa09e73f0..e8c3052acdfb 100644 --- a/java/ql/lib/semmle/code/java/security/InsecureCookieQuery.qll +++ b/java/ql/lib/semmle/code/java/security/InsecureCookieQuery.qll @@ -11,14 +11,14 @@ private predicate isSafeSecureCookieSetting(Expr e) { isSecure.hasName("isSecure") and isSecure.getDeclaringType().getASourceSupertype*() instanceof ServletRequest | - e.(MethodAccess).getMethod() = isSecure + e.(MethodCall).getMethod() = isSecure ) } /** A dataflow configuration to reason about the failure to use secure cookies. */ module SecureCookieConfig implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node source) { - exists(MethodAccess ma, Method m | ma.getMethod() = m | + exists(MethodCall ma, Method m | ma.getMethod() = m | m.getDeclaringType() instanceof TypeCookie and m.getName() = "setSecure" and source.asExpr() = ma.getQualifier() and @@ -33,7 +33,7 @@ module SecureCookieConfig implements DataFlow::ConfigSig { predicate isSink(DataFlow::Node sink) { sink.asExpr() = - any(MethodAccess add | add.getMethod() instanceof ResponseAddCookieMethod).getArgument(0) + any(MethodCall add | add.getMethod() instanceof ResponseAddCookieMethod).getArgument(0) } } diff --git a/java/ql/lib/semmle/code/java/security/InsecureLdapAuth.qll b/java/ql/lib/semmle/code/java/security/InsecureLdapAuth.qll index 80007650c633..9a8cd91b1fcf 100644 --- a/java/ql/lib/semmle/code/java/security/InsecureLdapAuth.qll +++ b/java/ql/lib/semmle/code/java/security/InsecureLdapAuth.qll @@ -44,7 +44,7 @@ class InsecureLdapUrlSink extends DataFlow::Node { /** * Holds if `ma` sets `java.naming.security.authentication` (also known as `Context.SECURITY_AUTHENTICATION`) to `simple` in some `Hashtable`. */ -predicate isBasicAuthEnv(MethodAccess ma) { +predicate isBasicAuthEnv(MethodCall ma) { hasFieldValueEnv(ma, "java.naming.security.authentication", "simple") or hasFieldNameEnv(ma, "SECURITY_AUTHENTICATION", "simple") } @@ -52,7 +52,7 @@ predicate isBasicAuthEnv(MethodAccess ma) { /** * Holds if `ma` sets `java.naming.security.protocol` (also known as `Context.SECURITY_PROTOCOL`) to `ssl` in some `Hashtable`. */ -predicate isSslEnv(MethodAccess ma) { +predicate isSslEnv(MethodCall ma) { hasFieldValueEnv(ma, "java.naming.security.protocol", "ssl") or hasFieldNameEnv(ma, "SECURITY_PROTOCOL", "ssl") } @@ -60,7 +60,7 @@ predicate isSslEnv(MethodAccess ma) { /** * Holds if `ma` writes the `java.naming.provider.url` (also known as `Context.PROVIDER_URL`) key of a `Hashtable`. */ -predicate isProviderUrlSetter(MethodAccess ma) { +predicate isProviderUrlSetter(MethodCall ma) { ma.getMethod().getDeclaringType().getAnAncestor() instanceof TypeHashtable and ma.getMethod().hasName(["put", "setProperty"]) and ( @@ -103,7 +103,7 @@ private string getHostname(Expr expr) { * Holds if `ma` sets `fieldValue` to `envValue` in some `Hashtable`. */ bindingset[fieldValue, envValue] -private predicate hasFieldValueEnv(MethodAccess ma, string fieldValue, string envValue) { +private predicate hasFieldValueEnv(MethodCall ma, string fieldValue, string envValue) { // environment.put("java.naming.security.authentication", "simple") ma.getMethod().getDeclaringType().getAnAncestor() instanceof TypeHashtable and ma.getMethod().hasName(["put", "setProperty"]) and @@ -115,7 +115,7 @@ private predicate hasFieldValueEnv(MethodAccess ma, string fieldValue, string en * Holds if `ma` sets attribute name `fieldName` to `envValue` in some `Hashtable`. */ bindingset[fieldName, envValue] -private predicate hasFieldNameEnv(MethodAccess ma, string fieldName, string envValue) { +private predicate hasFieldNameEnv(MethodCall ma, string fieldName, string envValue) { // environment.put(Context.SECURITY_AUTHENTICATION, "simple") ma.getMethod().getDeclaringType().getAnAncestor() instanceof TypeHashtable and ma.getMethod().hasName(["put", "setProperty"]) and diff --git a/java/ql/lib/semmle/code/java/security/InsecureLdapAuthQuery.qll b/java/ql/lib/semmle/code/java/security/InsecureLdapAuthQuery.qll index 6fb53b769e49..498a9401071a 100644 --- a/java/ql/lib/semmle/code/java/security/InsecureLdapAuthQuery.qll +++ b/java/ql/lib/semmle/code/java/security/InsecureLdapAuthQuery.qll @@ -16,7 +16,7 @@ module InsecureLdapUrlConfig implements DataFlow::ConfigSig { /** Method call of `env.put()`. */ predicate isAdditionalFlowStep(DataFlow::Node pred, DataFlow::Node succ) { - exists(MethodAccess ma | + exists(MethodCall ma | pred.asExpr() = ma.getArgument(1) and isProviderUrlSetter(ma) and succ.asExpr() = ma.getQualifier() @@ -31,7 +31,7 @@ module InsecureLdapUrlFlow = TaintTracking::Global; */ private module BasicAuthConfig implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node src) { - exists(MethodAccess ma | + exists(MethodCall ma | isBasicAuthEnv(ma) and ma.getQualifier() = src.(DataFlow::PostUpdateNode).getPreUpdateNode().asExpr() ) @@ -47,7 +47,7 @@ module BasicAuthFlow = DataFlow::Global; */ private module RequiresSslConfig implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node src) { - exists(MethodAccess ma | + exists(MethodCall ma | isSslEnv(ma) and ma.getQualifier() = src.(DataFlow::PostUpdateNode).getPreUpdateNode().asExpr() ) diff --git a/java/ql/lib/semmle/code/java/security/InsecureTrustManager.qll b/java/ql/lib/semmle/code/java/security/InsecureTrustManager.qll index ebc8615befb7..d82f088cf155 100644 --- a/java/ql/lib/semmle/code/java/security/InsecureTrustManager.qll +++ b/java/ql/lib/semmle/code/java/security/InsecureTrustManager.qll @@ -24,7 +24,7 @@ abstract class InsecureTrustManagerSink extends DataFlow::Node { private class DefaultInsecureTrustManagerSink extends InsecureTrustManagerSink { DefaultInsecureTrustManagerSink() { - exists(MethodAccess ma, Method m | + exists(MethodCall ma, Method m | m.hasName("init") and m.getDeclaringType() instanceof SslContext and ma.getMethod() = m diff --git a/java/ql/lib/semmle/code/java/security/InsufficientKeySize.qll b/java/ql/lib/semmle/code/java/security/InsufficientKeySize.qll index b156b594a70e..949657df6540 100644 --- a/java/ql/lib/semmle/code/java/security/InsufficientKeySize.qll +++ b/java/ql/lib/semmle/code/java/security/InsufficientKeySize.qll @@ -144,7 +144,7 @@ private module Asymmetric { * A call to the `initialize` method declared in `java.security.KeyPairGenerator` * or to the `init` method declared in `java.security.AlgorithmParameterGenerator`. */ - private class KeyPairGenInit extends MethodAccess { + private class KeyPairGenInit extends MethodCall { KeyPairGenInit() { this.getMethod() instanceof KeyPairGeneratorInitMethod or this.getMethod() instanceof AlgoParamGeneratorInitMethod @@ -200,7 +200,7 @@ private module Symmetric { private int getMinKeySize() { result = minSecureKeySizeAes() } /** A call to the `init` method declared in `javax.crypto.KeyGenerator`. */ - private class KeyGenInit extends MethodAccess { + private class KeyGenInit extends MethodCall { KeyGenInit() { this.getMethod() instanceof KeyGeneratorInitMethod } /** Gets the `keysize` argument of this call. */ diff --git a/java/ql/lib/semmle/code/java/security/IntentUriPermissionManipulation.qll b/java/ql/lib/semmle/code/java/security/IntentUriPermissionManipulation.qll index fc897dcc97d8..4309af8b3c80 100644 --- a/java/ql/lib/semmle/code/java/security/IntentUriPermissionManipulation.qll +++ b/java/ql/lib/semmle/code/java/security/IntentUriPermissionManipulation.qll @@ -38,7 +38,7 @@ class IntentUriPermissionManipulationAdditionalTaintStep extends Unit { private class DefaultIntentUriPermissionManipulationSink extends IntentUriPermissionManipulationSink { DefaultIntentUriPermissionManipulationSink() { - exists(MethodAccess ma | ma.getMethod() instanceof ActivitySetResultMethod | + exists(MethodCall ma | ma.getMethod() instanceof ActivitySetResultMethod | ma.getArgument(1) = this.asExpr() ) } @@ -54,7 +54,7 @@ private class DefaultIntentUriPermissionManipulationSink extends IntentUriPermis */ private class IntentFlagsOrDataChangedSanitizer extends IntentUriPermissionManipulationSanitizer { IntentFlagsOrDataChangedSanitizer() { - exists(MethodAccess ma, Method m | + exists(MethodCall ma, Method m | ma.getMethod() = m and m.getDeclaringType() instanceof TypeIntent and this.asExpr() = ma.getQualifier() @@ -99,7 +99,7 @@ private class IntentFlagsOrDataCheckedSanitizer extends IntentUriPermissionManip * is equality-tested. */ private predicate intentFlagsOrDataChecked(Guard g, Expr intent, boolean branch) { - exists(MethodAccess ma, Method m, Expr checkedValue | + exists(MethodCall ma, Method m, Expr checkedValue | ma.getQualifier() = intent and ma.getMethod() = m and m.getDeclaringType() instanceof TypeIntent and @@ -109,9 +109,9 @@ private predicate intentFlagsOrDataChecked(Guard g, Expr intent, boolean branch) bitwiseCheck(g, branch) and checkedValue = g.(EqualityTest).getAnOperand().(AndBitwiseExpr) or - g.(MethodAccess).getMethod() instanceof EqualsMethod and + g.(MethodCall).getMethod() instanceof EqualsMethod and branch = true and - checkedValue = [g.(MethodAccess).getArgument(0), g.(MethodAccess).getQualifier()] + checkedValue = [g.(MethodCall).getArgument(0), g.(MethodCall).getQualifier()] ) } diff --git a/java/ql/lib/semmle/code/java/security/JWT.qll b/java/ql/lib/semmle/code/java/security/JWT.qll index 7056c7567f20..183495d85652 100644 --- a/java/ql/lib/semmle/code/java/security/JWT.qll +++ b/java/ql/lib/semmle/code/java/security/JWT.qll @@ -6,7 +6,7 @@ private import semmle.code.java.dataflow.DataFlow /** A method access that assigns signing keys to a JWT parser. */ class JwtParserWithInsecureParseSource extends DataFlow::Node { JwtParserWithInsecureParseSource() { - exists(MethodAccess ma, Method m | + exists(MethodCall ma, Method m | m.getDeclaringType().getAnAncestor() instanceof TypeJwtParser or m.getDeclaringType().getAnAncestor() instanceof TypeJwtParserBuilder | @@ -25,7 +25,7 @@ class JwtParserWithInsecureParseSource extends DataFlow::Node { * where the `handler` is considered insecure. */ class JwtParserWithInsecureParseSink extends DataFlow::Node { - MethodAccess insecureParseMa; + MethodCall insecureParseMa; JwtParserWithInsecureParseSink() { insecureParseMa.getQualifier() = this.asExpr() and @@ -42,7 +42,10 @@ class JwtParserWithInsecureParseSink extends DataFlow::Node { } /** Gets the method access that does the insecure parsing. */ - MethodAccess getParseMethodAccess() { result = insecureParseMa } + MethodCall getParseMethodCall() { result = insecureParseMa } + + /** DEPRECATED: Alias for `getParseMethodCall`. */ + deprecated MethodCall getParseMethodAccess() { result = this.getParseMethodCall() } } /** @@ -63,7 +66,7 @@ private class DefaultJwtParserWithInsecureParseAdditionalFlowStep extends JwtPar } /** Models the builder style of `JwtParser` and `JwtParserBuilder`. */ -private predicate jwtParserStep(Expr parser, MethodAccess ma) { +private predicate jwtParserStep(Expr parser, MethodCall ma) { ( parser.getType().(RefType).getASourceSupertype*() instanceof TypeJwtParser or parser.getType().(RefType).getASourceSupertype*() instanceof TypeJwtParserBuilder diff --git a/java/ql/lib/semmle/code/java/security/JexlInjectionQuery.qll b/java/ql/lib/semmle/code/java/security/JexlInjectionQuery.qll index 8f08eee44a45..6f3a7ad00afd 100644 --- a/java/ql/lib/semmle/code/java/security/JexlInjectionQuery.qll +++ b/java/ql/lib/semmle/code/java/security/JexlInjectionQuery.qll @@ -83,7 +83,7 @@ module JexlInjectionFlow = TaintTracking::Global; * by calling `tainted.createScript(jexlExpr)`. */ private predicate createJexlScriptStep(DataFlow::Node n1, DataFlow::Node n2) { - exists(MethodAccess ma, Method m | m = ma.getMethod() and n2.asExpr() = ma | + exists(MethodCall ma, Method m | m = ma.getMethod() and n2.asExpr() = ma | not isSafeEngine(ma.getQualifier()) and m instanceof CreateJexlScriptMethod and n1.asExpr() = ma.getArgument(0) and @@ -96,7 +96,7 @@ private predicate createJexlScriptStep(DataFlow::Node n1, DataFlow::Node n2) { * by calling `tainted.createExpression(jexlExpr)`. */ private predicate createJexlExpressionStep(DataFlow::Node n1, DataFlow::Node n2) { - exists(MethodAccess ma, Method m | m = ma.getMethod() and n2.asExpr() = ma | + exists(MethodCall ma, Method m | m = ma.getMethod() and n2.asExpr() = ma | not isSafeEngine(ma.getQualifier()) and m instanceof CreateJexlExpressionMethod and n1.asExpr() = ma.getAnArgument() and @@ -109,7 +109,7 @@ private predicate createJexlExpressionStep(DataFlow::Node n1, DataFlow::Node n2) * by calling `tainted.createTemplate(jexlExpr)`. */ private predicate createJexlTemplateStep(DataFlow::Node n1, DataFlow::Node n2) { - exists(MethodAccess ma, Method m, RefType taintType | + exists(MethodCall ma, Method m, RefType taintType | m = ma.getMethod() and n2.asExpr() = ma and taintType = n1.asExpr().getType() | not isSafeEngine(ma.getQualifier()) and @@ -131,7 +131,7 @@ private module SandboxedJexlFlowConfig implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node node) { node instanceof SandboxedJexlSource } predicate isSink(DataFlow::Node node) { - exists(MethodAccess ma, Method m | + exists(MethodCall ma, Method m | m instanceof CreateJexlScriptMethod or m instanceof CreateJexlExpressionMethod or m instanceof CreateJexlTemplateMethod @@ -152,7 +152,7 @@ private module SandboxedJexlFlow = DataFlow::Global; */ private class SandboxedJexlSource extends DataFlow::ExprNode { SandboxedJexlSource() { - exists(MethodAccess ma, Method m | m = ma.getMethod() | + exists(MethodCall ma, Method m | m = ma.getMethod() | m.getDeclaringType() instanceof JexlBuilder and m.hasName(["uberspect", "sandbox"]) and m.getReturnType() instanceof JexlBuilder and @@ -171,7 +171,7 @@ private class SandboxedJexlSource extends DataFlow::ExprNode { * Holds if `fromNode` to `toNode` is a dataflow step that creates one of the JEXL engines. */ private predicate createJexlEngineStep(DataFlow::Node fromNode, DataFlow::Node toNode) { - exists(MethodAccess ma, Method m | m = ma.getMethod() | + exists(MethodCall ma, Method m | m = ma.getMethod() | (m.getDeclaringType() instanceof JexlBuilder or m.getDeclaringType() instanceof JexlEngine) and m.hasName(["create", "createJxltEngine"]) and ma.getQualifier() = fromNode.asExpr() and diff --git a/java/ql/lib/semmle/code/java/security/JndiInjection.qll b/java/ql/lib/semmle/code/java/security/JndiInjection.qll index 6a05bbfdc2cd..d7282996057d 100644 --- a/java/ql/lib/semmle/code/java/security/JndiInjection.qll +++ b/java/ql/lib/semmle/code/java/security/JndiInjection.qll @@ -36,7 +36,7 @@ private class DefaultJndiInjectionSink extends JndiInjectionSink { */ private class ConditionedJndiInjectionSink extends JndiInjectionSink, DataFlow::ExprNode { ConditionedJndiInjectionSink() { - exists(MethodAccess ma, Method m | + exists(MethodCall ma, Method m | ma.getMethod() = m and ma.getArgument(0) = this.asExpr() and m.getDeclaringType().getASourceSupertype*() instanceof TypeLdapOperations @@ -56,7 +56,7 @@ private class ConditionedJndiInjectionSink extends JndiInjectionSink, DataFlow:: */ private class ProviderUrlJndiInjectionSink extends JndiInjectionSink, DataFlow::ExprNode { ProviderUrlJndiInjectionSink() { - exists(MethodAccess ma, Method m | + exists(MethodCall ma, Method m | ma.getMethod() = m and ma.getArgument(1) = this.getExpr() | @@ -105,7 +105,7 @@ private predicate nameStep(DataFlow::ExprNode n1, DataFlow::ExprNode n2) { * `CompoundName` by calling `new CompositeName().add(tainted)` or `new CompoundName().add(tainted)`. */ private predicate nameAddStep(DataFlow::ExprNode n1, DataFlow::ExprNode n2) { - exists(Method m, MethodAccess ma | + exists(Method m, MethodCall ma | ma.getMethod() = m and m.hasName("add") and ( @@ -134,7 +134,7 @@ private predicate jmxServiceUrlStep(DataFlow::ExprNode n1, DataFlow::ExprNode n2 * `JMXConnector` by calling `JMXConnectorFactory.newJMXConnector(tainted)`. */ private predicate jmxConnectorStep(DataFlow::ExprNode n1, DataFlow::ExprNode n2) { - exists(MethodAccess ma, Method m | n1.asExpr() = ma.getArgument(0) and n2.asExpr() = ma | + exists(MethodCall ma, Method m | n1.asExpr() = ma.getArgument(0) and n2.asExpr() = ma | ma.getMethod() = m and m.getDeclaringType() instanceof TypeJmxConnectorFactory and m.hasName("newJMXConnector") diff --git a/java/ql/lib/semmle/code/java/security/JndiInjectionQuery.qll b/java/ql/lib/semmle/code/java/security/JndiInjectionQuery.qll index cf1520b3dd58..0f97261eb4f9 100644 --- a/java/ql/lib/semmle/code/java/security/JndiInjectionQuery.qll +++ b/java/ql/lib/semmle/code/java/security/JndiInjectionQuery.qll @@ -56,7 +56,7 @@ module JndiInjectionFlow = TaintTracking::Global; */ private class UnsafeSearchControlsSink extends JndiInjectionSink { UnsafeSearchControlsSink() { - exists(MethodAccess ma | UnsafeSearchControlsFlow::flowToExpr(ma.getAnArgument()) | + exists(MethodCall ma | UnsafeSearchControlsFlow::flowToExpr(ma.getAnArgument()) | this.asExpr() = ma.getArgument(0) ) } @@ -79,7 +79,7 @@ private module UnsafeSearchControlsFlow = DataFlow::Global { /** Gets a node that is safely guarded by a method that uses the given guard check. */ DataFlow::Node getAValidatedNode() { - exists(MethodAccess ma, int pos, RValue rv | + exists(MethodCall ma, int pos, VarRead rv | validationMethod(ma.getMethod(), pos) and ma.getArgument(pos) = rv and adjacentUseUseSameVar(rv, result.asExpr()) and @@ -47,7 +47,7 @@ private module ValidationMethod { * Holds if `g` is guard that compares a path to a trusted value. */ private predicate exactPathMatchGuard(Guard g, Expr e, boolean branch) { - exists(MethodAccess ma, RefType t | + exists(MethodCall ma, RefType t | t instanceof TypeString or t instanceof TypeUri or t instanceof TypePath or @@ -84,7 +84,7 @@ private predicate localTaintFlowToPathGuard(Expr e, PathGuard g) { TaintTracking::LocalTaintFlow::hasExprFlow(e, g.getCheckedExpr()) } -private class AllowedPrefixGuard extends PathGuard instanceof MethodAccess { +private class AllowedPrefixGuard extends PathGuard instanceof MethodCall { AllowedPrefixGuard() { (isStringPrefixMatch(this) or isPathPrefixMatch(this)) and not isDisallowedWord(super.getAnArgument()) @@ -151,7 +151,7 @@ private class DotDotCheckSanitizer extends PathInjectionSanitizer { } } -private class BlockListGuard extends PathGuard instanceof MethodAccess { +private class BlockListGuard extends PathGuard instanceof MethodCall { BlockListGuard() { (isStringPartialMatch(this) or isPathPrefixMatch(this)) and isDisallowedWord(super.getAnArgument()) @@ -203,7 +203,7 @@ private class ConstantOrRegex extends Expr { } } -private predicate isStringPrefixMatch(MethodAccess ma) { +private predicate isStringPrefixMatch(MethodCall ma) { exists(Method m, RefType t | m.getDeclaringType() = t and (t instanceof TypeString or t instanceof StringsKt) and @@ -222,7 +222,7 @@ private predicate isStringPrefixMatch(MethodAccess ma) { /** * Holds if `ma` is a call to a method that checks a partial string match. */ -private predicate isStringPartialMatch(MethodAccess ma) { +private predicate isStringPartialMatch(MethodCall ma) { isStringPrefixMatch(ma) or exists(RefType t | t = ma.getMethod().getDeclaringType() | @@ -235,7 +235,7 @@ private predicate isStringPartialMatch(MethodAccess ma) { /** * Holds if `ma` is a call to a method that checks whether a path starts with a prefix. */ -private predicate isPathPrefixMatch(MethodAccess ma) { +private predicate isPathPrefixMatch(MethodCall ma) { exists(RefType t | t = ma.getMethod().getDeclaringType() | t instanceof TypePath or t instanceof FilesKt ) and @@ -251,7 +251,7 @@ private class PathTraversalGuard extends PathGuard { Expr checkedExpr; PathTraversalGuard() { - exists(MethodAccess ma, Method m, RefType t | + exists(MethodCall ma, Method m, RefType t | m = ma.getMethod() and t = m.getDeclaringType() and (t instanceof TypeString or t instanceof StringsKt) and @@ -273,14 +273,14 @@ private class PathTraversalGuard extends PathGuard { override Expr getCheckedExpr() { result = checkedExpr } boolean getBranch() { - this instanceof MethodAccess and result = false + this instanceof MethodCall and result = false or result = this.(EqualityTest).polarity() } } /** A complementary sanitizer that protects against path traversal using path normalization. */ -private class PathNormalizeSanitizer extends MethodAccess { +private class PathNormalizeSanitizer extends MethodCall { PathNormalizeSanitizer() { exists(RefType t | this.getMethod().getDeclaringType() = t | (t instanceof TypePath or t instanceof FilesKt) and @@ -297,7 +297,7 @@ private class PathNormalizeSanitizer extends MethodAccess { * This is a helper predicate to solve discrepancies between * what `getQualifier` actually gets in Java and Kotlin. */ -private Expr getVisualQualifier(MethodAccess ma) { +private Expr getVisualQualifier(MethodCall ma) { if ma.getMethod() instanceof ExtensionMethod then result = ma.getArgument(ma.getMethod().(ExtensionMethod).getExtensionReceiverParameterIndex()) @@ -310,7 +310,7 @@ private Expr getVisualQualifier(MethodAccess ma) { * what `getArgument` actually gets in Java and Kotlin. */ bindingset[argPos] -private Argument getVisualArgument(MethodAccess ma, int argPos) { +private Argument getVisualArgument(MethodCall ma, int argPos) { if ma.getMethod() instanceof ExtensionMethod then result = diff --git a/java/ql/lib/semmle/code/java/security/QueryInjection.qll b/java/ql/lib/semmle/code/java/security/QueryInjection.qll index 217d80bf1704..aa92aa16a14c 100644 --- a/java/ql/lib/semmle/code/java/security/QueryInjection.qll +++ b/java/ql/lib/semmle/code/java/security/QueryInjection.qll @@ -32,7 +32,7 @@ private class SqlInjectionSink extends QueryInjectionSink { private class PersistenceQueryInjectionSink extends QueryInjectionSink { PersistenceQueryInjectionSink() { // the query (first) argument to a `createQuery` or `createNativeQuery` method on `EntityManager` - exists(MethodAccess call, TypeEntityManager em | call.getArgument(0) = this.asExpr() | + exists(MethodCall call, TypeEntityManager em | call.getArgument(0) = this.asExpr() | call.getMethod() = em.getACreateQueryMethod() or call.getMethod() = em.getACreateNativeQueryMethod() // note: `createNamedQuery` is safe, as it takes only the query name, @@ -44,7 +44,7 @@ private class PersistenceQueryInjectionSink extends QueryInjectionSink { /** A sink for MongoDB injection vulnerabilities. */ private class MongoDbInjectionSink extends QueryInjectionSink { MongoDbInjectionSink() { - exists(MethodAccess call | + exists(MethodCall call | call.getMethod().getDeclaringType().hasQualifiedName("com.mongodb", "BasicDBObject") and call.getMethod().hasName("parse") and this.asExpr() = call.getArgument(0) @@ -59,7 +59,7 @@ private class MongoDbInjectionSink extends QueryInjectionSink { private class MongoJsonStep extends AdditionalQueryInjectionTaintStep { override predicate step(DataFlow::Node node1, DataFlow::Node node2) { - exists(MethodAccess ma | + exists(MethodCall ma | ma.getMethod().getDeclaringType().hasQualifiedName("com.mongodb.util", "JSON") and ma.getMethod().hasName("parse") and ma.getArgument(0) = node1.asExpr() and diff --git a/java/ql/lib/semmle/code/java/security/RandomDataSource.qll b/java/ql/lib/semmle/code/java/security/RandomDataSource.qll index 29c980beb5f1..7d67032e3925 100644 --- a/java/ql/lib/semmle/code/java/security/RandomDataSource.qll +++ b/java/ql/lib/semmle/code/java/security/RandomDataSource.qll @@ -7,7 +7,7 @@ import java /** * A method access that returns random data or writes random data to an argument. */ -abstract class RandomDataSource extends MethodAccess { +abstract class RandomDataSource extends MethodCall { /** * Gets the integer lower bound, inclusive, of the values returned by this call, * if applicable to this method's type and a constant bound is known. diff --git a/java/ql/lib/semmle/code/java/security/RandomQuery.qll b/java/ql/lib/semmle/code/java/security/RandomQuery.qll index b14191f4dd46..6be76411ce94 100644 --- a/java/ql/lib/semmle/code/java/security/RandomQuery.qll +++ b/java/ql/lib/semmle/code/java/security/RandomQuery.qll @@ -20,10 +20,10 @@ class GetRandomData extends StdlibRandomSource { GetRandomData() { this.getQualifier().getType() instanceof SecureRandomNumberGenerator } } -private predicate isSeeded(RValue use) { +private predicate isSeeded(VarRead use) { isSeeding(_, use) or - exists(GetRandomData da, RValue seeduse | + exists(GetRandomData da, VarRead seeduse | da.getQualifier() = seeduse and useUsePair(seeduse, use) ) @@ -51,7 +51,7 @@ private predicate predictableCalcStep(Expr e1, Expr e2) { t.hasSubtype*(cc.getConstructedType()) ) or - exists(Method m, MethodAccess ma | + exists(Method m, MethodCall ma | ma = e2 and e1 = ma.getQualifier() and m = ma.getMethod() and @@ -63,7 +63,7 @@ private predicate predictableCalcStep(Expr e1, Expr e2) { ) ) or - exists(Method m, MethodAccess ma | + exists(Method m, MethodCall ma | ma = e2 and e1 = ma.getArgument(0) and m = ma.getMethod() and @@ -76,16 +76,16 @@ private predicate predictableCalcStep(Expr e1, Expr e2) { ) } -private predicate safelySeeded(RValue use) { +private predicate safelySeeded(VarRead use) { exists(Expr arg | isSeeding(arg, use) and not PredictableSeedFlow::flowToExpr(arg) ) or - exists(GetRandomData da, RValue seeduse | + exists(GetRandomData da, VarRead seeduse | da.getQualifier() = seeduse and useUsePair(seeduse, use) | - not exists(RValue prior | useUsePair(prior, seeduse) | isSeeded(prior)) + not exists(VarRead prior | useUsePair(prior, seeduse) | isSeeded(prior)) ) } @@ -93,12 +93,12 @@ private predicate safelySeeded(RValue use) { * Holds if predictable seed `source` is used to initialise a random-number generator * used at `use`. */ -predicate unsafelySeeded(RValue use, PredictableSeedExpr source) { +predicate unsafelySeeded(VarRead use, PredictableSeedExpr source) { isSeedingSource(_, use, source) and not safelySeeded(use) } -private predicate isSeeding(Expr arg, RValue use) { +private predicate isSeeding(Expr arg, VarRead use) { exists(Expr e, VariableAssign def | def.getSource() = e and isSeedingConstruction(e, arg) @@ -107,19 +107,19 @@ private predicate isSeeding(Expr arg, RValue use) { def.getDestVar().(Field).getAnAccess() = use ) or - exists(Expr e, RValue seeduse | - e.(MethodAccess).getQualifier() = seeduse and + exists(Expr e, VarRead seeduse | + e.(MethodCall).getQualifier() = seeduse and isRandomSeeding(e, arg) and useUsePair(seeduse, use) ) } -private predicate isSeedingSource(Expr arg, RValue use, Expr source) { +private predicate isSeedingSource(Expr arg, VarRead use, Expr source) { isSeeding(arg, use) and PredictableSeedFlow::flow(DataFlow::exprNode(source), DataFlow::exprNode(arg)) } -private predicate isRandomSeeding(MethodAccess m, Expr arg) { +private predicate isRandomSeeding(MethodCall m, Expr arg) { exists(Method def | m.getMethod() = def | def.getDeclaringType() instanceof SecureRandomNumberGenerator and def.getName() = "setSeed" and @@ -139,7 +139,7 @@ private predicate isSeedingConstruction(ClassInstanceExpr c, Expr arg) { */ class PredictableSeedExpr extends Expr { PredictableSeedExpr() { - this.(MethodAccess).getCallee() instanceof ReturnsPredictableExpr + this.(MethodCall).getCallee() instanceof ReturnsPredictableExpr or this instanceof CompileTimeConstantExpr or diff --git a/java/ql/lib/semmle/code/java/security/RequestForgery.qll b/java/ql/lib/semmle/code/java/security/RequestForgery.qll index 0eeea1c2afd4..a01f354953bc 100644 --- a/java/ql/lib/semmle/code/java/security/RequestForgery.qll +++ b/java/ql/lib/semmle/code/java/security/RequestForgery.qll @@ -37,7 +37,7 @@ private class DefaultRequestForgeryAdditionalTaintStep extends RequestForgeryAdd private class TypePropertiesRequestForgeryAdditionalTaintStep extends RequestForgeryAdditionalTaintStep { override predicate propagatesTaint(DataFlow::Node pred, DataFlow::Node succ) { - exists(MethodAccess ma | + exists(MethodCall ma | // Properties props = new Properties(); // props.setProperty("jdbcUrl", tainted); // Propagate tainted value to the qualifier `props` diff --git a/java/ql/lib/semmle/code/java/security/RequestForgeryConfig.qll b/java/ql/lib/semmle/code/java/security/RequestForgeryConfig.qll index bfaac0d99191..a26245ae9cff 100644 --- a/java/ql/lib/semmle/code/java/security/RequestForgeryConfig.qll +++ b/java/ql/lib/semmle/code/java/security/RequestForgeryConfig.qll @@ -20,7 +20,7 @@ deprecated class RequestForgeryConfiguration extends TaintTracking::Configuratio // Exclude results of remote HTTP requests: fetching something else based on that result // is no worse than following a redirect returned by the remote server, and typically // we're requesting a resource via https which we trust to only send us to safe URLs. - not source.asExpr().(MethodAccess).getCallee() instanceof UrlConnectionGetInputStreamMethod + not source.asExpr().(MethodCall).getCallee() instanceof UrlConnectionGetInputStreamMethod } override predicate isSink(DataFlow::Node sink) { sink instanceof RequestForgerySink } @@ -41,7 +41,7 @@ module RequestForgeryConfig implements DataFlow::ConfigSig { // Exclude results of remote HTTP requests: fetching something else based on that result // is no worse than following a redirect returned by the remote server, and typically // we're requesting a resource via https which we trust to only send us to safe URLs. - not source.asExpr().(MethodAccess).getCallee() instanceof UrlConnectionGetInputStreamMethod + not source.asExpr().(MethodCall).getCallee() instanceof UrlConnectionGetInputStreamMethod } predicate isSink(DataFlow::Node sink) { sink instanceof RequestForgerySink } diff --git a/java/ql/lib/semmle/code/java/security/ResponseSplitting.qll b/java/ql/lib/semmle/code/java/security/ResponseSplitting.qll index 2e2033443a5c..340f696db622 100644 --- a/java/ql/lib/semmle/code/java/security/ResponseSplitting.qll +++ b/java/ql/lib/semmle/code/java/security/ResponseSplitting.qll @@ -20,7 +20,7 @@ abstract class SafeHeaderSplittingSource extends DataFlow::Node instanceof Remot /** A default source that introduces data considered safe to use by a header splitting source. */ private class DefaultSafeHeaderSplittingSource extends SafeHeaderSplittingSource { DefaultSafeHeaderSplittingSource() { - this.asExpr().(MethodAccess).getMethod() instanceof HttpServletRequestGetHeaderMethod or - this.asExpr().(MethodAccess).getMethod() instanceof CookieGetNameMethod + this.asExpr().(MethodCall).getMethod() instanceof HttpServletRequestGetHeaderMethod or + this.asExpr().(MethodCall).getMethod() instanceof CookieGetNameMethod } } diff --git a/java/ql/lib/semmle/code/java/security/ResponseSplittingLocalQuery.qll b/java/ql/lib/semmle/code/java/security/ResponseSplittingLocalQuery.qll index a39c213502a7..23816caa1f85 100644 --- a/java/ql/lib/semmle/code/java/security/ResponseSplittingLocalQuery.qll +++ b/java/ql/lib/semmle/code/java/security/ResponseSplittingLocalQuery.qll @@ -17,7 +17,7 @@ module ResponseSplittingLocalConfig implements DataFlow::ConfigSig { or node.getType() instanceof BoxedType or - exists(MethodAccess ma, string methodName, CompileTimeConstantExpr target | + exists(MethodCall ma, string methodName, CompileTimeConstantExpr target | node.asExpr() = ma and ma.getMethod().hasQualifiedName("java.lang", "String", methodName) and target = ma.getArgument(0) and diff --git a/java/ql/lib/semmle/code/java/security/ResponseSplittingQuery.qll b/java/ql/lib/semmle/code/java/security/ResponseSplittingQuery.qll index 5cc7422e787e..87613795b85c 100644 --- a/java/ql/lib/semmle/code/java/security/ResponseSplittingQuery.qll +++ b/java/ql/lib/semmle/code/java/security/ResponseSplittingQuery.qll @@ -20,7 +20,7 @@ module ResponseSplittingConfig implements DataFlow::ConfigSig { or node.getType() instanceof BoxedType or - exists(MethodAccess ma, string methodName, CompileTimeConstantExpr target | + exists(MethodCall ma, string methodName, CompileTimeConstantExpr target | node.asExpr() = ma and ma.getMethod().hasQualifiedName("java.lang", "String", methodName) and target = ma.getArgument(0) and diff --git a/java/ql/lib/semmle/code/java/security/SecurityFlag.qll b/java/ql/lib/semmle/code/java/security/SecurityFlag.qll index e13912fe7c59..dab5d52bcb20 100644 --- a/java/ql/lib/semmle/code/java/security/SecurityFlag.qll +++ b/java/ql/lib/semmle/code/java/security/SecurityFlag.qll @@ -37,7 +37,7 @@ abstract class FlagKind extends string { or exists(StringLiteral s | s.getValue() = this.getAFlagName() | flag.asExpr() = s) or - exists(MethodAccess ma | ma.getMethod().getName() = this.getAFlagName() | + exists(MethodCall ma | ma.getMethod().getName() = this.getAFlagName() | flag.asExpr() = ma and ma.getType() instanceof FlagType ) @@ -83,11 +83,11 @@ private class FlagType extends Type { private predicate flagFlowStep(DataFlow::Node node1, DataFlow::Node node2) { DataFlow::localFlowStep(node1, node2) or - exists(MethodAccess ma | ma.getMethod() = any(EnvReadMethod m) | + exists(MethodCall ma | ma.getMethod() = any(EnvReadMethod m) | ma = node2.asExpr() and ma.getAnArgument() = node1.asExpr() ) or - exists(MethodAccess ma | + exists(MethodCall ma | ma.getMethod().hasName("parseBoolean") and ma.getMethod().getDeclaringType().hasQualifiedName("java.lang", "Boolean") | diff --git a/java/ql/lib/semmle/code/java/security/SensitiveActions.qll b/java/ql/lib/semmle/code/java/security/SensitiveActions.qll index e6d00bf870b6..4ce531d556a4 100644 --- a/java/ql/lib/semmle/code/java/security/SensitiveActions.qll +++ b/java/ql/lib/semmle/code/java/security/SensitiveActions.qll @@ -39,8 +39,8 @@ string getCommonSensitiveInfoRegex() { abstract class SensitiveExpr extends Expr { } /** A method access that might produce sensitive data. */ -class SensitiveMethodAccess extends SensitiveExpr, MethodAccess { - SensitiveMethodAccess() { +class SensitiveMethodCall extends SensitiveExpr, MethodCall { + SensitiveMethodCall() { this.getMethod() instanceof SensitiveDataMethod or // This is particularly to pick up methods with an argument like "password", which @@ -52,6 +52,9 @@ class SensitiveMethodAccess extends SensitiveExpr, MethodAccess { } } +/** DEPRECATED: Alias for `SensitiveMethodCall`. */ +deprecated class SensitiveMethodAccess = SensitiveMethodCall; + /** Access to a variable that might contain sensitive data. */ class SensitiveVarAccess extends SensitiveExpr, VarAccess { SensitiveVarAccess() { diff --git a/java/ql/lib/semmle/code/java/security/SensitiveKeyboardCacheQuery.qll b/java/ql/lib/semmle/code/java/security/SensitiveKeyboardCacheQuery.qll index 2a41d2da08c2..498a746a30a6 100644 --- a/java/ql/lib/semmle/code/java/security/SensitiveKeyboardCacheQuery.qll +++ b/java/ql/lib/semmle/code/java/security/SensitiveKeyboardCacheQuery.qll @@ -56,7 +56,7 @@ private class FindViewMethod extends Method { } /** Gets a use of the view that has the given id. */ -private MethodAccess getAUseOfViewWithId(string id) { +private MethodCall getAUseOfViewWithId(string id) { exists(string name, NestedClass r_id, Field id_field | id = "@+id/" + name and result.getMethod() instanceof FindViewMethod and @@ -71,7 +71,7 @@ private MethodAccess getAUseOfViewWithId(string id) { /** Gets the argument of a use of `setInputType` called on the view with the given id. */ private Argument setInputTypeForId(string id) { - exists(MethodAccess setInputType | + exists(MethodCall setInputType | setInputType.getMethod().hasQualifiedName("android.widget", "TextView", "setInputType") and DataFlow::localExprFlow(getAUseOfViewWithId(id), setInputType.getQualifier()) and result = setInputType.getArgument(0) diff --git a/java/ql/lib/semmle/code/java/security/SensitiveResultReceiverQuery.qll b/java/ql/lib/semmle/code/java/security/SensitiveResultReceiverQuery.qll index 0f3526bfd7f9..63d6d88d83cb 100644 --- a/java/ql/lib/semmle/code/java/security/SensitiveResultReceiverQuery.qll +++ b/java/ql/lib/semmle/code/java/security/SensitiveResultReceiverQuery.qll @@ -5,7 +5,7 @@ import semmle.code.java.dataflow.TaintTracking import semmle.code.java.dataflow.FlowSources import semmle.code.java.security.SensitiveActions -private class ResultReceiverSendCall extends MethodAccess { +private class ResultReceiverSendCall extends MethodCall { ResultReceiverSendCall() { this.getMethod() .getASourceOverriddenMethod*() diff --git a/java/ql/lib/semmle/code/java/security/SpelInjection.qll b/java/ql/lib/semmle/code/java/security/SpelInjection.qll index bed4d313ff6a..1aed2049afe4 100644 --- a/java/ql/lib/semmle/code/java/security/SpelInjection.qll +++ b/java/ql/lib/semmle/code/java/security/SpelInjection.qll @@ -33,7 +33,7 @@ private class DefaultSpelExpressionInjectionAdditionalTaintStep extends SpelExpr * by calling `parser.parseExpression(tainted)`. */ private predicate expressionParsingStep(DataFlow::Node node1, DataFlow::Node node2) { - exists(MethodAccess ma, Method m | ma.getMethod() = m | + exists(MethodCall ma, Method m | ma.getMethod() = m | m.getDeclaringType().getAnAncestor() instanceof ExpressionParser and m.hasName(["parseExpression", "parseRaw"]) and ma.getAnArgument() = node1.asExpr() and diff --git a/java/ql/lib/semmle/code/java/security/SpelInjectionQuery.qll b/java/ql/lib/semmle/code/java/security/SpelInjectionQuery.qll index b1a17e0fdd66..cbd79c65d256 100644 --- a/java/ql/lib/semmle/code/java/security/SpelInjectionQuery.qll +++ b/java/ql/lib/semmle/code/java/security/SpelInjectionQuery.qll @@ -44,7 +44,7 @@ module SpelInjectionFlow = TaintTracking::Global; /** Default sink for SpEL injection vulnerabilities. */ private class DefaultSpelExpressionEvaluationSink extends SpelExpressionEvaluationSink { DefaultSpelExpressionEvaluationSink() { - exists(MethodAccess ma | + exists(MethodCall ma | ma.getMethod() instanceof ExpressionEvaluationMethod and ma.getQualifier() = this.asExpr() and not SafeEvaluationContextFlow::flowToExpr(ma.getArgument(0)) @@ -59,7 +59,7 @@ private module SafeEvaluationContextFlowConfig implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node source) { source instanceof SafeContextSource } predicate isSink(DataFlow::Node sink) { - exists(MethodAccess ma | + exists(MethodCall ma | ma.getMethod() instanceof ExpressionEvaluationMethod and ma.getArgument(0) = sink.asExpr() ) @@ -95,7 +95,7 @@ private predicate isSimpleEvaluationContextConstructorCall(Expr expr) { * for instance, `SimpleEvaluationContext.forReadWriteDataBinding().build()`. */ private predicate isSimpleEvaluationContextBuilderCall(Expr expr) { - exists(MethodAccess ma, Method m | ma.getMethod() = m | + exists(MethodCall ma, Method m | ma.getMethod() = m | m.getDeclaringType() instanceof SimpleEvaluationContextBuilder and m.hasName("build") and ma = expr diff --git a/java/ql/lib/semmle/code/java/security/SpringCsrfProtection.qll b/java/ql/lib/semmle/code/java/security/SpringCsrfProtection.qll index bc25f167327f..cba95d4454d7 100644 --- a/java/ql/lib/semmle/code/java/security/SpringCsrfProtection.qll +++ b/java/ql/lib/semmle/code/java/security/SpringCsrfProtection.qll @@ -3,7 +3,7 @@ import java /** Holds if `call` disables CSRF protection in Spring. */ -predicate disablesSpringCsrfProtection(MethodAccess call) { +predicate disablesSpringCsrfProtection(MethodCall call) { call.getMethod().hasName("disable") and call.getReceiverType() .hasQualifiedName("org.springframework.security.config.annotation.web.configurers", diff --git a/java/ql/lib/semmle/code/java/security/SqlConcatenatedLib.qll b/java/ql/lib/semmle/code/java/security/SqlConcatenatedLib.qll index 21a3298cd383..5d3b1c803d22 100644 --- a/java/ql/lib/semmle/code/java/security/SqlConcatenatedLib.qll +++ b/java/ql/lib/semmle/code/java/security/SqlConcatenatedLib.qll @@ -29,13 +29,13 @@ predicate builtFromUncontrolledConcat(Expr expr, Expr uncontrolled) { */ predicate uncontrolledStringBuilderQuery(StringBuilderVar sbv, Expr uncontrolled) { // A single append that has a problematic concatenation. - exists(MethodAccess append | + exists(MethodCall append | append = sbv.getAnAppend() and builtFromUncontrolledConcat(append.getArgument(0), uncontrolled) ) or // Two calls to append, one ending in a quote, the next being uncontrolled. - exists(MethodAccess quoteAppend, MethodAccess uncontrolledAppend | + exists(MethodCall quoteAppend, MethodCall uncontrolledAppend | sbv.getAnAppend() = quoteAppend and endsInQuote(quoteAppend.getArgument(0)) and sbv.getNextAppend(quoteAppend) = uncontrolledAppend and diff --git a/java/ql/lib/semmle/code/java/security/StackTraceExposureQuery.qll b/java/ql/lib/semmle/code/java/security/StackTraceExposureQuery.qll index f478ac4815e9..dba9492d137b 100644 --- a/java/ql/lib/semmle/code/java/security/StackTraceExposureQuery.qll +++ b/java/ql/lib/semmle/code/java/security/StackTraceExposureQuery.qll @@ -22,7 +22,7 @@ private module ServletWriterSourceToPrintStackTraceMethodFlowConfig implements D predicate isSource(DataFlow::Node src) { src.asExpr() instanceof XssVulnerableWriterSource } predicate isSink(DataFlow::Node sink) { - exists(MethodAccess ma | + exists(MethodCall ma | sink.asExpr() = ma.getAnArgument() and ma.getMethod() instanceof PrintStackTraceMethod ) } @@ -35,7 +35,7 @@ private module ServletWriterSourceToPrintStackTraceMethodFlow = * A call that uses `Throwable.printStackTrace()` on a stream that is connected * to external output. */ -private predicate printsStackToWriter(MethodAccess call) { +private predicate printsStackToWriter(MethodCall call) { exists(PrintStackTraceMethod printStackTrace | call.getMethod() = printStackTrace and ServletWriterSourceToPrintStackTraceMethodFlow::flowToExpr(call.getAnArgument()) @@ -56,8 +56,8 @@ private predicate printWriterOnStringWriter(Expr printWriter, Variable stringWri ) } -private predicate stackTraceExpr(Expr exception, MethodAccess stackTraceString) { - exists(Expr printWriter, Variable stringWriterVar, MethodAccess printStackCall | +private predicate stackTraceExpr(Expr exception, MethodCall stackTraceString) { + exists(Expr printWriter, Variable stringWriterVar, MethodCall printStackCall | printWriterOnStringWriter(printWriter, stringWriterVar) and printStackCall.getMethod() instanceof PrintStackTraceMethod and printStackCall.getAnArgument() = printWriter and @@ -79,7 +79,7 @@ private module StackTraceStringToHttpResponseSinkFlow = /** * Holds if `call` writes the data of `stackTrace` to an external stream. */ -predicate printsStackExternally(MethodAccess call, Expr stackTrace) { +predicate printsStackExternally(MethodCall call, Expr stackTrace) { printsStackToWriter(call) and call.getQualifier() = stackTrace and not call.getQualifier() instanceof SuperAccess @@ -89,7 +89,7 @@ predicate printsStackExternally(MethodAccess call, Expr stackTrace) { * Holds if `stackTrace` is a stringified stack trace which flows to an external sink. */ predicate stringifiedStackFlowsExternally(DataFlow::Node externalExpr, Expr stackTrace) { - exists(MethodAccess stackTraceString | + exists(MethodCall stackTraceString | stackTraceExpr(stackTrace, stackTraceString) and StackTraceStringToHttpResponseSinkFlow::flow(DataFlow::exprNode(stackTraceString), externalExpr) ) @@ -97,7 +97,7 @@ predicate stringifiedStackFlowsExternally(DataFlow::Node externalExpr, Expr stac private class GetMessageFlowSource extends DataFlow::Node { GetMessageFlowSource() { - exists(Method method | this.asExpr().(MethodAccess).getMethod() = method | + exists(Method method | this.asExpr().(MethodCall).getMethod() = method | method.hasName("getMessage") and method.hasNoParameters() and method.getDeclaringType().hasQualifiedName("java.lang", "Throwable") diff --git a/java/ql/lib/semmle/code/java/security/StaticInitializationVectorQuery.qll b/java/ql/lib/semmle/code/java/security/StaticInitializationVectorQuery.qll index 673cfc5d7b1c..ecdc1daaffcf 100644 --- a/java/ql/lib/semmle/code/java/security/StaticInitializationVectorQuery.qll +++ b/java/ql/lib/semmle/code/java/security/StaticInitializationVectorQuery.qll @@ -43,13 +43,13 @@ private class ArrayUpdate extends Expr { not assign.getSource() instanceof CompileTimeConstantExpr ) or - exists(StaticMethodAccess ma | + exists(StaticMethodCall ma | ma.getMethod().hasQualifiedName("java.lang", "System", "arraycopy") and ma = this and ma.getArgument(2) = array ) or - exists(MethodAccess ma, Method m | + exists(MethodCall ma, Method m | m = ma.getMethod() and ma = this and ma.getArgument(0) = array @@ -64,7 +64,7 @@ private class ArrayUpdate extends Expr { m.getAnOverride*().hasQualifiedName("org.bouncycastle.crypto", "Digest", "doFinal") ) or - exists(MethodAccess ma, Method m | + exists(MethodCall ma, Method m | m = ma.getMethod() and ma = this and ma.getArgument(1) = array diff --git a/java/ql/lib/semmle/code/java/security/TaintedPermissionsCheckQuery.qll b/java/ql/lib/semmle/code/java/security/TaintedPermissionsCheckQuery.qll index e403a8b60a7f..92aba6dfa04c 100644 --- a/java/ql/lib/semmle/code/java/security/TaintedPermissionsCheckQuery.qll +++ b/java/ql/lib/semmle/code/java/security/TaintedPermissionsCheckQuery.qll @@ -28,8 +28,8 @@ abstract class PermissionsConstruction extends Top { abstract Expr getInput(); } -private class PermissionsCheckMethodAccess extends MethodAccess, PermissionsConstruction { - PermissionsCheckMethodAccess() { +private class PermissionsCheckMethodCall extends MethodCall, PermissionsConstruction { + PermissionsCheckMethodCall() { exists(Method m | m = this.getMethod() | m.getDeclaringType() instanceof TypeShiroSubject and m.getName() = "isPermitted" diff --git a/java/ql/lib/semmle/code/java/security/TempDirLocalInformationDisclosureQuery.qll b/java/ql/lib/semmle/code/java/security/TempDirLocalInformationDisclosureQuery.qll index d5cf900343b5..843db3b5934b 100644 --- a/java/ql/lib/semmle/code/java/security/TempDirLocalInformationDisclosureQuery.qll +++ b/java/ql/lib/semmle/code/java/security/TempDirLocalInformationDisclosureQuery.qll @@ -37,7 +37,7 @@ abstract private class FileCreationSink extends DataFlow::Node { } */ private class FileFileCreationSink extends FileCreationSink { FileFileCreationSink() { - exists(MethodAccess ma | + exists(MethodCall ma | ma.getMethod() instanceof MethodFileSystemFileCreation and ma.getQualifier() = this.asExpr() ) @@ -50,7 +50,7 @@ private class FileFileCreationSink extends FileCreationSink { */ private class FilesFileCreationSink extends FileCreationSink { FilesFileCreationSink() { - exists(FilesVulnerableCreationMethodAccess ma | ma.getArgument(0) = this.asExpr()) + exists(FilesVulnerableCreationMethodCall ma | ma.getArgument(0) = this.asExpr()) } } @@ -58,8 +58,8 @@ private class FilesFileCreationSink extends FileCreationSink { * A call to a `Files` method that create files/directories without explicitly * setting the newly-created file or directory's permissions. */ -private class FilesVulnerableCreationMethodAccess extends MethodAccess { - FilesVulnerableCreationMethodAccess() { +private class FilesVulnerableCreationMethodCall extends MethodCall { + FilesVulnerableCreationMethodCall() { exists(Method m | m = this.getMethod() and m.getDeclaringType().hasQualifiedName("java.nio.file", "Files") @@ -80,8 +80,8 @@ private class FilesVulnerableCreationMethodAccess extends MethodAccess { * We can safely assume that any calls to these methods with explicit `PosixFilePermissions.asFileAttribute` * contains a certain level of intentionality behind it. */ -private class FilesSanitizingCreationMethodAccess extends MethodAccess { - FilesSanitizingCreationMethodAccess() { +private class FilesSanitizingCreationMethodCall extends MethodCall { + FilesSanitizingCreationMethodCall() { exists(Method m | m = this.getMethod() and m.getDeclaringType().hasQualifiedName("java.nio.file", "Files") @@ -98,7 +98,7 @@ private class FilesSanitizingCreationMethodAccess extends MethodAccess { */ private class FileCreateTempFileSink extends FileCreationSink { FileCreateTempFileSink() { - exists(MethodAccess ma | + exists(MethodCall ma | ma.getMethod() instanceof MethodFileCreateTempFile and ma.getArgument(2) = this.asExpr() ) } @@ -138,8 +138,8 @@ module TempDirSystemGetPropertyToCreateConfig implements DataFlow::ConfigSig { } predicate isBarrier(DataFlow::Node sanitizer) { - exists(FilesSanitizingCreationMethodAccess sanitisingMethodAccess | - sanitizer.asExpr() = sanitisingMethodAccess.getArgument(0) + exists(FilesSanitizingCreationMethodCall sanitisingMethodCall | + sanitizer.asExpr() = sanitisingMethodCall.getArgument(0) ) or sanitizer instanceof WindowsOsSanitizer @@ -173,7 +173,7 @@ module TempDirSystemGetPropertyDirectlyToMkdirConfig implements DataFlow::Config } predicate isSink(DataFlow::Node node) { - exists(MethodAccess ma | ma.getMethod() instanceof MethodFileDirectoryCreation | + exists(MethodCall ma | ma.getMethod() instanceof MethodFileDirectoryCreation | ma.getQualifier() = node.asExpr() ) } @@ -200,9 +200,9 @@ module TempDirSystemGetPropertyDirectlyToMkdir = // Begin configuration for tracking single-method calls that are vulnerable. // /** - * A `MethodAccess` against a method that creates a temporary file or directory in a shared temporary directory. + * A `MethodCall` against a method that creates a temporary file or directory in a shared temporary directory. */ -abstract class MethodAccessInsecureFileCreation extends MethodAccess { +abstract class MethodCallInsecureFileCreation extends MethodCall { /** * Gets the type of entity created (e.g. `file`, `directory`, ...). */ @@ -214,11 +214,14 @@ abstract class MethodAccessInsecureFileCreation extends MethodAccess { DataFlow::Node getNode() { result.asExpr() = this } } +/** DEPRECATED: Alias for `MethodCallInsecureFileCreation`. */ +deprecated class MethodAccessInsecureFileCreation = MethodCallInsecureFileCreation; + /** * An insecure call to `java.io.File.createTempFile`. */ -class MethodAccessInsecureFileCreateTempFile extends MethodAccessInsecureFileCreation { - MethodAccessInsecureFileCreateTempFile() { +class MethodCallInsecureFileCreateTempFile extends MethodCallInsecureFileCreation { + MethodCallInsecureFileCreateTempFile() { this.getMethod() instanceof MethodFileCreateTempFile and ( // `File.createTempFile(string, string)` always uses the default temporary directory @@ -232,6 +235,9 @@ class MethodAccessInsecureFileCreateTempFile extends MethodAccessInsecureFileCre override string getFileSystemEntityType() { result = "file" } } +/** DEPRECATED: Alias for `MethodCallInsecureFileCreateTempFile`. */ +deprecated class MethodAccessInsecureFileCreateTempFile = MethodCallInsecureFileCreateTempFile; + /** * The `com.google.common.io.Files.createTempDir` method. */ @@ -245,10 +251,14 @@ class MethodGuavaFilesCreateTempFile extends Method { /** * A call to the `com.google.common.io.Files.createTempDir` method. */ -class MethodAccessInsecureGuavaFilesCreateTempFile extends MethodAccessInsecureFileCreation { - MethodAccessInsecureGuavaFilesCreateTempFile() { +class MethodCallInsecureGuavaFilesCreateTempFile extends MethodCallInsecureFileCreation { + MethodCallInsecureGuavaFilesCreateTempFile() { this.getMethod() instanceof MethodGuavaFilesCreateTempFile } override string getFileSystemEntityType() { result = "directory" } } + +/** DEPRECATED: Alias for `MethodCallInsecureGuavaFilesCreateTempFile`. */ +deprecated class MethodAccessInsecureGuavaFilesCreateTempFile = + MethodCallInsecureGuavaFilesCreateTempFile; diff --git a/java/ql/lib/semmle/code/java/security/TempDirUtils.qll b/java/ql/lib/semmle/code/java/security/TempDirUtils.qll index 5e015c9abecd..33b6c46b916c 100644 --- a/java/ql/lib/semmle/code/java/security/TempDirUtils.qll +++ b/java/ql/lib/semmle/code/java/security/TempDirUtils.qll @@ -38,8 +38,8 @@ predicate isFileConstructorArgument(Expr expSource, Expr exprDest, int paramCoun /** * A method call to `java.io.File::setReadable`. */ -private class FileSetRedableMethodAccess extends MethodAccess { - FileSetRedableMethodAccess() { +private class FileSetRedableMethodCall extends MethodCall { + FileSetRedableMethodCall() { exists(Method m | this.getMethod() = m | m.getDeclaringType() instanceof TypeFile and m.hasName("setReadable") @@ -67,7 +67,7 @@ private class FileSetRedableMethodAccess extends MethodAccess { * `setReadable(false, false)`, then `setRedabale(true, true)`. */ predicate isPermissionsProtectedTempDirUse(DataFlow::Node sink) { - exists(FileSetRedableMethodAccess setReadable1, FileSetRedableMethodAccess setReadable2 | + exists(FileSetRedableMethodCall setReadable1, FileSetRedableMethodCall setReadable2 | setReadable1.isCallWithArguments(false, false) and setReadable2.isCallWithArguments(true, true) | diff --git a/java/ql/lib/semmle/code/java/security/TrustBoundaryViolationQuery.qll b/java/ql/lib/semmle/code/java/security/TrustBoundaryViolationQuery.qll index 69ea9f4bcaed..fecd7e593a65 100644 --- a/java/ql/lib/semmle/code/java/security/TrustBoundaryViolationQuery.qll +++ b/java/ql/lib/semmle/code/java/security/TrustBoundaryViolationQuery.qll @@ -33,7 +33,7 @@ abstract class TrustBoundaryValidationSanitizer extends DataFlow::Node { } private class EsapiValidatedInputSanitizer extends TrustBoundaryValidationSanitizer { EsapiValidatedInputSanitizer() { this = DataFlow::BarrierGuard::getABarrierNode() or - this.asExpr().(MethodAccess).getMethod() instanceof EsapiGetValidMethod + this.asExpr().(MethodCall).getMethod() instanceof EsapiGetValidMethod } } @@ -42,7 +42,7 @@ private class EsapiValidatedInputSanitizer extends TrustBoundaryValidationSaniti */ private predicate esapiIsValidData(Guard g, Expr e, boolean branch) { branch = true and - exists(MethodAccess ma | ma.getMethod() instanceof EsapiIsValidMethod | + exists(MethodCall ma | ma.getMethod() instanceof EsapiIsValidMethod | g = ma and e = ma.getArgument(1) ) diff --git a/java/ql/lib/semmle/code/java/security/UnsafeAndroidAccess.qll b/java/ql/lib/semmle/code/java/security/UnsafeAndroidAccess.qll index 9a85a7714064..499475cff3ec 100644 --- a/java/ql/lib/semmle/code/java/security/UnsafeAndroidAccess.qll +++ b/java/ql/lib/semmle/code/java/security/UnsafeAndroidAccess.qll @@ -88,7 +88,7 @@ private predicate applyReceiverVariable(Parameter p, Variable v) { * with `urlArg` as its first argument. */ private predicate webViewLoadUrl(Argument urlArg, WebViewRef webview) { - exists(MethodAccess loadUrl | + exists(MethodCall loadUrl | loadUrl.getArgument(0) = urlArg and loadUrl.getMethod() instanceof WebViewLoadUrlMethod | @@ -98,7 +98,7 @@ private predicate webViewLoadUrl(Argument urlArg, WebViewRef webview) { or // `webview` is received as a parameter of an event method in a custom `WebViewClient`, // so we need to find `WebViews` that use that specific `WebViewClient`. - exists(WebViewClientEventMethod eventMethod, MethodAccess setWebClient | + exists(WebViewClientEventMethod eventMethod, MethodCall setWebClient | setWebClient.getMethod() instanceof WebViewSetWebViewClientMethod and setWebClient.getArgument(0).getType() = eventMethod.getDeclaringType() and loadUrl.getQualifier().getUnderlyingExpr() = eventMethod.getWebViewParameter().getAnAccess() @@ -114,7 +114,7 @@ private predicate webViewLoadUrl(Argument urlArg, WebViewRef webview) { * has been set to `true` via a `WebSettings` object obtained from it. */ private predicate isJSEnabled(WebViewRef webview) { - exists(MethodAccess allowJs, MethodAccess settings | + exists(MethodCall allowJs, MethodCall settings | allowJs.getMethod() instanceof AllowJavaScriptMethod and allowJs.getArgument(0).(CompileTimeConstantExpr).getBooleanValue() = true and settings.getMethod() instanceof WebViewGetSettingsMethod and @@ -129,7 +129,7 @@ private predicate isJSEnabled(WebViewRef webview) { * obtained from it. */ private predicate isAllowFileAccessEnabled(WebViewRef webview) { - exists(MethodAccess allowFileAccess, MethodAccess settings | + exists(MethodCall allowFileAccess, MethodCall settings | allowFileAccess.getMethod() instanceof CrossOriginAccessMethod and allowFileAccess.getArgument(0).(CompileTimeConstantExpr).getBooleanValue() = true and settings.getMethod() instanceof WebViewGetSettingsMethod and diff --git a/java/ql/lib/semmle/code/java/security/UnsafeCertTrust.qll b/java/ql/lib/semmle/code/java/security/UnsafeCertTrust.qll index d780207bbdae..60f0cef83847 100644 --- a/java/ql/lib/semmle/code/java/security/UnsafeCertTrust.qll +++ b/java/ql/lib/semmle/code/java/security/UnsafeCertTrust.qll @@ -12,7 +12,7 @@ private import semmle.code.java.dataflow.DataFlow */ class SslConnectionInit extends DataFlow::Node { SslConnectionInit() { - exists(MethodAccess ma, Method m | + exists(MethodCall ma, Method m | this.asExpr() = ma and ma.getMethod() = m | @@ -30,7 +30,7 @@ class SslConnectionInit extends DataFlow::Node { */ class SslConnectionCreation extends DataFlow::Node { SslConnectionCreation() { - exists(MethodAccess ma, Method m | + exists(MethodCall ma, Method m | m instanceof BeginHandshakeMethod or m instanceof SslWrapMethod or m instanceof SslUnwrapMethod or @@ -54,7 +54,7 @@ abstract class SslUnsafeCertTrustSanitizer extends DataFlow::Node { } */ private class SslEngineServerMode extends SslUnsafeCertTrustSanitizer { SslEngineServerMode() { - exists(MethodAccess ma, Method m | + exists(MethodCall ma, Method m | m.hasName("setUseClientMode") and m.getDeclaringType().getAnAncestor() instanceof SslEngine and ma.getMethod() = m and @@ -68,7 +68,7 @@ private class SslEngineServerMode extends SslUnsafeCertTrustSanitizer { * Holds if the return value of `createSocket` is cast to `SSLSocket` * or the qualifier of `createSocket` is an instance of `SSLSocketFactory`. */ -private predicate isSslSocket(MethodAccess createSocket) { +private predicate isSslSocket(MethodCall createSocket) { createSocket = any(CastExpr ce | ce.getType() instanceof SslSocket).getExpr() or createSocket.getQualifier().getType().(RefType).getAnAncestor() instanceof SslSocketFactory @@ -78,14 +78,14 @@ private predicate isSslSocket(MethodAccess createSocket) { * A call to a method that enables SSL (`useSslProtocol` or `setSslContextFactory`) * on an instance of `com.rabbitmq.client.ConnectionFactory` that doesn't set `enableHostnameVerification`. */ -class RabbitMQEnableHostnameVerificationNotSet extends MethodAccess { +class RabbitMQEnableHostnameVerificationNotSet extends MethodCall { RabbitMQEnableHostnameVerificationNotSet() { this.getMethod().hasName(["useSslProtocol", "setSslContextFactory"]) and this.getMethod().getDeclaringType() instanceof RabbitMQConnectionFactory and exists(Variable v | v.getType() instanceof RabbitMQConnectionFactory and this.getQualifier() = v.getAnAccess() and - not exists(MethodAccess ma | + not exists(MethodCall ma | ma.getMethod().hasName("enableHostnameVerification") and ma.getQualifier() = v.getAnAccess() ) diff --git a/java/ql/lib/semmle/code/java/security/UnsafeCertTrustQuery.qll b/java/ql/lib/semmle/code/java/security/UnsafeCertTrustQuery.qll index 0b45e150c0cd..39a55118ec4e 100644 --- a/java/ql/lib/semmle/code/java/security/UnsafeCertTrustQuery.qll +++ b/java/ql/lib/semmle/code/java/security/UnsafeCertTrustQuery.qll @@ -53,14 +53,14 @@ private class SslConnectionWithSafeSslParameters extends SslUnsafeCertTrustSanit private module SafeSslParametersFlowConfig implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node source) { - exists(MethodAccess ma | + exists(MethodCall ma | ma instanceof SafeSetEndpointIdentificationAlgorithm and DataFlow::getInstanceArgument(ma) = source.(DataFlow::PostUpdateNode).getPreUpdateNode() ) } predicate isSink(DataFlow::Node sink) { - exists(MethodAccess ma, RefType t | t instanceof SslSocket or t instanceof SslEngine | + exists(MethodCall ma, RefType t | t instanceof SslSocket or t instanceof SslEngine | ma.getMethod().hasName("setSSLParameters") and ma.getMethod().getDeclaringType().getAnAncestor() = t and ma.getArgument(0) = sink.asExpr() @@ -73,7 +73,7 @@ private module SafeSslParametersFlow = DataFlow::Global ...)` */ - private predicate stepKryoPoolRunMethodAccessQualifierToFunctionalArgument( + private predicate stepKryoPoolRunMethodCallQualifierToFunctionalArgument( DataFlow::Node node1, DataFlow::Node node2 ) { - exists(MethodAccess ma | + exists(MethodCall ma | ma.getMethod() instanceof KryoPoolRunMethod and node1.asExpr() = ma.getQualifier() and ma.getArgument(0).(FunctionalExpr).asMethod().getParameter(0) = node2.asParameter() @@ -118,7 +118,7 @@ private module SafeKryoConfig implements DataFlow::ConfigSig { * Holds when a `KryoPool.Builder` method is called fluently. */ private predicate stepKryoPoolBuilderChainMethod(DataFlow::Node node1, DataFlow::Node node2) { - exists(MethodAccess ma | + exists(MethodCall ma | ma.getMethod() instanceof KryoPoolBuilderMethod and ma = node2.asExpr() and ma.getQualifier() = node1.asExpr() @@ -129,7 +129,7 @@ private module SafeKryoConfig implements DataFlow::ConfigSig { * Holds when a `KryoPool.borrow` method is called. */ private predicate stepKryoPoolBorrowMethod(DataFlow::Node node1, DataFlow::Node node2) { - exists(MethodAccess ma | + exists(MethodCall ma | ma.getMethod() = any(Method m | m.getDeclaringType() instanceof KryoPool and m.hasName("borrow")) and node1.asExpr() = ma.getQualifier() and @@ -143,7 +143,7 @@ private module SafeKryoFlow = DataFlow::Global; /** * Holds if `ma` is a call that deserializes data from `sink`. */ -predicate unsafeDeserialization(MethodAccess ma, Expr sink) { +predicate unsafeDeserialization(MethodCall ma, Expr sink) { exists(Method m | m = ma.getMethod() | m instanceof ObjectInputStreamReadObjectMethod and sink = ma.getQualifier() and @@ -232,7 +232,10 @@ class UnsafeDeserializationSink extends DataFlow::ExprNode { UnsafeDeserializationSink() { unsafeDeserialization(_, this.getExpr()) } /** Gets a call that triggers unsafe deserialization. */ - MethodAccess getMethodAccess() { unsafeDeserialization(result, this.getExpr()) } + MethodCall getMethodCall() { unsafeDeserialization(result, this.getExpr()) } + + /** DEPRECATED: Alias for `getMethodCall`. */ + deprecated MethodCall getMethodAccess() { result = this.getMethodCall() } } /** Holds if `node` is a sanitizer for unsafe deserialization */ @@ -243,13 +246,13 @@ private predicate isUnsafeDeserializationSanitizer(DataFlow::Node node) { SafeJsonIoFlow::flowToExpr(cie.getArgument(1)) ) or - exists(MethodAccess ma | + exists(MethodCall ma | ma.getMethod() instanceof JsonIoJsonToJavaMethod and ma.getArgument(0) = node.asExpr() and SafeJsonIoFlow::flowToExpr(ma.getArgument(1)) ) or - exists(MethodAccess ma | + exists(MethodCall ma | // Sanitize the input to jodd.json.JsonParser.parse et al whenever it appears // to be called with an explicit class argument limiting those types that can // be instantiated during deserialization. @@ -260,7 +263,7 @@ private predicate isUnsafeDeserializationSanitizer(DataFlow::Node node) { node.asExpr() = ma.getAnArgument() ) or - exists(MethodAccess ma | + exists(MethodCall ma | // Sanitize the input to flexjson.JSONDeserializer.deserialize whenever it appears // to be called with an explicit class argument limiting those types that can // be instantiated during deserialization, or if the deserializer has already been @@ -290,7 +293,7 @@ private predicate isUnsafeDeserializationTaintStep(DataFlow::Node pred, DataFlow ) ) or - exists(MethodAccess ma | + exists(MethodCall ma | ma.getMethod() instanceof BurlapInputInitMethod and ma.getArgument(0) = pred.asExpr() and ma.getQualifier() = succ.asExpr() @@ -342,7 +345,7 @@ module UnsafeDeserializationFlow = TaintTracking::Global 0 and ma.getArgument(i) = arg | + exists(MethodCall ma, int i, Expr arg | i > 0 and ma.getArgument(i) = arg | ( ma.getMethod() instanceof ObjectMapperReadMethod or @@ -501,7 +504,7 @@ module EnableJacksonDefaultTypingFlow = DataFlow::Global; */ private class JoddJsonParserConfigurationMethodQualifier extends DataFlow::ExprNode { JoddJsonParserConfigurationMethodQualifier() { - exists(MethodAccess ma, Method m | ma.getQualifier() = this.asExpr() and m = ma.getMethod() | + exists(MethodCall ma, Method m | ma.getQualifier() = this.asExpr() and m = ma.getMethod() | m instanceof WithClassMetadataMethod or m instanceof SetClassMetadataNameMethod @@ -588,7 +591,7 @@ private module JoddJsonParserConfigurationMethodConfig implements DataFlow::Conf } predicate isSink(DataFlow::Node sink) { - exists(MethodAccess ma | + exists(MethodCall ma | ma.getMethod() instanceof JoddJsonParseMethod and sink.asExpr() = ma.getQualifier() // The class type argument ) @@ -608,7 +611,7 @@ private module JoddJsonParserConfigurationMethodFlow = * Such a parser may instantiate an arbtirary type when deserializing untrusted data. */ private DataFlow::Node getAnUnsafelyConfiguredParser() { - exists(MethodAccess ma | result.asExpr() = ma.getQualifier() | + exists(MethodCall ma | result.asExpr() = ma.getQualifier() | ma.getMethod() instanceof WithClassMetadataMethod and ma.getArgument(0).(CompileTimeConstantExpr).getBooleanValue() = true or @@ -623,7 +626,7 @@ private DataFlow::Node getAnUnsafelyConfiguredParser() { * Such a parser will not instantiate an arbtirary type when deserializing untrusted data. */ private DataFlow::Node getASafelyConfiguredParser() { - exists(MethodAccess ma | result.asExpr() = ma.getQualifier() | + exists(MethodCall ma | result.asExpr() = ma.getQualifier() | ma.getMethod() instanceof WithClassMetadataMethod and ma.getArgument(0).(CompileTimeConstantExpr).getBooleanValue() = false or diff --git a/java/ql/lib/semmle/code/java/security/UrlRedirect.qll b/java/ql/lib/semmle/code/java/security/UrlRedirect.qll index fdd09fe89576..5877358eaf09 100644 --- a/java/ql/lib/semmle/code/java/security/UrlRedirect.qll +++ b/java/ql/lib/semmle/code/java/security/UrlRedirect.qll @@ -18,12 +18,12 @@ private class DefaultUrlRedirectSink extends UrlRedirectSink { /** A Servlet URL redirection sink. */ private class ServletUrlRedirectSink extends UrlRedirectSink { ServletUrlRedirectSink() { - exists(MethodAccess ma | + exists(MethodCall ma | ma.getMethod() instanceof HttpServletResponseSendRedirectMethod and this.asExpr() = ma.getArgument(0) ) or - exists(MethodAccess ma | + exists(MethodCall ma | ma.getMethod() instanceof ResponseSetHeaderMethod or ma.getMethod() instanceof ResponseAddHeaderMethod | diff --git a/java/ql/lib/semmle/code/java/security/Validation.qll b/java/ql/lib/semmle/code/java/security/Validation.qll index 34c752444b9f..b8183b10751b 100644 --- a/java/ql/lib/semmle/code/java/security/Validation.qll +++ b/java/ql/lib/semmle/code/java/security/Validation.qll @@ -5,7 +5,7 @@ import semmle.code.java.controlflow.Guards /** Holds if the method `method` validates its `arg`-th argument in some way. */ predicate validationMethod(Method method, int arg) { // The method examines the contents of the string argument. - exists(Parameter param, VarAccess paramRef, MethodAccess call | + exists(Parameter param, VarAccess paramRef, MethodCall call | method.getParameter(arg) = param and param.getType() instanceof TypeString and paramRef.getVariable() = param and @@ -17,19 +17,19 @@ predicate validationMethod(Method method, int arg) { ) or // The method calls another one that verifies the argument. - exists(Parameter param, MethodAccess call, int recursiveArg | + exists(Parameter param, MethodCall call, int recursiveArg | method.getParameter(arg) = param and call.getArgument(pragma[only_bind_into](recursiveArg)) = param.getAnAccess() and validationMethod(pragma[only_bind_into](call.getMethod()), pragma[only_bind_into](recursiveArg)) ) } -private predicate validationCall(MethodAccess ma, VarAccess va) { +private predicate validationCall(MethodCall ma, VarAccess va) { exists(int arg | validationMethod(ma.getMethod(), arg) and ma.getArgument(arg) = va) } private predicate validatedAccess(VarAccess va) { - exists(SsaVariable v, MethodAccess guardcall | + exists(SsaVariable v, MethodCall guardcall | va = v.getAUse() and validationCall(guardcall, v.getAUse()) | diff --git a/java/ql/lib/semmle/code/java/security/WebviewDebuggingEnabledQuery.qll b/java/ql/lib/semmle/code/java/security/WebviewDebuggingEnabledQuery.qll index d5aaf92f4125..00b9c715f752 100644 --- a/java/ql/lib/semmle/code/java/security/WebviewDebuggingEnabledQuery.qll +++ b/java/ql/lib/semmle/code/java/security/WebviewDebuggingEnabledQuery.qll @@ -13,8 +13,8 @@ private predicate isDebugCheck(Expr ex) { | subex.(VarAccess).getVariable().getName() = debug or - subex.(MethodAccess).getMethod().hasName("getProperty") and - subex.(MethodAccess).getAnArgument().(CompileTimeConstantExpr).getStringValue() = debug + subex.(MethodCall).getMethod().hasName("getProperty") and + subex.(MethodCall).getAnArgument().(CompileTimeConstantExpr).getStringValue() = debug ) } @@ -31,7 +31,7 @@ deprecated class WebviewDebugEnabledConfig extends DataFlow::Configuration { } override predicate isSink(DataFlow::Node node) { - exists(MethodAccess ma | + exists(MethodCall ma | ma.getMethod().hasQualifiedName("android.webkit", "WebView", "setWebContentsDebuggingEnabled") and node.asExpr() = ma.getArgument(0) ) @@ -51,7 +51,7 @@ module WebviewDebugEnabledConfig implements DataFlow::ConfigSig { } predicate isSink(DataFlow::Node node) { - exists(MethodAccess ma | + exists(MethodCall ma | ma.getMethod().hasQualifiedName("android.webkit", "WebView", "setWebContentsDebuggingEnabled") and node.asExpr() = ma.getArgument(0) ) diff --git a/java/ql/lib/semmle/code/java/security/XSS.qll b/java/ql/lib/semmle/code/java/security/XSS.qll index 163696e4489d..9edee5823bfc 100644 --- a/java/ql/lib/semmle/code/java/security/XSS.qll +++ b/java/ql/lib/semmle/code/java/security/XSS.qll @@ -42,7 +42,7 @@ private class DefaultXssSink extends XssSink { DefaultXssSink() { sinkNode(this, ["html-injection", "js-injection"]) or - exists(MethodAccess ma | + exists(MethodCall ma | ma.getMethod() instanceof WritingMethod and XssVulnerableWriterSourceToWritingMethodFlow::flowToExpr(ma.getQualifier()) and this.asExpr() = ma.getArgument(_) @@ -56,7 +56,7 @@ private class DefaultXssSanitizer extends XssSanitizer { this.getType() instanceof NumericType or this.getType() instanceof BooleanType or // Match `org.springframework.web.util.HtmlUtils.htmlEscape` and possibly other methods like it. - this.asExpr().(MethodAccess).getMethod().getName().regexpMatch("(?i)html_?escape.*") + this.asExpr().(MethodCall).getMethod().getName().regexpMatch("(?i)html_?escape.*") } } @@ -65,7 +65,7 @@ private module XssVulnerableWriterSourceToWritingMethodFlowConfig implements Dat predicate isSource(DataFlow::Node src) { src.asExpr() instanceof XssVulnerableWriterSource } predicate isSink(DataFlow::Node sink) { - exists(MethodAccess ma | + exists(MethodCall ma | sink.asExpr() = ma.getQualifier() and ma.getMethod() instanceof WritingMethod ) } @@ -88,7 +88,7 @@ private class WritingMethod extends Method { } /** An output stream or writer that writes to a servlet, JSP or JSF response. */ -class XssVulnerableWriterSource extends MethodAccess { +class XssVulnerableWriterSource extends MethodCall { XssVulnerableWriterSource() { this.getMethod() instanceof ServletResponseGetWriterMethod or diff --git a/java/ql/lib/semmle/code/java/security/XmlParsers.qll b/java/ql/lib/semmle/code/java/security/XmlParsers.qll index cf8ef5e8775b..5a37ebee5e2d 100644 --- a/java/ql/lib/semmle/code/java/security/XmlParsers.qll +++ b/java/ql/lib/semmle/code/java/security/XmlParsers.qll @@ -16,7 +16,7 @@ private module Frameworks { /** * An abstract type representing a call to parse XML files. */ -abstract class XmlParserCall extends MethodAccess { +abstract class XmlParserCall extends MethodCall { /** * Gets the argument representing the XML content to be parsed. */ @@ -31,7 +31,7 @@ abstract class XmlParserCall extends MethodAccess { /** * An access to a method use for configuring the parser. */ -abstract class ParserConfig extends MethodAccess { +abstract class ParserConfig extends MethodCall { /** * Holds if the method disables a property. */ @@ -141,7 +141,7 @@ class SafeDocumentBuilderFactory extends VarAccess { } } -private class DocumentBuilderConstruction extends MethodAccess { +private class DocumentBuilderConstruction extends MethodCall { DocumentBuilderConstruction() { exists(Method m | this.getMethod() = m and @@ -440,7 +440,7 @@ private predicate safeSaxParserNode(DataFlow::Node src) { src.asExpr() instanceo private module SafeSaxParserFlow = DataFlow::SimpleGlobal; /** A `SaxParser` created from a safely configured `SaxParserFactory`. */ -class SafeSaxParser extends MethodAccess { +class SafeSaxParser extends MethodCall { SafeSaxParser() { this.getMethod().getDeclaringType() instanceof SaxParserFactory and this.getMethod().hasName("newSAXParser") and @@ -640,13 +640,13 @@ private module CreatedSafeXmlReaderFlow = DataFlow::SimpleGlobal 1 + count(MethodCall a | a.getParent*() = branch) > 1 } predicate complicatedCondition(Expr cond) { diff --git a/java/ql/src/Language Abuse/UselessUpcast.ql b/java/ql/src/Language Abuse/UselessUpcast.ql index 36810b4116e8..ea7c12632ecd 100644 --- a/java/ql/src/Language Abuse/UselessUpcast.ql +++ b/java/ql/src/Language Abuse/UselessUpcast.ql @@ -25,7 +25,7 @@ predicate usefulUpcast(CastingExpr e) { other.getName() = target.getName() and other.getSourceDeclaration() != target.getSourceDeclaration() | - c.(MethodAccess).getReceiverType().inherits(other.(Method)) or + c.(MethodCall).getReceiverType().inherits(other.(Method)) or other = target.(Constructor).getDeclaringType().getAConstructor() ) ) @@ -48,7 +48,7 @@ predicate usefulUpcast(CastingExpr e) { not e.getExpr().getType().(RefType).inherits(fa.getField()) ) or - exists(MethodAccess ma, Method m | + exists(MethodCall ma, Method m | e = ma.getQualifier() and m = ma.getMethod() and (m.isStatic() or m.isPrivate()) diff --git a/java/ql/src/Likely Bugs/Arithmetic/BadAbsOfRandom.ql b/java/ql/src/Likely Bugs/Arithmetic/BadAbsOfRandom.ql index ec9c4716ea67..26353891f418 100644 --- a/java/ql/src/Likely Bugs/Arithmetic/BadAbsOfRandom.ql +++ b/java/ql/src/Likely Bugs/Arithmetic/BadAbsOfRandom.ql @@ -13,7 +13,7 @@ import java import semmle.code.java.security.RandomQuery -from MethodAccess ma, Method abs, Method nextIntOrLong, RandomDataSource nma +from MethodCall ma, Method abs, Method nextIntOrLong, RandomDataSource nma where ma.getMethod() = abs and abs.hasName("abs") and diff --git a/java/ql/src/Likely Bugs/Arithmetic/BadCheckOdd.ql b/java/ql/src/Likely Bugs/Arithmetic/BadCheckOdd.ql index 6285320cee8d..567e2628dae1 100644 --- a/java/ql/src/Likely Bugs/Arithmetic/BadCheckOdd.ql +++ b/java/ql/src/Likely Bugs/Arithmetic/BadCheckOdd.ql @@ -17,8 +17,8 @@ import semmle.code.java.Collections predicate isDefinitelyPositive(Expr e) { isDefinitelyPositive(e) or e.(IntegerLiteral).getIntValue() >= 0 or - e.(MethodAccess).getMethod() instanceof CollectionSizeMethod or - e.(MethodAccess).getMethod() instanceof StringLengthMethod or + e.(MethodCall).getMethod() instanceof CollectionSizeMethod or + e.(MethodCall).getMethod() instanceof StringLengthMethod or e.(FieldAccess).getField() instanceof ArrayLengthField } diff --git a/java/ql/src/Likely Bugs/Collections/Containers.qll b/java/ql/src/Likely Bugs/Collections/Containers.qll index 4c19ddf647ca..3fdf44aba8c5 100644 --- a/java/ql/src/Likely Bugs/Collections/Containers.qll +++ b/java/ql/src/Likely Bugs/Collections/Containers.qll @@ -18,7 +18,7 @@ class ContainerMutator extends Method { } } -class ContainerMutation extends MethodAccess { +class ContainerMutation extends MethodCall { ContainerMutation() { this instanceof CollectionMutation or this instanceof MapMutation diff --git a/java/ql/src/Likely Bugs/Collections/ContainsTypeMismatch.ql b/java/ql/src/Likely Bugs/Collections/ContainsTypeMismatch.ql index 52d790e0e718..e1137b111bf6 100644 --- a/java/ql/src/Likely Bugs/Collections/ContainsTypeMismatch.ql +++ b/java/ql/src/Likely Bugs/Collections/ContainsTypeMismatch.ql @@ -95,7 +95,7 @@ predicate containerAccess(string package, string type, int p, string signature, i = 0 } -class MismatchedContainerAccess extends MethodAccess { +class MismatchedContainerAccess extends MethodCall { MismatchedContainerAccess() { exists(string package, string type, int i | containerAccess(package, type, _, this.getCallee().getSignature(), i) diff --git a/java/ql/src/Likely Bugs/Collections/IteratorRemoveMayFail.ql b/java/ql/src/Likely Bugs/Collections/IteratorRemoveMayFail.ql index 8784b7ccd00e..0308f68f231c 100644 --- a/java/ql/src/Likely Bugs/Collections/IteratorRemoveMayFail.ql +++ b/java/ql/src/Likely Bugs/Collections/IteratorRemoveMayFail.ql @@ -13,11 +13,9 @@ import java -class SpecialCollectionCreation extends MethodAccess { +class SpecialCollectionCreation extends MethodCall { SpecialCollectionCreation() { - exists(Method m, RefType rt | - m = this.(MethodAccess).getCallee() and rt = m.getDeclaringType() - | + exists(Method m, RefType rt | m = this.(MethodCall).getCallee() and rt = m.getDeclaringType() | rt.hasQualifiedName("java.util", "Arrays") and m.hasName("asList") or rt.hasQualifiedName("java.util", "Collections") and @@ -46,7 +44,7 @@ predicate containsSpecialCollection(Expr e, SpecialCollectionCreation origin) { } predicate iterOfSpecialCollection(Expr e, SpecialCollectionCreation origin) { - exists(MethodAccess ma | ma = e | + exists(MethodCall ma | ma = e | containsSpecialCollection(ma.getQualifier(), origin) and ma.getCallee().hasName("iterator") ) @@ -67,7 +65,7 @@ predicate iterOfSpecialCollection(Expr e, SpecialCollectionCreation origin) { ) } -from MethodAccess remove, SpecialCollectionCreation scc +from MethodCall remove, SpecialCollectionCreation scc where remove.getCallee().hasName("remove") and iterOfSpecialCollection(remove.getQualifier(), scc) diff --git a/java/ql/src/Likely Bugs/Collections/ReadOnlyContainer.ql b/java/ql/src/Likely Bugs/Collections/ReadOnlyContainer.ql index f9390c9c6ec3..a3fb91e99b69 100644 --- a/java/ql/src/Likely Bugs/Collections/ReadOnlyContainer.ql +++ b/java/ql/src/Likely Bugs/Collections/ReadOnlyContainer.ql @@ -32,12 +32,10 @@ where v instanceof LocalVariableDecl and exists(ReturnStmt ret | ret.getResult() = va) or // ...or a call to a query method on `v`. - exists(MethodAccess ma | va = ma.getQualifier() | - ma.getMethod() instanceof ContainerQueryMethod - ) + exists(MethodCall ma | va = ma.getQualifier() | ma.getMethod() instanceof ContainerQueryMethod) ) and // There is at least one call to a query method. - exists(MethodAccess ma | v.getAnAccess() = ma.getQualifier() | + exists(MethodCall ma | v.getAnAccess() = ma.getQualifier() | ma.getMethod() instanceof ContainerQueryMethod ) and // Also, any value that `v` is initialized to is a fresh container, diff --git a/java/ql/src/Likely Bugs/Collections/RemoveTypeMismatch.ql b/java/ql/src/Likely Bugs/Collections/RemoveTypeMismatch.ql index 076ccc122404..08a8da884846 100644 --- a/java/ql/src/Likely Bugs/Collections/RemoveTypeMismatch.ql +++ b/java/ql/src/Likely Bugs/Collections/RemoveTypeMismatch.ql @@ -65,7 +65,7 @@ predicate containerModification(string package, string type, int p, string signa i = 0 } -class MismatchedContainerModification extends MethodAccess { +class MismatchedContainerModification extends MethodCall { MismatchedContainerModification() { exists(string package, string type, int i | containerModification(package, type, _, this.getCallee().getSignature(), i) diff --git a/java/ql/src/Likely Bugs/Comparison/DefineEqualsWhenAddingFields.ql b/java/ql/src/Likely Bugs/Comparison/DefineEqualsWhenAddingFields.ql index be186d2b2e20..2edeea4ec57f 100644 --- a/java/ql/src/Likely Bugs/Comparison/DefineEqualsWhenAddingFields.ql +++ b/java/ql/src/Likely Bugs/Comparison/DefineEqualsWhenAddingFields.ql @@ -46,7 +46,7 @@ predicate checksReferenceEquality(EqualsMethod em) { // Check whether `em` delegates to another method checking reference equality. // More precisely, we check whether the body of `em` is of the form `return super.equals(o);`, // where `o` is the (only) parameter of `em`, and the invoked method is a reference equality check. - exists(SuperMethodAccess sup | + exists(SuperMethodCall sup | sup = em.getBody().(SingletonBlock).getStmt().(ReturnStmt).getResult() and sup.getArgument(0) = em.getParameter(0).getAnAccess() and checksReferenceEquality(sup.getCallee()) diff --git a/java/ql/src/Likely Bugs/Comparison/Equality.qll b/java/ql/src/Likely Bugs/Comparison/Equality.qll index 1ee8eac49add..9aeb4a46047e 100644 --- a/java/ql/src/Likely Bugs/Comparison/Equality.qll +++ b/java/ql/src/Likely Bugs/Comparison/Equality.qll @@ -13,7 +13,7 @@ class RefiningEquals extends EqualsMethod { // For each return statement `ret` in this method, ... forall(ReturnStmt ret | ret.getEnclosingCallable() = this | // ... there is a `super` access that ... - exists(MethodAccess sup, SuperAccess qual | + exists(MethodCall sup, SuperAccess qual | // ... is of the form `super.something`, but not `A.super.something` ... qual = sup.getQualifier() and not exists(qual.getQualifier()) and diff --git a/java/ql/src/Likely Bugs/Comparison/EqualsArray.ql b/java/ql/src/Likely Bugs/Comparison/EqualsArray.ql index c7324012fc29..2b04d8711540 100644 --- a/java/ql/src/Likely Bugs/Comparison/EqualsArray.ql +++ b/java/ql/src/Likely Bugs/Comparison/EqualsArray.ql @@ -12,7 +12,7 @@ import java -from MethodAccess ma, Array recvtype, Method m +from MethodCall ma, Array recvtype, Method m where recvtype = ma.getQualifier().getType() and m = ma.getMethod() and diff --git a/java/ql/src/Likely Bugs/Comparison/HashedButNoHash.ql b/java/ql/src/Likely Bugs/Comparison/HashedButNoHash.ql index 1d20e98a21b8..6d3c4ce28218 100644 --- a/java/ql/src/Likely Bugs/Comparison/HashedButNoHash.ql +++ b/java/ql/src/Likely Bugs/Comparison/HashedButNoHash.ql @@ -38,7 +38,7 @@ predicate usedInHash(RefType t, Expr e) { exists(RefType s | s.getName().matches("%Hash%") and not s.getSourceDeclaration().getName() = "IdentityHashMap" | - exists(MethodAccess ma | + exists(MethodCall ma | ma.getQualifier().getType() = s and ma.getArgument(0).getType() = t and e = ma and diff --git a/java/ql/src/Likely Bugs/Comparison/IncomparableEquals.ql b/java/ql/src/Likely Bugs/Comparison/IncomparableEquals.ql index d98fc77af38d..2326ae5dd3d9 100644 --- a/java/ql/src/Likely Bugs/Comparison/IncomparableEquals.ql +++ b/java/ql/src/Likely Bugs/Comparison/IncomparableEquals.ql @@ -13,7 +13,7 @@ import java /** A call to an `equals` method. */ -class EqualsCall extends MethodAccess { +class EqualsCall extends MethodCall { EqualsCall() { this.getMethod() instanceof EqualsMethod } /** @@ -22,7 +22,7 @@ class EqualsCall extends MethodAccess { */ predicate whitelisted() { // Allow tests and assertions to verify that `equals` methods return `false`. - this.getParent*().(MethodAccess).getMethod().getName().matches("assert%") or + this.getParent*().(MethodCall).getMethod().getName().matches("assert%") or this.getEnclosingStmt() instanceof AssertStmt } diff --git a/java/ql/src/Likely Bugs/Comparison/MissingInstanceofInEquals.ql b/java/ql/src/Likely Bugs/Comparison/MissingInstanceofInEquals.ql index 1c7bb13c0654..455ca22d6e3f 100644 --- a/java/ql/src/Likely Bugs/Comparison/MissingInstanceofInEquals.ql +++ b/java/ql/src/Likely Bugs/Comparison/MissingInstanceofInEquals.ql @@ -32,7 +32,7 @@ predicate hasTypeTest(Variable v) { or any(ClassExpr c).getExpr() = v.getAnAccess() or - exists(MethodAccess ma | + exists(MethodCall ma | ma.getMethod().getName() = "getClass" and ma.getQualifier() = v.getAnAccess() ) @@ -71,7 +71,7 @@ where not hasTypeTest(p) and // If the parameter is passed to a method for which we don't have the source // we assume it's ok - not exists(MethodAccess ma | + not exists(MethodCall ma | not exists(ma.getMethod().getBody()) and ma.getAnArgument() = p.getAnAccess() ) diff --git a/java/ql/src/Likely Bugs/Comparison/ObjectComparison.ql b/java/ql/src/Likely Bugs/Comparison/ObjectComparison.ql index d240f908941a..63ad7af87fa8 100644 --- a/java/ql/src/Likely Bugs/Comparison/ObjectComparison.ql +++ b/java/ql/src/Likely Bugs/Comparison/ObjectComparison.ql @@ -30,7 +30,7 @@ class ReferenceEqualityTestOnObject extends ReferenceEqualityTest { from ReferenceEqualityTestOnObject scw where - not exists(Variable left, Variable right, MethodAccess equals | + not exists(Variable left, Variable right, MethodCall equals | left = scw.getLeftOperand().(VarAccess).getVariable() and right = scw.getRightOperand().(VarAccess).getVariable() and scw.getEnclosingCallable() = equals.getEnclosingCallable() and diff --git a/java/ql/src/Likely Bugs/Comparison/StringComparison.ql b/java/ql/src/Likely Bugs/Comparison/StringComparison.ql index fd840d416e89..63d09e0f7915 100644 --- a/java/ql/src/Likely Bugs/Comparison/StringComparison.ql +++ b/java/ql/src/Likely Bugs/Comparison/StringComparison.ql @@ -21,7 +21,7 @@ class StringValue extends Expr { exists(Method intern | intern.getDeclaringType() instanceof TypeString and intern.hasName("intern") and - this.(MethodAccess).getMethod() = intern + this.(MethodCall).getMethod() = intern ) or // Ternary conditional operator. @@ -35,7 +35,7 @@ class StringValue extends Expr { variableValuesInterned(this.(VarAccess).getVariable()) or // Method accesses whose results are all interned. - forex(ReturnStmt rs | rs.getEnclosingCallable() = this.(MethodAccess).getMethod() | + forex(ReturnStmt rs | rs.getEnclosingCallable() = this.(MethodCall).getMethod() | rs.getResult().(StringValue).isInterned() ) } diff --git a/java/ql/src/Likely Bugs/Concurrency/BusyWait.ql b/java/ql/src/Likely Bugs/Concurrency/BusyWait.ql index e9b160222bc8..2cba4d10f035 100644 --- a/java/ql/src/Likely Bugs/Concurrency/BusyWait.ql +++ b/java/ql/src/Likely Bugs/Concurrency/BusyWait.ql @@ -23,8 +23,8 @@ class SleepMethod extends Method { } } -class SleepMethodAccess extends MethodAccess { - SleepMethodAccess() { this.getMethod() instanceof SleepMethod } +class SleepMethodCall extends MethodCall { + SleepMethodCall() { this.getMethod() instanceof SleepMethod } } class WaitMethod extends Method { @@ -48,7 +48,7 @@ class CommunicationMethod extends Method { predicate callsCommunicationMethod(Method source) { source instanceof CommunicationMethod or - exists(MethodAccess a, Method overridingMethod, Method target | + exists(MethodCall a, Method overridingMethod, Method target | callsCommunicationMethod(overridingMethod) and overridingMethod.overridesOrInstantiates*(target) and target = a.getMethod() and @@ -57,13 +57,13 @@ predicate callsCommunicationMethod(Method source) { } class DangerStmt extends Stmt { - DangerStmt() { exists(SleepMethodAccess sleep | sleep.getEnclosingStmt() = this) } + DangerStmt() { exists(SleepMethodCall sleep | sleep.getEnclosingStmt() = this) } } from WhileStmt s, DangerStmt d where d.getEnclosingStmt+() = s and - not exists(MethodAccess call | callsCommunicationMethod(call.getMethod()) | + not exists(MethodCall call | callsCommunicationMethod(call.getMethod()) | call.getEnclosingStmt().getEnclosingStmt*() = s ) select d, "Prefer wait/notify or java.util.concurrent to communicate between threads." diff --git a/java/ql/src/Likely Bugs/Concurrency/CallsToConditionWait.ql b/java/ql/src/Likely Bugs/Concurrency/CallsToConditionWait.ql index 9962596d5b6d..bf1639361154 100644 --- a/java/ql/src/Likely Bugs/Concurrency/CallsToConditionWait.ql +++ b/java/ql/src/Likely Bugs/Concurrency/CallsToConditionWait.ql @@ -26,7 +26,7 @@ class ConditionInterface extends Interface { ConditionInterface() { this.hasQualifiedName("java.util.concurrent.locks", "Condition") } } -from MethodAccess ma, ConditionInterface condition +from MethodCall ma, ConditionInterface condition where ma.getMethod() instanceof WaitMethod and ma.getQualifier().getType().(RefType).hasSupertype*(condition) diff --git a/java/ql/src/Likely Bugs/Concurrency/CallsToRunnableRun.ql b/java/ql/src/Likely Bugs/Concurrency/CallsToRunnableRun.ql index e7e8f43dc42a..c31ef9962252 100644 --- a/java/ql/src/Likely Bugs/Concurrency/CallsToRunnableRun.ql +++ b/java/ql/src/Likely Bugs/Concurrency/CallsToRunnableRun.ql @@ -22,7 +22,7 @@ class RunMethod extends Method { } } -from MethodAccess m, RunMethod run +from MethodCall m, RunMethod run where m.getMethod() = run and not m.getEnclosingCallable() instanceof RunMethod diff --git a/java/ql/src/Likely Bugs/Concurrency/DateFormatThreadUnsafe.ql b/java/ql/src/Likely Bugs/Concurrency/DateFormatThreadUnsafe.ql index ef3814014eee..18683ac690ff 100644 --- a/java/ql/src/Likely Bugs/Concurrency/DateFormatThreadUnsafe.ql +++ b/java/ql/src/Likely Bugs/Concurrency/DateFormatThreadUnsafe.ql @@ -19,7 +19,7 @@ where (f.isPublic() or f.isProtected()) and dateFormat.hasQualifiedName("java.text", "DateFormat") and f.getType().(RefType).hasSupertype*(dateFormat) and - exists(MethodAccess m | m.getQualifier().(VarAccess).getVariable() = f) + exists(MethodCall m | m.getQualifier().(VarAccess).getVariable() = f) select f, "Found static field of type " + f.getType().getName() + " in " + f.getDeclaringType().getName() + "." diff --git a/java/ql/src/Likely Bugs/Concurrency/DoubleCheckedLockingWithInitRace.ql b/java/ql/src/Likely Bugs/Concurrency/DoubleCheckedLockingWithInitRace.ql index be9314072847..241825c092e6 100644 --- a/java/ql/src/Likely Bugs/Concurrency/DoubleCheckedLockingWithInitRace.ql +++ b/java/ql/src/Likely Bugs/Concurrency/DoubleCheckedLockingWithInitRace.ql @@ -24,8 +24,8 @@ predicate whitelistedMethod(Method m) { class SideEffect extends Expr { SideEffect() { - this instanceof MethodAccess and - not whitelistedMethod(this.(MethodAccess).getMethod()) + this instanceof MethodCall and + not whitelistedMethod(this.(MethodCall).getMethod()) or this.(Assignment).getDest() instanceof FieldAccess } diff --git a/java/ql/src/Likely Bugs/Concurrency/InconsistentAccess.ql b/java/ql/src/Likely Bugs/Concurrency/InconsistentAccess.ql index 9d44e5d4415b..27e0973ebf99 100644 --- a/java/ql/src/Likely Bugs/Concurrency/InconsistentAccess.ql +++ b/java/ql/src/Likely Bugs/Concurrency/InconsistentAccess.ql @@ -23,16 +23,14 @@ predicate withinInitializer(Expr e) { e.getEnclosingCallable() instanceof Constructor } -predicate locallySynchronized(MethodAccess ma) { +predicate locallySynchronized(MethodCall ma) { ma.getEnclosingStmt().getEnclosingStmt+() instanceof SynchronizedStmt } predicate hasUnsynchronizedCall(Method m) { m.isPublic() and not m.isSynchronized() or - exists(MethodAccess ma, Method caller | - ma.getMethod() = m and caller = ma.getEnclosingCallable() - | + exists(MethodCall ma, Method caller | ma.getMethod() = m and caller = ma.getEnclosingCallable() | hasUnsynchronizedCall(caller) and not caller.isSynchronized() and not locallySynchronized(ma) diff --git a/java/ql/src/Likely Bugs/Concurrency/LazyInitStaticField.ql b/java/ql/src/Likely Bugs/Concurrency/LazyInitStaticField.ql index c6f893e10950..757da40c6e6e 100644 --- a/java/ql/src/Likely Bugs/Concurrency/LazyInitStaticField.ql +++ b/java/ql/src/Likely Bugs/Concurrency/LazyInitStaticField.ql @@ -61,12 +61,12 @@ class ValidSynchStmt extends Stmt { exists(TryStmt try, LockObjectField lockField | this = try.getBlock() and lockField.getType().(RefType).hasQualifiedName("java.util.concurrent.locks", "ReentrantLock") and - exists(MethodAccess lockAction | + exists(MethodCall lockAction | lockAction.getQualifier() = lockField.getAnAccess() and lockAction.getMethod().getName() = "lock" and dominates(lockAction, this) ) and - exists(MethodAccess unlockAction | + exists(MethodCall unlockAction | unlockAction.getQualifier() = lockField.getAnAccess() and unlockAction.getMethod().getName() = "unlock" and postDominates(unlockAction, this) diff --git a/java/ql/src/Likely Bugs/Concurrency/NonSynchronizedOverride.ql b/java/ql/src/Likely Bugs/Concurrency/NonSynchronizedOverride.ql index c2f61b60f8dc..a2e41c9bd055 100644 --- a/java/ql/src/Likely Bugs/Concurrency/NonSynchronizedOverride.ql +++ b/java/ql/src/Likely Bugs/Concurrency/NonSynchronizedOverride.ql @@ -20,7 +20,7 @@ import java * `super.m(x, y, z)`, possibly wrapped in one or more casts and/or parentheses. */ predicate delegatingSuperCall(Expr e, Method target) { - exists(MethodAccess call | call = e | + exists(MethodCall call | call = e | call.getQualifier() instanceof SuperAccess and call.getCallee() = target and forall(Expr arg | arg = call.getAnArgument() | arg instanceof VarAccess) diff --git a/java/ql/src/Likely Bugs/Concurrency/NotifyNotNotifyAll.ql b/java/ql/src/Likely Bugs/Concurrency/NotifyNotNotifyAll.ql index 1cd857bf175c..047e6853011e 100644 --- a/java/ql/src/Likely Bugs/Concurrency/NotifyNotNotifyAll.ql +++ b/java/ql/src/Likely Bugs/Concurrency/NotifyNotNotifyAll.ql @@ -14,15 +14,15 @@ import java -class InvokeInterfaceOrVirtualMethodAccess extends MethodAccess { - InvokeInterfaceOrVirtualMethodAccess() { +class InvokeInterfaceOrVirtualMethodCall extends MethodCall { + InvokeInterfaceOrVirtualMethodCall() { this.getMethod().getDeclaringType() instanceof Interface or not this.hasQualifier() or not this.getQualifier() instanceof SuperAccess } } -from InvokeInterfaceOrVirtualMethodAccess ma, Method m +from InvokeInterfaceOrVirtualMethodCall ma, Method m where ma.getMethod() = m and m.hasName("notify") and diff --git a/java/ql/src/Likely Bugs/Concurrency/NotifyWithoutSynch.ql b/java/ql/src/Likely Bugs/Concurrency/NotifyWithoutSynch.ql index 52ae743412b2..89dbedd02532 100644 --- a/java/ql/src/Likely Bugs/Concurrency/NotifyWithoutSynch.ql +++ b/java/ql/src/Likely Bugs/Concurrency/NotifyWithoutSynch.ql @@ -48,7 +48,7 @@ private predicate synchronizedCallable(Callable c) { c.isSynchronized() or c.isPrivate() and - forall(MethodAccess parent | parent.getCallee() = c | + forall(MethodCall parent | parent.getCallee() = c | synchronizedThisAccess(parent, c.getDeclaringType()) ) } @@ -60,7 +60,7 @@ private predicate synchronizedCallable(Callable c) { * example, if the method call is `MyClass.wait()`, then the predicate * holds if there is an enclosing synchronization on `MyClass.this`. */ -private predicate synchronizedThisAccess(MethodAccess ma, Type thisType) { +private predicate synchronizedThisAccess(MethodCall ma, Type thisType) { // Are we inside a synchronized method? exists(Callable c | c = ma.getEnclosingCallable() and @@ -90,11 +90,11 @@ predicate synchronizedVarAccess(VarAccess x) { } /** - * This predicate holds if the `MethodAccess` is a qualified call, + * This predicate holds if the `MethodCall` is a qualified call, * such as `this.wait()`, and it is not inside a synchronized statement * or method. */ -private predicate unsynchronizedExplicitThisAccess(MethodAccess ma) { +private predicate unsynchronizedExplicitThisAccess(MethodCall ma) { exists(ThisAccess x | x = ma.getQualifier() and not synchronizedThisAccess(ma, x.getType()) @@ -102,27 +102,27 @@ private predicate unsynchronizedExplicitThisAccess(MethodAccess ma) { } /** - * Holds if the `MethodAccess` is an unqualified call, + * Holds if the `MethodCall` is an unqualified call, * such as `wait()`, and it is not inside a synchronized statement * or method. */ -private predicate unsynchronizedImplicitThisAccess(MethodAccess ma) { +private predicate unsynchronizedImplicitThisAccess(MethodCall ma) { not ma.hasQualifier() and not synchronizedThisAccess(ma, ma.getEnclosingCallable().getDeclaringType()) } /** - * Holds if the `MethodAccess` is on a variable, + * Holds if the `MethodCall` is on a variable, * such as `x.wait()`, and it is not inside a synchronized statement. */ -private predicate unsynchronizedVarAccess(MethodAccess ma) { +private predicate unsynchronizedVarAccess(MethodCall ma) { exists(VarAccess x | x = ma.getQualifier() and not synchronizedVarAccess(x) ) } -from MethodAccess ma, Method m +from MethodCall ma, Method m where m = ma.getMethod() and m instanceof MethodRequiresSynch and diff --git a/java/ql/src/Likely Bugs/Concurrency/PriorityCalls.ql b/java/ql/src/Likely Bugs/Concurrency/PriorityCalls.ql index 3c309eb79382..bd3231fee8b5 100644 --- a/java/ql/src/Likely Bugs/Concurrency/PriorityCalls.ql +++ b/java/ql/src/Likely Bugs/Concurrency/PriorityCalls.ql @@ -20,10 +20,10 @@ class PriorityMethod extends Method { } } -class PriorityMethodAccess extends MethodAccess { - PriorityMethodAccess() { this.getMethod() instanceof PriorityMethod } +class PriorityMethodCall extends MethodCall { + PriorityMethodCall() { this.getMethod() instanceof PriorityMethod } } -from PriorityMethodAccess ma +from PriorityMethodCall ma where ma.getCompilationUnit().fromSource() select ma, "Avoid using thread priorities. The effect is unpredictable and not portable." diff --git a/java/ql/src/Likely Bugs/Concurrency/SleepWithLock.ql b/java/ql/src/Likely Bugs/Concurrency/SleepWithLock.ql index 411618ef4bd4..417e426b7868 100644 --- a/java/ql/src/Likely Bugs/Concurrency/SleepWithLock.ql +++ b/java/ql/src/Likely Bugs/Concurrency/SleepWithLock.ql @@ -14,7 +14,7 @@ import java -from MethodAccess ma, Method sleep +from MethodCall ma, Method sleep where ma.getMethod() = sleep and sleep.hasName("sleep") and diff --git a/java/ql/src/Likely Bugs/Concurrency/StartInConstructor.ql b/java/ql/src/Likely Bugs/Concurrency/StartInConstructor.ql index fa145ebb1b4d..cb971a5f109f 100644 --- a/java/ql/src/Likely Bugs/Concurrency/StartInConstructor.ql +++ b/java/ql/src/Likely Bugs/Concurrency/StartInConstructor.ql @@ -26,7 +26,7 @@ private predicate cannotBeExtended(RefType t) { not exists(RefType sub | sub != t | sub.getAnAncestor() = t) } -from MethodAccess m, Constructor c, Class clazz +from MethodCall m, Constructor c, Class clazz where m.getMethod().getDeclaringType().hasQualifiedName("java.lang", "Thread") and m.getMethod().getName() = "start" and diff --git a/java/ql/src/Likely Bugs/Concurrency/UnreleasedLock.ql b/java/ql/src/Likely Bugs/Concurrency/UnreleasedLock.ql index 10a054f4106c..4efaf4f9820b 100644 --- a/java/ql/src/Likely Bugs/Concurrency/UnreleasedLock.ql +++ b/java/ql/src/Likely Bugs/Concurrency/UnreleasedLock.ql @@ -39,22 +39,22 @@ class LockType extends RefType { result.hasName("isHeldByCurrentThread") } - MethodAccess getLockAccess() { + MethodCall getLockAccess() { result.getMethod() = this.getLockMethod() and // Not part of a Mockito verification call - not result instanceof MockitoVerifiedMethodAccess + not result instanceof MockitoVerifiedMethodCall } - MethodAccess getUnlockAccess() { + MethodCall getUnlockAccess() { result.getMethod() = this.getUnlockMethod() and // Not part of a Mockito verification call - not result instanceof MockitoVerifiedMethodAccess + not result instanceof MockitoVerifiedMethodCall } - MethodAccess getIsHeldByCurrentThreadAccess() { + MethodCall getIsHeldByCurrentThreadAccess() { result.getMethod() = this.getIsHeldByCurrentThreadMethod() and // Not part of a Mockito verification call - not result instanceof MockitoVerifiedMethodAccess + not result instanceof MockitoVerifiedMethodCall } } @@ -147,7 +147,7 @@ predicate blockIsLocked(LockType t, BasicBlock src, BasicBlock b, int locks) { ) } -from Callable c, LockType t, BasicBlock src, BasicBlock exit, MethodAccess lock +from Callable c, LockType t, BasicBlock src, BasicBlock exit, MethodCall lock where // Restrict results to those methods that actually attempt to unlock. t.getUnlockAccess().getEnclosingCallable() = c and diff --git a/java/ql/src/Likely Bugs/Concurrency/WaitOutsideLoop.ql b/java/ql/src/Likely Bugs/Concurrency/WaitOutsideLoop.ql index 644c003a1dcd..6e1356ff1a18 100644 --- a/java/ql/src/Likely Bugs/Concurrency/WaitOutsideLoop.ql +++ b/java/ql/src/Likely Bugs/Concurrency/WaitOutsideLoop.ql @@ -20,7 +20,7 @@ class WaitMethod extends Method { } } -from MethodAccess ma +from MethodCall ma where ma.getMethod() instanceof WaitMethod and not ma.getEnclosingStmt().getEnclosingStmt*() instanceof LoopStmt diff --git a/java/ql/src/Likely Bugs/Concurrency/WaitWithTwoLocks.ql b/java/ql/src/Likely Bugs/Concurrency/WaitWithTwoLocks.ql index 4c9896e0223c..f02f93f05254 100644 --- a/java/ql/src/Likely Bugs/Concurrency/WaitWithTwoLocks.ql +++ b/java/ql/src/Likely Bugs/Concurrency/WaitWithTwoLocks.ql @@ -21,7 +21,7 @@ class Synched extends Stmt { } } -from MethodAccess ma, SynchronizedStmt synch +from MethodCall ma, SynchronizedStmt synch where ma.getMethod().hasName("wait") and ma.getMethod().getDeclaringType().hasQualifiedName("java.lang", "Object") and diff --git a/java/ql/src/Likely Bugs/Concurrency/YieldCalls.ql b/java/ql/src/Likely Bugs/Concurrency/YieldCalls.ql index 91ae12b6464c..0d2bd62d0da8 100644 --- a/java/ql/src/Likely Bugs/Concurrency/YieldCalls.ql +++ b/java/ql/src/Likely Bugs/Concurrency/YieldCalls.ql @@ -20,11 +20,11 @@ class YieldMethod extends Method { } } -class YieldMethodAccess extends MethodAccess { - YieldMethodAccess() { this.getMethod() instanceof YieldMethod } +class YieldMethodCall extends MethodCall { + YieldMethodCall() { this.getMethod() instanceof YieldMethod } } -from YieldMethodAccess yield +from YieldMethodCall yield where yield.getCompilationUnit().fromSource() select yield, "Do not use Thread.yield(). It is non-portable and will most likely not have the desired effect." diff --git a/java/ql/src/Likely Bugs/Frameworks/Swing/BadlyOverriddenAdapter.ql b/java/ql/src/Likely Bugs/Frameworks/Swing/BadlyOverriddenAdapter.ql index 2d9d49802bfe..3d4f62707344 100644 --- a/java/ql/src/Likely Bugs/Frameworks/Swing/BadlyOverriddenAdapter.ql +++ b/java/ql/src/Likely Bugs/Frameworks/Swing/BadlyOverriddenAdapter.ql @@ -31,7 +31,7 @@ where exists(Method original | adapter = original.getDeclaringType() | m.getName() = original.getName()) and not exists(Method overridden | adapter = overridden.getDeclaringType() | m.overrides(overridden)) and // The method is not used for any other purpose. - not exists(MethodAccess ma | ma.getMethod() = m) + not exists(MethodCall ma | ma.getMethod() = m) select m, "Method " + m.getName() + " attempts to override a method in " + adapter.getName() + ", but does not have the same argument types. " + m.getName() + diff --git a/java/ql/src/Likely Bugs/Frameworks/Swing/ThreadSafety.ql b/java/ql/src/Likely Bugs/Frameworks/Swing/ThreadSafety.ql index 7feac69647e1..8d49cf1d59e8 100644 --- a/java/ql/src/Likely Bugs/Frameworks/Swing/ThreadSafety.ql +++ b/java/ql/src/Likely Bugs/Frameworks/Swing/ThreadSafety.ql @@ -13,7 +13,7 @@ import java -from MethodAccess ma, Method m, MainMethod main +from MethodCall ma, Method m, MainMethod main where ma.getQualifier().getType().getCompilationUnit().getPackage().getName().matches("javax.swing%") and ( diff --git a/java/ql/src/Likely Bugs/I18N/MissingLocaleArgument.ql b/java/ql/src/Likely Bugs/I18N/MissingLocaleArgument.ql index 2af7402661c1..0285aca36f4a 100644 --- a/java/ql/src/Likely Bugs/I18N/MissingLocaleArgument.ql +++ b/java/ql/src/Likely Bugs/I18N/MissingLocaleArgument.ql @@ -12,7 +12,7 @@ import java -from MethodAccess ma, Method changecase +from MethodCall ma, Method changecase where ( changecase.hasName("toUpperCase") or diff --git a/java/ql/src/Likely Bugs/Inheritance/NoNonFinalInConstructor.ql b/java/ql/src/Likely Bugs/Inheritance/NoNonFinalInConstructor.ql index ece8007eab99..618160538970 100644 --- a/java/ql/src/Likely Bugs/Inheritance/NoNonFinalInConstructor.ql +++ b/java/ql/src/Likely Bugs/Inheritance/NoNonFinalInConstructor.ql @@ -27,7 +27,7 @@ private FieldRead nonFinalFieldRead(Callable m, Field f) { not f.isFinal() } -private MethodAccess unqualifiedCallToNonAbstractMethod(Constructor c, Method m) { +private MethodCall unqualifiedCallToNonAbstractMethod(Constructor c, Method m) { result.getEnclosingCallable() = c and ( not exists(result.getQualifier()) or @@ -38,7 +38,7 @@ private MethodAccess unqualifiedCallToNonAbstractMethod(Constructor c, Method m) } from - Constructor c, MethodAccess ma, Method m, Method n, Field f, FieldRead fa, Constructor d, + Constructor c, MethodCall ma, Method m, Method n, Field f, FieldRead fa, Constructor d, FieldWrite fw where // Method access in a constructor diff --git a/java/ql/src/Likely Bugs/Likely Typos/ContainerSizeCmpZero.ql b/java/ql/src/Likely Bugs/Likely Typos/ContainerSizeCmpZero.ql index 90044ab25953..01f0ceac56cd 100644 --- a/java/ql/src/Likely Bugs/Likely Typos/ContainerSizeCmpZero.ql +++ b/java/ql/src/Likely Bugs/Likely Typos/ContainerSizeCmpZero.ql @@ -27,21 +27,21 @@ class ArrayLengthRead extends FieldRead, SizeOfContainer { } /** An access to `String.length()`. */ -class StringLengthRead extends MethodAccess, SizeOfContainer { +class StringLengthRead extends MethodCall, SizeOfContainer { StringLengthRead() { this.getMethod() instanceof StringLengthMethod } override string getContainerKind() { result = "a string" } } /** An access to `Collection.size()`. */ -class CollectionSizeCall extends MethodAccess, SizeOfContainer { +class CollectionSizeCall extends MethodCall, SizeOfContainer { CollectionSizeCall() { this.getMethod() instanceof CollectionSizeMethod } override string getContainerKind() { result = "a collection" } } /** An access to `Map.size()`. */ -class MapSizeCall extends MethodAccess, SizeOfContainer { +class MapSizeCall extends MethodCall, SizeOfContainer { MapSizeCall() { this.getMethod() instanceof MapSizeMethod } override string getContainerKind() { result = "a map" } diff --git a/java/ql/src/Likely Bugs/Likely Typos/DangerousNonCircuitLogic.ql b/java/ql/src/Likely Bugs/Likely Typos/DangerousNonCircuitLogic.ql index 738a26518fc5..8d9409059f8e 100644 --- a/java/ql/src/Likely Bugs/Likely Typos/DangerousNonCircuitLogic.ql +++ b/java/ql/src/Likely Bugs/Likely Typos/DangerousNonCircuitLogic.ql @@ -18,7 +18,7 @@ import java class DangerousExpression extends Expr { DangerousExpression() { exists(Expr e | this = e.getParent*() | - e instanceof MethodAccess or + e instanceof MethodCall or e instanceof ArrayAccess or exists(e.(FieldAccess).getQualifier()) ) diff --git a/java/ql/src/Likely Bugs/Reflection/AnnotationPresentCheck.ql b/java/ql/src/Likely Bugs/Reflection/AnnotationPresentCheck.ql index 2bffa1ea4f49..0bfb4b45a5a5 100644 --- a/java/ql/src/Likely Bugs/Reflection/AnnotationPresentCheck.ql +++ b/java/ql/src/Likely Bugs/Reflection/AnnotationPresentCheck.ql @@ -12,7 +12,7 @@ import java -from MethodAccess c, Method m, ParameterizedClass p, AnnotationType t +from MethodCall c, Method m, ParameterizedClass p, AnnotationType t where c.getMethod() = m and m.hasName("isAnnotationPresent") and diff --git a/java/ql/src/Likely Bugs/Resource Leaks/CloseType.qll b/java/ql/src/Likely Bugs/Resource Leaks/CloseType.qll index 42bcc8472ebf..53b213aa3be0 100644 --- a/java/ql/src/Likely Bugs/Resource Leaks/CloseType.qll +++ b/java/ql/src/Likely Bugs/Resource Leaks/CloseType.qll @@ -42,8 +42,8 @@ private predicate closeableType(RefType t) { * An access to a method on a type in the 'java.sql` package that creates a closeable object in the `java.sql` package. * For example, `PreparedStatement.executeQuery()` or `Connection.prepareStatement(String)`. */ -class SqlResourceOpeningMethodAccess extends MethodAccess { - SqlResourceOpeningMethodAccess() { +class SqlResourceOpeningMethodCall extends MethodCall { + SqlResourceOpeningMethodCall() { exists(Method m | this.getMethod() = m | m.getDeclaringType().hasQualifiedName("java.sql", _) and m.getReturnType().(RefType).hasQualifiedName("java.sql", _) and @@ -54,13 +54,16 @@ class SqlResourceOpeningMethodAccess extends MethodAccess { } } +/** DEPRECATED: Alias for `SqlResourceOpeningMethodCall`. */ +deprecated class SqlResourceOpeningMethodAccess = SqlResourceOpeningMethodCall; + /** * A candidate for a "closeable init" expression, which may require calling a "close" method. */ class CloseableInitExpr extends Expr { CloseableInitExpr() { this instanceof ClassInstanceExpr or - this instanceof SqlResourceOpeningMethodAccess + this instanceof SqlResourceOpeningMethodCall } } @@ -86,7 +89,7 @@ private predicate closeableInit(Expr e, Expr parent) { ) ) or - exists(SqlResourceOpeningMethodAccess ma | ma = e and parent = e) + exists(SqlResourceOpeningMethodCall ma | ma = e and parent = e) or exists(LocalVariableDecl v, Expr f | e = v.getAnAccess() and flowsInto(f, v) | closeableInit(f, parent) @@ -218,7 +221,7 @@ private predicate closeCalled(Variable v) { exists(TryStmt try | try.getAResourceVariable() = v) or // Otherwise, there should be an explicit call to a method whose name contains "close". - exists(MethodAccess e | + exists(MethodCall e | v = getCloseableVariable(_) or v instanceof Parameter or v instanceof LocalVariableDecl | e.getMethod().getName().toLowerCase().matches("%close%") and @@ -263,7 +266,7 @@ private predicate closedResource(CloseableInitExpr cie) { } private predicate immediatelyClosed(ClassInstanceExpr cie) { - exists(MethodAccess ma | ma.getQualifier() = cie | ma.getMethod().hasName("close")) + exists(MethodCall ma | ma.getQualifier() = cie | ma.getMethod().hasName("close")) } /** @@ -305,10 +308,10 @@ predicate noNeedToClose(CloseableInitExpr cie) { flowsInto(sqlStmt, v) and closedResource(sqlStmt) and cie.getType() instanceof TypeResultSet and - cie.(SqlResourceOpeningMethodAccess).getQualifier() = v.getAnAccess() + cie.(SqlResourceOpeningMethodCall).getQualifier() = v.getAnAccess() ) or - exists(MethodAccess ma | cie.(ClassInstanceExpr).getAnArgument() = ma | + exists(MethodCall ma | cie.(ClassInstanceExpr).getAnArgument() = ma | ma.getMethod() instanceof ServletResponseGetOutputStreamMethod or ma.getMethod() instanceof ServletResponseGetWriterMethod or ma.getMethod() instanceof ServletRequestGetBodyMethod diff --git a/java/ql/src/Likely Bugs/Statements/Chaining.qll b/java/ql/src/Likely Bugs/Statements/Chaining.qll index b8fdb63facec..bb7fba549e7b 100644 --- a/java/ql/src/Likely Bugs/Statements/Chaining.qll +++ b/java/ql/src/Likely Bugs/Statements/Chaining.qll @@ -35,8 +35,8 @@ private predicate nonChainingReturn(Method m, ReturnStmt ret) { ret.getResult().getType() != m.getDeclaringType() or // A method call to the wrong method is returned. - ret.getResult() instanceof MethodAccess and - exists(MethodAccess delegateCall, Method delegate | + ret.getResult() instanceof MethodCall and + exists(MethodCall delegateCall, Method delegate | delegateCall = ret.getResult() and delegate = delegateCall.getMethod() | @@ -47,7 +47,7 @@ private predicate nonChainingReturn(Method m, ReturnStmt ret) { not hasDescendant(m.getReturnType(), delegate.getReturnType()) or // A method on the wrong object is called. - not delegateCall.isOwnMethodAccess() + not delegateCall.isOwnMethodCall() or nonChaining(delegate) ) @@ -55,6 +55,6 @@ private predicate nonChainingReturn(Method m, ReturnStmt ret) { // Something else is returned. not ( ret.getResult() instanceof ThisAccess or - ret.getResult() instanceof MethodAccess + ret.getResult() instanceof MethodCall ) } diff --git a/java/ql/src/Likely Bugs/Statements/InconsistentCallOnResult.ql b/java/ql/src/Likely Bugs/Statements/InconsistentCallOnResult.ql index 6526a24cc5f9..fe47661def4b 100644 --- a/java/ql/src/Likely Bugs/Statements/InconsistentCallOnResult.ql +++ b/java/ql/src/Likely Bugs/Statements/InconsistentCallOnResult.ql @@ -33,7 +33,7 @@ predicate exclude(Method m) { * - is different from `callToCheck`, and * - is not a call to an excluded method. */ -predicate checkExpr(MethodAccess callToCheck, MethodAccess otherCall, string operation, Variable v) { +predicate checkExpr(MethodCall callToCheck, MethodCall otherCall, string operation, Variable v) { not exclude(otherCall.getMethod()) and v.getAnAssignedValue() = callToCheck and otherCall != callToCheck and @@ -47,7 +47,7 @@ predicate checkExpr(MethodAccess callToCheck, MethodAccess otherCall, string ope /** * Holds if `operation` is implicitly called on `v`, and `v` is assigned the result of `callToCheck`. */ -predicate implicitCheckExpr(MethodAccess callToCheck, string operation, Variable v) { +predicate implicitCheckExpr(MethodCall callToCheck, string operation, Variable v) { exists(TryStmt try, LocalVariableDeclExpr decl | try.getAResourceDecl().getAVariable() = decl and decl.getVariable() = v and @@ -62,7 +62,7 @@ predicate implicitCheckExpr(MethodAccess callToCheck, string operation, Variable Expr getChainedAccess(Variable v) { result = v.getAnAccess() or - exists(MethodAccess chainedAccess | chainedAccess.getQualifier() = getChainedAccess(v) | + exists(MethodCall chainedAccess | chainedAccess.getQualifier() = getChainedAccess(v) | designedForChaining(chainedAccess.getMethod()) and result = chainedAccess ) } @@ -70,7 +70,7 @@ Expr getChainedAccess(Variable v) { /** * The result of `ma` and a call to a method named `operation` are both assigned to the same variable. */ -predicate checkedFunctionCall(MethodAccess ma, string operation) { +predicate checkedFunctionCall(MethodCall ma, string operation) { relevantFunctionCall(ma, _) and exists(Variable v | not v instanceof Field | v.getAnAssignedValue() = ma and @@ -81,24 +81,24 @@ predicate checkedFunctionCall(MethodAccess ma, string operation) { /** * The method access `ma` is a call to `m` where the result is assigned. */ -predicate relevantFunctionCall(MethodAccess ma, Method m) { +predicate relevantFunctionCall(MethodCall ma, Method m) { ma.getMethod() = m and exists(Variable v | v.getAnAssignedValue() = ma) and not okToIgnore(ma) } -predicate okToIgnore(MethodAccess ma) { not ma.getCompilationUnit().fromSource() } +predicate okToIgnore(MethodCall ma) { not ma.getCompilationUnit().fromSource() } predicate functionStats(Method m, string operation, int used, int total, int percentage) { m.getReturnType() instanceof RefType and // Calls to `m` where we also perform `operation`. - used = strictcount(MethodAccess ma | checkedFunctionCall(ma, operation) and m = ma.getMethod()) and + used = strictcount(MethodCall ma | checkedFunctionCall(ma, operation) and m = ma.getMethod()) and // Calls to `m`. - total = strictcount(MethodAccess ma | relevantFunctionCall(ma, m)) and + total = strictcount(MethodCall ma | relevantFunctionCall(ma, m)) and percentage = used * 100 / total } -from MethodAccess unchecked, Method m, string operation, int percent +from MethodCall unchecked, Method m, string operation, int percent where relevantFunctionCall(unchecked, m) and not checkedFunctionCall(unchecked, operation) and diff --git a/java/ql/src/Likely Bugs/Statements/ReturnValueIgnored.ql b/java/ql/src/Likely Bugs/Statements/ReturnValueIgnored.ql index c50a9a5f1a48..f3861dd6174d 100644 --- a/java/ql/src/Likely Bugs/Statements/ReturnValueIgnored.ql +++ b/java/ql/src/Likely Bugs/Statements/ReturnValueIgnored.ql @@ -16,7 +16,7 @@ import java import Chaining -predicate checkedMethodCall(MethodAccess ma) { +predicate checkedMethodCall(MethodCall ma) { relevantMethodCall(ma, _) and not ma instanceof ValueDiscardingExpr } @@ -73,31 +73,31 @@ predicate isMustBeQualifierMockingMethod(Method m) { m.hasName("verify") } -predicate relevantMethodCall(MethodAccess ma, Method m) { +predicate relevantMethodCall(MethodCall ma, Method m) { // For "return value ignored", all method calls are relevant. not ma.getFile().isKotlinSourceFile() and ma.getMethod() = m and not m.getReturnType().hasName("void") and (not isMockingMethod(m) or isMustBeQualifierMockingMethod(m)) and - not isMockingMethod(ma.getQualifier().(MethodAccess).getMethod()) + not isMockingMethod(ma.getQualifier().(MethodCall).getMethod()) } predicate methodStats(Method m, int used, int total, int percentage) { - used = strictcount(MethodAccess ma | checkedMethodCall(ma) and m = ma.getMethod()) and - total = strictcount(MethodAccess ma | relevantMethodCall(ma, m)) and + used = strictcount(MethodCall ma | checkedMethodCall(ma) and m = ma.getMethod()) and + total = strictcount(MethodCall ma | relevantMethodCall(ma, m)) and percentage = used * 100 / total } int chainedUses(Method m) { result = - count(MethodAccess ma, MethodAccess qual | + count(MethodCall ma, MethodCall qual | ma.getMethod() = m and ma.getQualifier() = qual and qual.getMethod() = m ) } -from MethodAccess unchecked, Method m, int percent, int total +from MethodCall unchecked, Method m, int percent, int total where relevantMethodCall(unchecked, m) and not checkedMethodCall(unchecked) and diff --git a/java/ql/src/Likely Bugs/Termination/ConstantLoopCondition.ql b/java/ql/src/Likely Bugs/Termination/ConstantLoopCondition.ql index 0b3c12560501..7dc893edaef9 100644 --- a/java/ql/src/Likely Bugs/Termination/ConstantLoopCondition.ql +++ b/java/ql/src/Likely Bugs/Termination/ConstantLoopCondition.ql @@ -73,12 +73,12 @@ where loopWhileTrue(loop) and loopExitGuard(loop, cond) ) and // None of the ssa variables in `cond` are updated inside the loop. - forex(SsaVariable ssa, RValue use | ssa.getAUse() = use and use.getParent*() = cond | + forex(SsaVariable ssa, VarRead use | ssa.getAUse() = use and use.getParent*() = cond | not ssa.getCfgNode().getEnclosingStmt().getEnclosingStmt*() = loop or ssa.getCfgNode().(Expr).getParent*() = loop.(ForStmt).getAnInit() ) and // And `cond` does not use method calls, field reads, or array reads. - not exists(MethodAccess ma | ma.getParent*() = cond) and + not exists(MethodCall ma | ma.getParent*() = cond) and not exists(FieldRead fa | // Ignore if field is final not fa.getField().isFinal() and diff --git a/java/ql/src/Performance/InefficientEmptyStringTest.ql b/java/ql/src/Performance/InefficientEmptyStringTest.ql index f51b4d964bd6..0033bcf12845 100644 --- a/java/ql/src/Performance/InefficientEmptyStringTest.ql +++ b/java/ql/src/Performance/InefficientEmptyStringTest.ql @@ -11,7 +11,7 @@ import java -from MethodAccess mc +from MethodCall mc where mc.getQualifier().getType() instanceof TypeString and mc.getMethod().hasName("equals") and diff --git a/java/ql/src/Performance/InefficientKeySetIterator.ql b/java/ql/src/Performance/InefficientKeySetIterator.ql index 2b7f1e248967..2dbe8831cb12 100644 --- a/java/ql/src/Performance/InefficientKeySetIterator.ql +++ b/java/ql/src/Performance/InefficientKeySetIterator.ql @@ -14,25 +14,25 @@ import java /** A local variable that is initialized using a key-set iterator. */ class KeySetIterator extends LocalVariableDecl { KeySetIterator() { - exists(LocalVariableDeclExpr lvde, MethodAccess init | + exists(LocalVariableDeclExpr lvde, MethodCall init | lvde.getVariable() = this and lvde.getInit() = init and init.getMethod().hasName("iterator") and - init.getQualifier().(MethodAccess).getMethod().hasName("keySet") + init.getQualifier().(MethodCall).getMethod().hasName("keySet") ) } LocalVariableDecl getBase() { - exists(LocalVariableDeclExpr lvde, MethodAccess init | + exists(LocalVariableDeclExpr lvde, MethodCall init | lvde.getVariable() = this and lvde.getInit() = init and - init.getQualifier().(MethodAccess).getQualifier().(VarAccess).getVariable() = result + init.getQualifier().(MethodCall).getQualifier().(VarAccess).getVariable() = result ) } } predicate isKeyNext(Expr e, KeySetIterator it) { - exists(MethodAccess ma | ma = e | + exists(MethodCall ma | ma = e | ma.getMethod().hasName("next") and ma.getQualifier().(VarAccess).getVariable() = it ) @@ -56,7 +56,7 @@ class Key extends LocalVariableDecl { } } -from MethodAccess ma, Method get +from MethodCall ma, Method get where ma.getMethod() = get and get.hasName("get") and diff --git a/java/ql/src/Performance/InefficientOutputStream.ql b/java/ql/src/Performance/InefficientOutputStream.ql index e0b501a886cb..5ddf568b79af 100644 --- a/java/ql/src/Performance/InefficientOutputStream.ql +++ b/java/ql/src/Performance/InefficientOutputStream.ql @@ -34,7 +34,7 @@ where ) and // If that method doesn't call write itself, then we don't have a problem. // This is the case is some dummy implementations. - exists(MethodAccess ma | ma.getEnclosingCallable() = m | ma.getMethod().getName() = "write") + exists(MethodCall ma | ma.getEnclosingCallable() = m | ma.getMethod().getName() = "write") select c, "This class extends 'java.io.OutputStream' and implements $@, but does not override 'write(byte[],int,int)'.", m, m.getName() diff --git a/java/ql/src/Performance/InnerClassCouldBeStatic.ql b/java/ql/src/Performance/InnerClassCouldBeStatic.ql index 67ee835b747a..95d3057c9629 100644 --- a/java/ql/src/Performance/InnerClassCouldBeStatic.ql +++ b/java/ql/src/Performance/InnerClassCouldBeStatic.ql @@ -74,7 +74,7 @@ RefType enclosingInstanceAccess(Expr expr) { not inherits(enclosing, fa.getVariable()) ) or - exists(MethodAccess ma | ma = expr | + exists(MethodCall ma | ma = expr | result = ma.getMethod().getDeclaringType() and not exists(ma.getQualifier()) and not ma.getMethod().isStatic() and diff --git a/java/ql/src/Security/CWE/CWE-023/PartialPathTraversal.ql b/java/ql/src/Security/CWE/CWE-023/PartialPathTraversal.ql index 5b6a081f07a7..9d987ae7d0cd 100644 --- a/java/ql/src/Security/CWE/CWE-023/PartialPathTraversal.ql +++ b/java/ql/src/Security/CWE/CWE-023/PartialPathTraversal.ql @@ -12,5 +12,5 @@ import semmle.code.java.security.PartialPathTraversal -from PartialPathTraversalMethodAccess ma +from PartialPathTraversalMethodCall ma select ma, "Partial Path Traversal Vulnerability due to insufficient guard against path traversal." diff --git a/java/ql/src/Security/CWE/CWE-079/AndroidWebViewAddJavascriptInterface.ql b/java/ql/src/Security/CWE/CWE-079/AndroidWebViewAddJavascriptInterface.ql index 8f866c7b5cc8..4368b537ab7c 100644 --- a/java/ql/src/Security/CWE/CWE-079/AndroidWebViewAddJavascriptInterface.ql +++ b/java/ql/src/Security/CWE/CWE-079/AndroidWebViewAddJavascriptInterface.ql @@ -13,6 +13,6 @@ import java import semmle.code.java.frameworks.android.WebView -from MethodAccess ma +from MethodCall ma where ma.getMethod() instanceof WebViewAddJavascriptInterfaceMethod select ma, "JavaScript interface to Java object added in Android WebView." diff --git a/java/ql/src/Security/CWE/CWE-079/AndroidWebViewSettingsEnabledJavaScript.ql b/java/ql/src/Security/CWE/CWE-079/AndroidWebViewSettingsEnabledJavaScript.ql index 2e5b2a0d375b..561b2af8de02 100644 --- a/java/ql/src/Security/CWE/CWE-079/AndroidWebViewSettingsEnabledJavaScript.ql +++ b/java/ql/src/Security/CWE/CWE-079/AndroidWebViewSettingsEnabledJavaScript.ql @@ -13,7 +13,7 @@ import java import semmle.code.java.frameworks.android.WebView -from MethodAccess ma +from MethodCall ma where ma.getMethod() instanceof AllowJavaScriptMethod and ma.getArgument(0).(CompileTimeConstantExpr).getBooleanValue() = true diff --git a/java/ql/src/Security/CWE/CWE-200/AndroidWebViewSettingsAllowsContentAccess.ql b/java/ql/src/Security/CWE/CWE-200/AndroidWebViewSettingsAllowsContentAccess.ql index 6fd6da06a27b..bd5cc2a5b76f 100644 --- a/java/ql/src/Security/CWE/CWE-200/AndroidWebViewSettingsAllowsContentAccess.ql +++ b/java/ql/src/Security/CWE/CWE-200/AndroidWebViewSettingsAllowsContentAccess.ql @@ -24,8 +24,8 @@ private class TypeWebViewOrSubclass extends RefType { * * In Kotlin, member accesses are translated to getter methods. */ -private class PrivateGetterMethodAccess extends MethodAccess { - PrivateGetterMethodAccess() { +private class PrivateGetterMethodCall extends MethodCall { + PrivateGetterMethodCall() { this.getMethod() instanceof GetterMethod and this.getMethod().isPrivate() } @@ -39,11 +39,11 @@ class WebViewSource extends DataFlow::Node { // constructor and method calls, or method accesses which are cast to WebView. ( this.asExpr() instanceof ClassInstanceExpr or - this.asExpr() instanceof MethodAccess or - this.asExpr().(CastExpr).getAChildExpr() instanceof MethodAccess + this.asExpr() instanceof MethodCall or + this.asExpr().(CastExpr).getAChildExpr() instanceof MethodCall ) and // Avoid duplicate results from Kotlin member accesses. - not this.asExpr() instanceof PrivateGetterMethodAccess + not this.asExpr() instanceof PrivateGetterMethodCall } } @@ -53,7 +53,7 @@ class WebViewSource extends DataFlow::Node { */ class WebSettingsDisallowContentAccessSink extends DataFlow::Node { WebSettingsDisallowContentAccessSink() { - exists(MethodAccess ma | + exists(MethodCall ma | ma.getQualifier() = this.asExpr() and ma.getMethod() instanceof AllowContentAccessMethod and ma.getArgument(0).(CompileTimeConstantExpr).getBooleanValue() = false @@ -86,7 +86,7 @@ module WebViewDisallowContentAccessConfig implements DataFlow::StateConfigSig { state2 instanceof IsSettings and // settings = webView.getSettings() // ^node2 = ^node1 - exists(MethodAccess ma | + exists(MethodCall ma | ma = node2.asExpr() and ma.getQualifier() = node1.asExpr() and ma.getMethod() instanceof WebViewGetSettingsMethod @@ -105,7 +105,7 @@ module WebViewDisallowContentAccessFlow = from Expr e where // explicit: setAllowContentAccess(true) - exists(MethodAccess ma | + exists(MethodCall ma | ma = e and ma.getMethod() instanceof AllowContentAccessMethod and ma.getArgument(0).(CompileTimeConstantExpr).getBooleanValue() = true diff --git a/java/ql/src/Security/CWE/CWE-200/AndroidWebViewSettingsFileAccess.ql b/java/ql/src/Security/CWE/CWE-200/AndroidWebViewSettingsFileAccess.ql index 86c4a24dd5ee..86a8038d5082 100644 --- a/java/ql/src/Security/CWE/CWE-200/AndroidWebViewSettingsFileAccess.ql +++ b/java/ql/src/Security/CWE/CWE-200/AndroidWebViewSettingsFileAccess.ql @@ -13,7 +13,7 @@ import java import semmle.code.java.frameworks.android.WebView -from MethodAccess ma +from MethodCall ma where ma.getMethod() instanceof CrossOriginAccessMethod and ma.getArgument(0).(CompileTimeConstantExpr).getBooleanValue() = true diff --git a/java/ql/src/Security/CWE/CWE-200/TempDirLocalInformationDisclosure.ql b/java/ql/src/Security/CWE/CWE-200/TempDirLocalInformationDisclosure.ql index 489de5a7ba4e..6efb7e9104c6 100644 --- a/java/ql/src/Security/CWE/CWE-200/TempDirLocalInformationDisclosure.ql +++ b/java/ql/src/Security/CWE/CWE-200/TempDirLocalInformationDisclosure.ql @@ -24,18 +24,16 @@ import semmle.code.java.security.TempDirLocalInformationDisclosureQuery * We achieve this by making inherently-insecure method invocations into an edge-less graph, * resulting in a zero-length paths. */ -module InsecureMethodPathGraph implements DataFlow::PathGraphSig { - predicate edges(MethodAccessInsecureFileCreation n1, MethodAccessInsecureFileCreation n2) { - none() - } +module InsecureMethodPathGraph implements DataFlow::PathGraphSig { + predicate edges(MethodCallInsecureFileCreation n1, MethodCallInsecureFileCreation n2) { none() } - predicate nodes(MethodAccessInsecureFileCreation n, string key, string val) { + predicate nodes(MethodCallInsecureFileCreation n, string key, string val) { key = "semmle.label" and val = n.toString() } predicate subpaths( - MethodAccessInsecureFileCreation n1, MethodAccessInsecureFileCreation n2, - MethodAccessInsecureFileCreation n3, MethodAccessInsecureFileCreation n4 + MethodCallInsecureFileCreation n1, MethodCallInsecureFileCreation n2, + MethodCallInsecureFileCreation n3, MethodCallInsecureFileCreation n4 ) { none() } @@ -43,7 +41,7 @@ module InsecureMethodPathGraph implements DataFlow::PathGraphSig; import Flow::PathGraph diff --git a/java/ql/src/Security/CWE/CWE-297/InsecureJavaMail.ql b/java/ql/src/Security/CWE/CWE-297/InsecureJavaMail.ql index d19bbeda9ef9..d4fe25d0f40b 100644 --- a/java/ql/src/Security/CWE/CWE-297/InsecureJavaMail.ql +++ b/java/ql/src/Security/CWE/CWE-297/InsecureJavaMail.ql @@ -15,7 +15,7 @@ import java import semmle.code.java.security.Mail -from MethodAccess ma +from MethodCall ma where ma.getMethod() instanceof MailSessionGetInstanceMethod and isInsecureMailPropertyConfig(ma.getArgument(0).(VarAccess).getVariable()) diff --git a/java/ql/src/Security/CWE/CWE-312/CleartextStorageAndroidDatabase.ql b/java/ql/src/Security/CWE/CWE-312/CleartextStorageAndroidDatabase.ql index e428566cbaa3..759060257863 100644 --- a/java/ql/src/Security/CWE/CWE-312/CleartextStorageAndroidDatabase.ql +++ b/java/ql/src/Security/CWE/CWE-312/CleartextStorageAndroidDatabase.ql @@ -15,7 +15,7 @@ import java import semmle.code.java.security.CleartextStorageAndroidDatabaseQuery -from SensitiveSource data, LocalDatabaseOpenMethodAccess s, Expr input, Expr store +from SensitiveSource data, LocalDatabaseOpenMethodCall s, Expr input, Expr store where input = s.getAnInput() and store = s.getAStore() and diff --git a/java/ql/src/Security/CWE/CWE-312/CleartextStorageSharedPrefs.ql b/java/ql/src/Security/CWE/CWE-312/CleartextStorageSharedPrefs.ql index af188931be77..e872c2c100db 100644 --- a/java/ql/src/Security/CWE/CWE-312/CleartextStorageSharedPrefs.ql +++ b/java/ql/src/Security/CWE/CWE-312/CleartextStorageSharedPrefs.ql @@ -15,7 +15,7 @@ import java import semmle.code.java.security.CleartextStorageSharedPrefsQuery -from SensitiveSource data, SharedPreferencesEditorMethodAccess s, Expr input, Expr store +from SensitiveSource data, SharedPreferencesEditorMethodCall s, Expr input, Expr store where input = s.getAnInput() and store = s.getAStore() and diff --git a/java/ql/src/Security/CWE/CWE-319/UseSSL.ql b/java/ql/src/Security/CWE/CWE-319/UseSSL.ql index e9bf5ed0ed2b..6e00e3d7f113 100644 --- a/java/ql/src/Security/CWE/CWE-319/UseSSL.ql +++ b/java/ql/src/Security/CWE/CWE-319/UseSSL.ql @@ -25,7 +25,7 @@ class Socket extends RefType { Socket() { this.getAnAncestor().hasQualifiedName("java.net", "Socket") } } -from MethodAccess m, Class c, string type +from MethodCall m, Class c, string type where m.getQualifier().getType() = c and ( diff --git a/java/ql/src/Security/CWE/CWE-319/UseSSLSocketFactories.ql b/java/ql/src/Security/CWE/CWE-319/UseSSLSocketFactories.ql index abf68b465fe5..1ea08ca73194 100644 --- a/java/ql/src/Security/CWE/CWE-319/UseSSLSocketFactories.ql +++ b/java/ql/src/Security/CWE/CWE-319/UseSSLSocketFactories.ql @@ -56,7 +56,7 @@ predicate methodInfo(Method m, RefType t, string name) { m.getName() = name } -predicate query(MethodAccess m, Method def, int paramNo, string message, Element evidence) { +predicate query(MethodCall m, Method def, int paramNo, string message, Element evidence) { m.getMethod() = def and // Using a networking method. def.getDeclaringType() instanceof NetworkClass and @@ -76,6 +76,6 @@ predicate query(MethodAccess m, Method def, int paramNo, string message, Element ) } -from MethodAccess m, Method def, int param, string message, Element evidence +from MethodCall m, Method def, int param, string message, Element evidence where query(m, def, param, message, evidence) select m, "Method " + message + ": use an SSL factory." diff --git a/java/ql/src/Security/CWE/CWE-335/PredictableSeed.ql b/java/ql/src/Security/CWE/CWE-335/PredictableSeed.ql index 1941b8fd10ce..be16829fcc30 100644 --- a/java/ql/src/Security/CWE/CWE-335/PredictableSeed.ql +++ b/java/ql/src/Security/CWE/CWE-335/PredictableSeed.ql @@ -14,7 +14,7 @@ import java import semmle.code.java.security.RandomQuery -from GetRandomData da, RValue use, PredictableSeedExpr source +from GetRandomData da, VarRead use, PredictableSeedExpr source where da.getQualifier() = use and unsafelySeeded(use, source) diff --git a/java/ql/src/Security/CWE/CWE-338/JHipsterGeneratedPRNG.ql b/java/ql/src/Security/CWE/CWE-338/JHipsterGeneratedPRNG.ql index de7a5743a56b..c51e5d4acc57 100644 --- a/java/ql/src/Security/CWE/CWE-338/JHipsterGeneratedPRNG.ql +++ b/java/ql/src/Security/CWE/CWE-338/JHipsterGeneratedPRNG.ql @@ -21,8 +21,8 @@ private class PredictableApacheRandomStringUtilsMethod extends Method { } } -private class PredictableApacheRandomStringUtilsMethodAccess extends MethodAccess { - PredictableApacheRandomStringUtilsMethodAccess() { +private class PredictableApacheRandomStringUtilsMethodCall extends MethodCall { + PredictableApacheRandomStringUtilsMethodCall() { this.getMethod() instanceof PredictableApacheRandomStringUtilsMethod } } @@ -41,7 +41,7 @@ private class VulnerableJHipsterRandomUtilMethod extends Method { this.getReturnType() instanceof TypeString and exists(ReturnStmt s | s = this.getBody().(SingletonBlock).getStmt() and - s.getResult() instanceof PredictableApacheRandomStringUtilsMethodAccess + s.getResult() instanceof PredictableApacheRandomStringUtilsMethodCall ) } } diff --git a/java/ql/src/Security/CWE/CWE-352/SpringCSRFProtection.ql b/java/ql/src/Security/CWE/CWE-352/SpringCSRFProtection.ql index 2ce5d5797ba6..dfb6fbbd5956 100644 --- a/java/ql/src/Security/CWE/CWE-352/SpringCSRFProtection.ql +++ b/java/ql/src/Security/CWE/CWE-352/SpringCSRFProtection.ql @@ -14,6 +14,6 @@ import java import semmle.code.java.security.SpringCsrfProtection -from MethodAccess call +from MethodCall call where disablesSpringCsrfProtection(call) select call, "CSRF vulnerability due to protection being disabled." diff --git a/java/ql/src/Security/CWE/CWE-367/TOCTOURace.ql b/java/ql/src/Security/CWE/CWE-367/TOCTOURace.ql index 55dcaeb2de49..ca2c948867f8 100644 --- a/java/ql/src/Security/CWE/CWE-367/TOCTOURace.ql +++ b/java/ql/src/Security/CWE/CWE-367/TOCTOURace.ql @@ -28,7 +28,7 @@ predicate commonSynchronization(Expr e1, Expr e2, Variable monitor) { /** * Holds if `m` is a call to a synchronized method on `receiver`. */ -predicate synchCallOn(MethodAccess m, Variable receiver) { +predicate synchCallOn(MethodCall m, Variable receiver) { m.getCallee() instanceof SynchronizedCallable and m.getQualifier() = receiver.getAnAccess() } @@ -98,7 +98,7 @@ predicate probablyNeverEscapes(LocalVariableDecl v) { } // Loop conditions tend to be uninteresting, so are not included. -from IfStmt check, MethodAccess call1, MethodAccess call2, Variable r +from IfStmt check, MethodCall call1, MethodCall call2, Variable r where check.getCondition().getAChildExpr*() = call1 and // This can happen if there are loops, etc. diff --git a/java/ql/src/Security/CWE/CWE-421/SocketAuthRace.ql b/java/ql/src/Security/CWE/CWE-421/SocketAuthRace.ql index c8515f2b0850..6e6e885c812a 100644 --- a/java/ql/src/Security/CWE/CWE-421/SocketAuthRace.ql +++ b/java/ql/src/Security/CWE/CWE-421/SocketAuthRace.ql @@ -53,7 +53,7 @@ predicate controlledByAuth(Expr controlled, Expr condition) { exists(ConditionBlock b | condition = b.getCondition() and b.controls(controlled.getBasicBlock(), _) and - condition.(MethodAccess).getMethod() instanceof AuthMethod + condition.(MethodCall).getMethod() instanceof AuthMethod ) } @@ -71,7 +71,7 @@ predicate controlledByAuth(Expr controlled, Expr condition) { * no idea which ones were meant to be secure. */ -from MethodAccess connection, Expr condition +from MethodCall connection, Expr condition where connection.getMethod() instanceof ConnectionMethod and controlledByAuth(connection, condition) diff --git a/java/ql/src/Security/CWE/CWE-502/UnsafeDeserialization.ql b/java/ql/src/Security/CWE/CWE-502/UnsafeDeserialization.ql index 1c5660653a60..a5ebd206752b 100644 --- a/java/ql/src/Security/CWE/CWE-502/UnsafeDeserialization.ql +++ b/java/ql/src/Security/CWE/CWE-502/UnsafeDeserialization.ql @@ -17,5 +17,5 @@ import UnsafeDeserializationFlow::PathGraph from UnsafeDeserializationFlow::PathNode source, UnsafeDeserializationFlow::PathNode sink where UnsafeDeserializationFlow::flowPath(source, sink) -select sink.getNode().(UnsafeDeserializationSink).getMethodAccess(), source, sink, +select sink.getNode().(UnsafeDeserializationSink).getMethodCall(), source, sink, "Unsafe deserialization depends on a $@.", source.getNode(), "user-provided value" diff --git a/java/ql/src/Security/CWE/CWE-614/InsecureCookie.ql b/java/ql/src/Security/CWE/CWE-614/InsecureCookie.ql index 5933bb94fc21..b8d64d22e295 100644 --- a/java/ql/src/Security/CWE/CWE-614/InsecureCookie.ql +++ b/java/ql/src/Security/CWE/CWE-614/InsecureCookie.ql @@ -15,7 +15,7 @@ import java import semmle.code.java.frameworks.Servlets import semmle.code.java.security.InsecureCookieQuery -from MethodAccess add +from MethodCall add where add.getMethod() instanceof ResponseAddCookieMethod and not SecureCookieFlow::flowToExpr(add.getArgument(0)) diff --git a/java/ql/src/Security/CWE/CWE-676/PotentiallyDangerousFunction.ql b/java/ql/src/Security/CWE/CWE-676/PotentiallyDangerousFunction.ql index 662e2c487ab7..0387a16eff68 100644 --- a/java/ql/src/Security/CWE/CWE-676/PotentiallyDangerousFunction.ql +++ b/java/ql/src/Security/CWE/CWE-676/PotentiallyDangerousFunction.ql @@ -15,7 +15,7 @@ import java predicate dangerousMethod(string descriptor) { descriptor = "java.lang.Thread.stop" } -from MethodAccess call, Method target, string descriptor +from MethodCall call, Method target, string descriptor where call.getCallee() = target and descriptor = target.getDeclaringType().getQualifiedName() + "." + target.getName() and diff --git a/java/ql/src/Security/CWE/CWE-798/HardcodedCredentialsComparison.ql b/java/ql/src/Security/CWE/CWE-798/HardcodedCredentialsComparison.ql index 4a21fcc5e928..85cf2d809099 100644 --- a/java/ql/src/Security/CWE/CWE-798/HardcodedCredentialsComparison.ql +++ b/java/ql/src/Security/CWE/CWE-798/HardcodedCredentialsComparison.ql @@ -13,6 +13,6 @@ import java import semmle.code.java.security.HardcodedCredentialsComparison -from EqualsAccess sink, HardcodedExpr source, PasswordVariable p +from EqualsCall sink, HardcodedExpr source, PasswordVariable p where isHardcodedCredentialsComparison(sink, source, p) select source, "Hard-coded value is $@ with password variable $@.", sink, "compared", p, p.getName() diff --git a/java/ql/src/Security/CWE/CWE-807/ConditionalBypass.ql b/java/ql/src/Security/CWE/CWE-807/ConditionalBypass.ql index d012ae33810c..2715ec830d5f 100644 --- a/java/ql/src/Security/CWE/CWE-807/ConditionalBypass.ql +++ b/java/ql/src/Security/CWE/CWE-807/ConditionalBypass.ql @@ -18,8 +18,7 @@ import semmle.code.java.security.ConditionalBypassQuery import ConditionalBypassFlow::PathGraph from - ConditionalBypassFlow::PathNode source, ConditionalBypassFlow::PathNode sink, MethodAccess m, - Expr e + ConditionalBypassFlow::PathNode source, ConditionalBypassFlow::PathNode sink, MethodCall m, Expr e where conditionControlsMethod(m, e) and sink.getNode().asExpr() = e and diff --git a/java/ql/src/Security/CWE/CWE-833/LockOrderInconsistency.ql b/java/ql/src/Security/CWE/CWE-833/LockOrderInconsistency.ql index 7d8ad35c4d14..4e9857f3b938 100644 --- a/java/ql/src/Security/CWE/CWE-833/LockOrderInconsistency.ql +++ b/java/ql/src/Security/CWE/CWE-833/LockOrderInconsistency.ql @@ -19,8 +19,8 @@ class LockVariable extends Variable { } /** An access to method `lock` on this variable. */ - MethodAccess getLockAction() { - exists(MethodAccess ma | ma.getQualifier() = this.getAnAccess() | + MethodCall getLockAction() { + exists(MethodCall ma | ma.getQualifier() = this.getAnAccess() | ma.getMethod().hasName("lock") and result = ma ) @@ -35,7 +35,7 @@ class Synched extends Top { exists(Method m | m.isSynchronized() and not m.isStatic() | m = this or - exists(MethodAccess ma, VarAccess qual | ma = this and qual = ma.getQualifier() | + exists(MethodCall ma, VarAccess qual | ma = this and qual = ma.getQualifier() | ma.getMethod() = m ) ) @@ -47,7 +47,7 @@ class Synched extends Top { or result = this.(SynchronizedStmt).getAChild+() or - exists(MethodAccess ma | ma = result | + exists(MethodCall ma | ma = result | ma.getEnclosingStmt().getEnclosingStmt*() = this or ma.getEnclosingCallable() = this ) } @@ -65,7 +65,7 @@ class Synched extends Top { */ RefType getLockType() { result = this.(Method).getDeclaringType().getSourceDeclaration() or - result = this.(MethodAccess).getMethod().getDeclaringType().getSourceDeclaration() + result = this.(MethodCall).getMethod().getDeclaringType().getSourceDeclaration() } } @@ -74,8 +74,8 @@ class Synched extends Top { * and then on another variable in `second`, but elsewhere, the lock order is reversed * by first obtaining a lock on the latter variable in `otherFirst`. */ -predicate badReentrantLockOrder(MethodAccess first, MethodAccess second, MethodAccess otherFirst) { - exists(LockVariable v1, LockVariable v2, MethodAccess otherSecond | +predicate badReentrantLockOrder(MethodCall first, MethodCall second, MethodCall otherFirst) { + exists(LockVariable v1, LockVariable v2, MethodCall otherSecond | first = v1.getLockAction() and otherSecond = v1.getLockAction() and second = v2.getLockAction() and @@ -113,7 +113,7 @@ predicate badSynchronizedStmtLockOrder(Expr outerExpr, Expr innerExpr, Expr othe * The method access `ma` to method `m` is qualified by an access to variable `vQual` * and has an access to variable `vArg` as the argument at index `i`. */ -predicate qualifiedMethodAccess(MethodAccess ma, Method m, Variable vQual, int i, Variable vArg) { +predicate qualifiedMethodCall(MethodCall ma, Method m, Variable vQual, int i, Variable vArg) { ma.getMethod() = m and ma.getQualifier().(VarAccess).getVariable() = vQual and ma.getArgument(i).(VarAccess).getVariable() = vArg @@ -123,7 +123,7 @@ predicate qualifiedMethodAccess(MethodAccess ma, Method m, Variable vQual, int i * Holds if the specified method accesses occur on different branches of the same conditional statement * inside an unsynchronized method. */ -predicate inDifferentBranches(MethodAccess ma1, MethodAccess ma2) { +predicate inDifferentBranches(MethodCall ma1, MethodCall ma2) { exists(IfStmt cond | ma1.getEnclosingStmt() = cond.getThen().getAChild*() and ma2.getEnclosingStmt() = cond.getElse().getAChild*() and @@ -132,7 +132,7 @@ predicate inDifferentBranches(MethodAccess ma1, MethodAccess ma2) { } /** The method access `ma` occurs in method `runnable`, which is an implementation of `Runnable.run()`. */ -predicate inRunnable(MethodAccess ma, Method runnable) { +predicate inRunnable(MethodCall ma, Method runnable) { runnable.getName() = "run" and runnable.getDeclaringType().getAStrictAncestor().hasQualifiedName("java.lang", "Runnable") and ma.getEnclosingCallable() = runnable @@ -142,7 +142,7 @@ predicate inRunnable(MethodAccess ma, Method runnable) { * Holds if the specified method accesses occur in different `Runnable.run()` methods, * indicating that they may be invoked by different threads. */ -predicate inDifferentRunnables(MethodAccess ma1, MethodAccess ma2) { +predicate inDifferentRunnables(MethodCall ma1, MethodCall ma2) { exists(Method runnable1, Method runnable2 | inRunnable(ma1, runnable1) and inRunnable(ma2, runnable2) and @@ -155,18 +155,16 @@ predicate inDifferentRunnables(MethodAccess ma1, MethodAccess ma2) { * in statement `inner` that is qualified by one of the parameters of `outer`, and there is * another access to `outer` that may cause locking to be performed in a different order. */ -predicate badMethodAccessLockOrder( - MethodAccess outerAccess, MethodAccess innerAccess, MethodAccess other -) { +predicate badMethodCallLockOrder(MethodCall outerAccess, MethodCall innerAccess, MethodCall other) { exists(Synched outer, Synched inner | inner = innerAccess and inner = outer.getInnerSynch() and inner.getLockType() = outer.getLockType() and exists(Parameter p, int i | outer.(Method).getAParameter() = p and p.getPosition() = i | - inner.(MethodAccess).getQualifier().(VarAccess).getVariable() = p and - exists(MethodAccess ma1, MethodAccess ma2, Variable v1, Variable v2 | - qualifiedMethodAccess(ma1, outer, v1, i, v2) and - qualifiedMethodAccess(ma2, outer, v2, i, v1) and + inner.(MethodCall).getQualifier().(VarAccess).getVariable() = p and + exists(MethodCall ma1, MethodCall ma2, Variable v1, Variable v2 | + qualifiedMethodCall(ma1, outer, v1, i, v2) and + qualifiedMethodCall(ma2, outer, v2, i, v1) and v1 != v2 and ( inDifferentBranches(ma1, ma2) or @@ -183,7 +181,7 @@ from Expr first, Expr second, Expr other where badReentrantLockOrder(first, second, other) or badSynchronizedStmtLockOrder(first, second, other) or - badMethodAccessLockOrder(first, second, other) + badMethodCallLockOrder(first, second, other) select first, "Synchronization here and $@ may be performed in reverse order starting $@ and result in deadlock.", second, "here", other, "here" diff --git a/java/ql/src/Violations of Best Practice/Boxed Types/BoxedVariable.ql b/java/ql/src/Violations of Best Practice/Boxed Types/BoxedVariable.ql index 6ef404d0af4a..33c16eb598cd 100644 --- a/java/ql/src/Violations of Best Practice/Boxed Types/BoxedVariable.ql +++ b/java/ql/src/Violations of Best Practice/Boxed Types/BoxedVariable.ql @@ -26,7 +26,7 @@ class LocalBoxedVar extends LocalVariableDecl { * some number of boxing operations, these cases are excluded. */ predicate notDeliberatelyBoxed(LocalBoxedVar v) { - not forall(RValue a | a = v.getAnAccess() | + not forall(VarRead a | a = v.getAnAccess() | exists(Call c, int i | c.getCallee().getParameterType(i) instanceof RefType and c.getArgument(i) = a diff --git a/java/ql/src/Violations of Best Practice/Dead Code/CreatesEmptyZip.ql b/java/ql/src/Violations of Best Practice/Dead Code/CreatesEmptyZip.ql index 50a778cbaff5..a2b6afbbeee0 100644 --- a/java/ql/src/Violations of Best Practice/Dead Code/CreatesEmptyZip.ql +++ b/java/ql/src/Violations of Best Practice/Dead Code/CreatesEmptyZip.ql @@ -42,15 +42,15 @@ class ZipOutputStream extends Class { } from - ZipOutputStream jos, MethodAccess putNextEntry, MethodAccess closeEntry, RValue putNextQualifier, - RValue closeQualifier + ZipOutputStream jos, MethodCall putNextEntry, MethodCall closeEntry, VarRead putNextQualifier, + VarRead closeQualifier where putNextEntry.getMethod() = jos.putNextEntry() and closeEntry.getMethod() = jos.closeEntry() and putNextQualifier = putNextEntry.getQualifier() and closeQualifier = closeEntry.getQualifier() and adjacentUseUseSameVar(putNextQualifier, closeQualifier) and - not exists(RValue other | + not exists(VarRead other | adjacentUseUseSameVar(other, closeQualifier) and other != putNextQualifier ) diff --git a/java/ql/src/Violations of Best Practice/Dead Code/DeadLocals.qll b/java/ql/src/Violations of Best Practice/Dead Code/DeadLocals.qll index 8837b207e20e..39719f3524d4 100644 --- a/java/ql/src/Violations of Best Practice/Dead Code/DeadLocals.qll +++ b/java/ql/src/Violations of Best Practice/Dead Code/DeadLocals.qll @@ -58,7 +58,7 @@ predicate overwritten(SsaExplicitUpdate ssa) { * A local variable with a read access. */ predicate read(LocalScopeVariable v) { - exists(VarAccess va | va = v.getAnAccess() | va.isRValue()) + exists(VarAccess va | va = v.getAnAccess() | va.isVarRead()) or readImplicitly(_, v) } @@ -72,7 +72,7 @@ private predicate readImplicitly(SsaExplicitUpdate ssa, LocalScopeVariable v) { * A local variable with a write access. */ predicate assigned(LocalScopeVariable v) { - exists(VarAccess va | va = v.getAnAccess() | va.isLValue()) + exists(VarAccess va | va = v.getAnAccess() | va.isVarWrite()) } /** @@ -91,9 +91,7 @@ predicate exprHasNoEffect(Expr e) { constructorHasEffect(c) ) or - exists(MethodAccess ma, Method m | - bad = ma and m = ma.getMethod().getAPossibleImplementation() - | + exists(MethodCall ma, Method m | bad = ma and m = ma.getMethod().getAPossibleImplementation() | methodHasEffect(m) or not m.fromSource() ) ) @@ -107,7 +105,7 @@ private predicate inInitializer(Expr e) { private predicate constructorHasEffect(Constructor c) { // Only assign fields of the class - do not call methods, // create new objects or assign any other variables. - exists(MethodAccess ma | ma.getEnclosingCallable() = c) + exists(MethodCall ma | ma.getEnclosingCallable() = c) or exists(ClassInstanceExpr cie | cie.getEnclosingCallable() = c) or @@ -120,7 +118,7 @@ private predicate constructorHasEffect(Constructor c) { } private predicate methodHasEffect(Method m) { - exists(MethodAccess ma | ma.getEnclosingCallable() = m) or + exists(MethodCall ma | ma.getEnclosingCallable() = m) or exists(Assignment a | a.getEnclosingCallable() = m) or exists(ClassInstanceExpr cie | cie.getEnclosingCallable() = m) or exists(ThrowStmt throw | throw.getEnclosingCallable() = m) or diff --git a/java/ql/src/Violations of Best Practice/Dead Code/NonAssignedFields.ql b/java/ql/src/Violations of Best Practice/Dead Code/NonAssignedFields.ql index ba41a309a460..2c618f94aad3 100644 --- a/java/ql/src/Violations of Best Practice/Dead Code/NonAssignedFields.ql +++ b/java/ql/src/Violations of Best Practice/Dead Code/NonAssignedFields.ql @@ -27,7 +27,7 @@ predicate isClassOf(ParameterizedClass c, RefType t) { * Holds if field `f` is potentially accessed by an `AtomicReferenceFieldUpdater`. */ predicate subjectToAtomicReferenceFieldUpdater(Field f) { - exists(Class arfu, Method newUpdater, MethodAccess c | + exists(Class arfu, Method newUpdater, MethodCall c | arfu.hasQualifiedName("java.util.concurrent.atomic", "AtomicReferenceFieldUpdater") and newUpdater = arfu.getAMethod() and newUpdater.hasName("newUpdater") and @@ -42,7 +42,7 @@ predicate subjectToAtomicReferenceFieldUpdater(Field f) { * Holds if `f` is ever looked up reflectively. */ predicate lookedUpReflectively(Field f) { - exists(MethodAccess getDeclaredField | + exists(MethodCall getDeclaredField | isClassOf(getDeclaredField.getQualifier().getType(), f.getDeclaringType()) and getDeclaredField.getMethod().hasName("getDeclaredField") and getDeclaredField.getArgument(0).(StringLiteral).getValue() = f.getName() diff --git a/java/ql/src/Violations of Best Practice/Dead Code/PointlessForwardingMethod.ql b/java/ql/src/Violations of Best Practice/Dead Code/PointlessForwardingMethod.ql index 31e051cd77b3..a78abcc4a5d3 100644 --- a/java/ql/src/Violations of Best Practice/Dead Code/PointlessForwardingMethod.ql +++ b/java/ql/src/Violations of Best Practice/Dead Code/PointlessForwardingMethod.ql @@ -19,8 +19,8 @@ Method forwarderCandidate(Method forwardee) { result != forwardee and result.getName() = forwardee.getName() and result.getDeclaringType() = forwardee.getDeclaringType() and - forex(MethodAccess c | c.getMethod() = forwardee | c.getCaller() = result) and - forall(MethodAccess c | c.getCaller() = result | c.getMethod() = forwardee) + forex(MethodCall c | c.getMethod() = forwardee | c.getCaller() = result) and + forall(MethodCall c | c.getCaller() = result | c.getMethod() = forwardee) } from Method forwarder, Method forwardee @@ -29,10 +29,10 @@ where // Exclusions not ignored(forwarder) and not ignored(forwardee) and - not exists(VirtualMethodAccess c | + not exists(VirtualMethodCall c | c.getMethod() = forwardee and c.getCaller() = forwarder and - c.(MethodAccess).hasQualifier() + c.(MethodCall).hasQualifier() ) select forwarder.getSourceDeclaration(), "This method is a forwarder for $@, which is not called independently - the methods can be merged.", diff --git a/java/ql/src/Violations of Best Practice/Exception Handling/ExceptionCatch.ql b/java/ql/src/Violations of Best Practice/Exception Handling/ExceptionCatch.ql index 0340e63d74ca..e321e3c94226 100644 --- a/java/ql/src/Violations of Best Practice/Exception Handling/ExceptionCatch.ql +++ b/java/ql/src/Violations of Best Practice/Exception Handling/ExceptionCatch.ql @@ -21,7 +21,7 @@ private predicate relevantTypeNames(string typeName, string message) { } private Type getAThrownExceptionType(TryStmt t) { - exists(MethodAccess ma, Exception e | + exists(MethodCall ma, Exception e | t.getBlock() = ma.getEnclosingStmt().getEnclosingStmt*() and ma.getMethod().getAnException() = e and result = e.getType() diff --git a/java/ql/src/Violations of Best Practice/Exception Handling/IgnoreExceptionalReturn.ql b/java/ql/src/Violations of Best Practice/Exception Handling/IgnoreExceptionalReturn.ql index 5a03dafa6733..2e95c087ed54 100644 --- a/java/ql/src/Violations of Best Practice/Exception Handling/IgnoreExceptionalReturn.ql +++ b/java/ql/src/Violations of Best Practice/Exception Handling/IgnoreExceptionalReturn.ql @@ -43,7 +43,7 @@ predicate unboundedQueue(RefType t) { ) } -from MethodAccess ma, SpecialMethod m +from MethodCall ma, SpecialMethod m where ma instanceof ValueDiscardingExpr and m = ma.getMethod() and diff --git a/java/ql/src/Violations of Best Practice/Implementation Hiding/ExposeRepresentation.ql b/java/ql/src/Violations of Best Practice/Implementation Hiding/ExposeRepresentation.ql index 2889de0b5cf6..98c1e1a2fbea 100644 --- a/java/ql/src/Violations of Best Practice/Implementation Hiding/ExposeRepresentation.ql +++ b/java/ql/src/Violations of Best Practice/Implementation Hiding/ExposeRepresentation.ql @@ -71,7 +71,7 @@ predicate mayWriteToArray(Expr modified) { or // return __array__; ... method()[1] = 0 exists(ReturnStmt rs | modified = rs.getResult() and relevantType(modified.getType()) | - exists(Callable enclosing, MethodAccess ma | + exists(Callable enclosing, MethodCall ma | enclosing = rs.getEnclosingCallable() and ma.getMethod().getSourceDeclaration() = enclosing | mayWriteToArray(ma) @@ -84,7 +84,7 @@ predicate writesToArray(Expr array) { ( exists(Assignment a, ArrayAccess access | a.getDest() = access | access.getArray() = array) or - exists(MethodAccess ma | ma.getQualifier() = array | modifyMethod(ma.getMethod())) + exists(MethodCall ma | ma.getQualifier() = array | modifyMethod(ma.getMethod())) ) } @@ -99,7 +99,7 @@ VarAccess varPassedInto(Callable c, int i) { predicate exposesByReturn(Callable c, Field f, Expr why, string whyText) { returnsArray(c, f) and - exists(MethodAccess ma | + exists(MethodCall ma | ma.getMethod().getSourceDeclaration() = c and ma.getCompilationUnit() != c.getCompilationUnit() | mayWriteToArray(ma) and diff --git a/java/ql/src/Violations of Best Practice/Implementation Hiding/GetClassGetResource.ql b/java/ql/src/Violations of Best Practice/Implementation Hiding/GetClassGetResource.ql index 21b5a73a3a4d..7f52c495835e 100644 --- a/java/ql/src/Violations of Best Practice/Implementation Hiding/GetClassGetResource.ql +++ b/java/ql/src/Violations of Best Practice/Implementation Hiding/GetClassGetResource.ql @@ -12,7 +12,7 @@ import java -from Class c, MethodAccess getResource, MethodAccess getClass +from Class c, MethodCall getResource, MethodCall getClass where getResource.getNumArgument() = 1 and ( @@ -20,7 +20,7 @@ where getResource.getMethod().hasName("getResourceAsStream") ) and getResource.getQualifier() = getClass and - getClass.isOwnMethodAccess() and + getClass.isOwnMethodCall() and getClass.getNumArgument() = 0 and getClass.getMethod().hasName("getClass") and getResource.getEnclosingCallable().getDeclaringType() = c and diff --git a/java/ql/src/Violations of Best Practice/Magic Constants/MagicConstants.qll b/java/ql/src/Violations of Best Practice/Magic Constants/MagicConstants.qll index 5fc7e9069cd8..dc5b4eada8d9 100644 --- a/java/ql/src/Violations of Best Practice/Magic Constants/MagicConstants.qll +++ b/java/ql/src/Violations of Best Practice/Magic Constants/MagicConstants.qll @@ -97,7 +97,7 @@ private predicate nonTrivialValue(string value, Literal literal, string context) not literalIsConstantInitializer(literal, _) and not literal.getParent*() instanceof ArrayInit and not literal.getParent+() instanceof Annotation and - exists(MethodAccess ma | literal = ma.getAnArgument() and ma.getMethod().getName() = context) + exists(MethodCall ma | literal = ma.getAnArgument() and ma.getMethod().getName() = context) } private predicate valueOccurrenceCount(string value, int n, string context) { @@ -173,7 +173,7 @@ private predicate relevantType(RefType t, string value, Package p) { private predicate fieldUsedInContext(Field constField, string context) { literalIsConstantInitializer(_, constField) and - exists(MethodAccess ma | + exists(MethodCall ma | constField.getAnAccess() = ma.getAnArgument() and ma.getMethod().getName() = context ) @@ -282,5 +282,5 @@ private predicate excludedLiteral(Literal lit) { // Remove test cases lit.getEnclosingCallable().getDeclaringType() instanceof TestClass or - exists(MethodAccess ma | lit = ma.getAnArgument() | ma.getMethod() instanceof TestMethod) + exists(MethodCall ma | lit = ma.getAnArgument() | ma.getMethod() instanceof TestMethod) } diff --git a/java/ql/src/Violations of Best Practice/Magic Constants/MagicConstantsString.ql b/java/ql/src/Violations of Best Practice/Magic Constants/MagicConstantsString.ql index 66e75e7cc47c..c50057c111e9 100644 --- a/java/ql/src/Violations of Best Practice/Magic Constants/MagicConstantsString.ql +++ b/java/ql/src/Violations of Best Practice/Magic Constants/MagicConstantsString.ql @@ -37,13 +37,13 @@ predicate trivialContext(Literal e) { or e.getParent() instanceof AssignAddExpr or - exists(MethodAccess ma | + exists(MethodCall ma | ma.getMethod().getName() = "append" and (e = ma.getAnArgument() or e = ma.getQualifier()) ) or // Standard property in a call to `System.getProperty()`. - exists(MethodAccess ma | + exists(MethodCall ma | ma.getMethod().getName() = "getProperty" and e = ma.getAnArgument() and ma.getMethod().getDeclaringType() instanceof TypeSystem and diff --git a/java/ql/src/Violations of Best Practice/Naming Conventions/AmbiguousOuterSuper.ql b/java/ql/src/Violations of Best Practice/Naming Conventions/AmbiguousOuterSuper.ql index f41611603036..a52a6d816880 100644 --- a/java/ql/src/Violations of Best Practice/Naming Conventions/AmbiguousOuterSuper.ql +++ b/java/ql/src/Violations of Best Practice/Naming Conventions/AmbiguousOuterSuper.ql @@ -23,7 +23,7 @@ RefType nestedSupertypePlus(RefType t) { * A call (without a qualifier) in a nested type * to an inherited method with the specified `signature`. */ -predicate callToInheritedMethod(RefType lexicalScope, MethodAccess ma, string signature) { +predicate callToInheritedMethod(RefType lexicalScope, MethodCall ma, string signature) { not ma.getMethod().isStatic() and not ma.hasQualifier() and ma.getEnclosingCallable().getDeclaringType() = lexicalScope and @@ -46,7 +46,7 @@ Method methodInEnclosingType(NestedType nested, string signature) { ) } -from MethodAccess ma, Method m, NestedType nt, string signature +from MethodCall ma, Method m, NestedType nt, string signature where callToInheritedMethod(nt, ma, signature) and m = methodInEnclosingType(nt, signature) and diff --git a/java/ql/src/Violations of Best Practice/Naming Conventions/ConfusingOverloading.ql b/java/ql/src/Violations of Best Practice/Naming Conventions/ConfusingOverloading.ql index f355cd5f2196..96188c534ffa 100644 --- a/java/ql/src/Violations of Best Practice/Naming Conventions/ConfusingOverloading.ql +++ b/java/ql/src/Violations of Best Practice/Naming Conventions/ConfusingOverloading.ql @@ -115,13 +115,13 @@ private predicate confusinglyOverloaded(Method m, Method n) { not exists(Method target | delegate*(m, target) and delegate*(n, target)) } -private predicate wrappedAccess(Expr e, MethodAccess ma) { +private predicate wrappedAccess(Expr e, MethodCall ma) { e = ma or wrappedAccess(e.(CastingExpr).getExpr(), ma) } private predicate delegate(Method caller, Method callee) { - exists(MethodAccess ma | ma.getMethod() = callee | + exists(MethodCall ma | ma.getMethod() = callee | exists(Stmt stmt | stmt = caller.getBody().(SingletonBlock).getStmt() | wrappedAccess(stmt.(ExprStmt).getExpr(), ma) or wrappedAccess(stmt.(ReturnStmt).getResult(), ma) diff --git a/java/ql/src/Violations of Best Practice/Naming Conventions/Shadowing.qll b/java/ql/src/Violations of Best Practice/Naming Conventions/Shadowing.qll index e58016bdff97..f37d7fdcab00 100644 --- a/java/ql/src/Violations of Best Practice/Naming Conventions/Shadowing.qll +++ b/java/ql/src/Violations of Best Practice/Naming Conventions/Shadowing.qll @@ -57,7 +57,7 @@ predicate assignmentToShadowingLocal(LocalVariableDecl d, Field f) { ff.getSourceDeclaration() = f ) or - exists(MethodAccess get, Method getter | get = assignedValue and getter = get.getMethod() | + exists(MethodCall get, Method getter | get = assignedValue and getter = get.getMethod() | getterFor(getter, f) ) ) @@ -66,7 +66,7 @@ predicate assignmentToShadowingLocal(LocalVariableDecl d, Field f) { predicate assignmentFromShadowingLocal(LocalVariableDecl d, Field f) { shadows(d, _, _, _) and exists(VarAccess access | access = d.getAnAccess() | - exists(MethodAccess set, Expr arg, Method setter | + exists(MethodCall set, Expr arg, Method setter | access = getARelevantChild(arg) and arg = set.getAnArgument() and setter = set.getMethod() and @@ -82,7 +82,7 @@ predicate assignmentFromShadowingLocal(LocalVariableDecl d, Field f) { } private Expr getARelevantChild(Expr parent) { - exists(MethodAccess ma | parent = ma.getAnArgument() and result = parent) + exists(MethodCall ma | parent = ma.getAnArgument() and result = parent) or exists(Variable v | parent = v.getAnAccess() and result = parent) or diff --git a/java/ql/src/Violations of Best Practice/Undesirable Calls/CallsToRunFinalizersOnExit.ql b/java/ql/src/Violations of Best Practice/Undesirable Calls/CallsToRunFinalizersOnExit.ql index 0ee14f58b701..c2ffe45b5209 100644 --- a/java/ql/src/Violations of Best Practice/Undesirable Calls/CallsToRunFinalizersOnExit.ql +++ b/java/ql/src/Violations of Best Practice/Undesirable Calls/CallsToRunFinalizersOnExit.ql @@ -13,7 +13,7 @@ import java -from MethodAccess ma, Method runfinalizers, Class c +from MethodCall ma, Method runfinalizers, Class c where ma.getMethod() = runfinalizers and runfinalizers.hasName("runFinalizersOnExit") and diff --git a/java/ql/src/Violations of Best Practice/Undesirable Calls/CallsToStringToString.ql b/java/ql/src/Violations of Best Practice/Undesirable Calls/CallsToStringToString.ql index c13956694056..9b1bcb9877cb 100644 --- a/java/ql/src/Violations of Best Practice/Undesirable Calls/CallsToStringToString.ql +++ b/java/ql/src/Violations of Best Practice/Undesirable Calls/CallsToStringToString.ql @@ -10,7 +10,7 @@ import java -from MethodAccess ma, ToStringMethod tostring +from MethodCall ma, ToStringMethod tostring where tostring.getDeclaringType() instanceof TypeString and ma.getMethod() = tostring diff --git a/java/ql/src/Violations of Best Practice/Undesirable Calls/CallsToSystemExit.ql b/java/ql/src/Violations of Best Practice/Undesirable Calls/CallsToSystemExit.ql index 387098d23b7c..93d7911694cf 100644 --- a/java/ql/src/Violations of Best Practice/Undesirable Calls/CallsToSystemExit.ql +++ b/java/ql/src/Violations of Best Practice/Undesirable Calls/CallsToSystemExit.ql @@ -13,7 +13,7 @@ import java -from Method m, MethodAccess sysexitCall, Method sysexit, Class system +from Method m, MethodCall sysexitCall, Method sysexit, Class system where sysexitCall = m.getACallSite(sysexit) and (sysexit.hasName("exit") or sysexit.hasName("halt")) and diff --git a/java/ql/src/Violations of Best Practice/Undesirable Calls/DefaultToString.ql b/java/ql/src/Violations of Best Practice/Undesirable Calls/DefaultToString.ql index b224744a7ad0..d404e4a929a4 100644 --- a/java/ql/src/Violations of Best Practice/Undesirable Calls/DefaultToString.ql +++ b/java/ql/src/Violations of Best Practice/Undesirable Calls/DefaultToString.ql @@ -14,7 +14,7 @@ import java import semmle.code.java.StringFormat predicate explicitToStringCall(Expr e) { - exists(MethodAccess ma | + exists(MethodCall ma | ma.getMethod() instanceof ToStringMethod and e = ma.getQualifier() ) diff --git a/java/ql/src/Violations of Best Practice/Undesirable Calls/GarbageCollection.ql b/java/ql/src/Violations of Best Practice/Undesirable Calls/GarbageCollection.ql index f30dd30759fb..1067bdcb6dce 100644 --- a/java/ql/src/Violations of Best Practice/Undesirable Calls/GarbageCollection.ql +++ b/java/ql/src/Violations of Best Practice/Undesirable Calls/GarbageCollection.ql @@ -12,7 +12,7 @@ import java -from MethodAccess mc, Method m +from MethodCall mc, Method m where ( m.getDeclaringType().hasQualifiedName("java.lang", "Runtime") or diff --git a/java/ql/src/Violations of Best Practice/Undesirable Calls/NextFromIterator.ql b/java/ql/src/Violations of Best Practice/Undesirable Calls/NextFromIterator.ql index 3400110b3d6f..ebdf55761989 100644 --- a/java/ql/src/Violations of Best Practice/Undesirable Calls/NextFromIterator.ql +++ b/java/ql/src/Violations of Best Practice/Undesirable Calls/NextFromIterator.ql @@ -12,11 +12,11 @@ import java -from MethodAccess m +from MethodCall m where m.getMethod().hasName("next") and m.getMethod().getNumberOfParameters() = 0 and - m.isOwnMethodAccess() and + m.isOwnMethodCall() and exists(Interface i, Method hasNext | i.getSourceDeclaration().hasQualifiedName("java.util", "Iterator") and m.getEnclosingCallable() = hasNext and diff --git a/java/ql/src/Violations of Best Practice/Undesirable Calls/PrintLnArray.ql b/java/ql/src/Violations of Best Practice/Undesirable Calls/PrintLnArray.ql index a89b3b0cbea7..f356aa635d4a 100644 --- a/java/ql/src/Violations of Best Practice/Undesirable Calls/PrintLnArray.ql +++ b/java/ql/src/Violations of Best Practice/Undesirable Calls/PrintLnArray.ql @@ -16,7 +16,7 @@ import semmle.code.java.StringFormat * Holds if `e` is an argument of `Arrays.toString(..)`. */ predicate arraysToStringArgument(Expr e) { - exists(MethodAccess ma, Method m | + exists(MethodCall ma, Method m | ma.getAnArgument() = e and ma.getMethod() = m and m.getDeclaringType().hasQualifiedName("java.util", "Arrays") and diff --git a/java/ql/src/Violations of Best Practice/legacy/InexactVarArg.ql b/java/ql/src/Violations of Best Practice/legacy/InexactVarArg.ql index af5b80853636..bcd43d9e2aab 100644 --- a/java/ql/src/Violations of Best Practice/legacy/InexactVarArg.ql +++ b/java/ql/src/Violations of Best Practice/legacy/InexactVarArg.ql @@ -13,7 +13,7 @@ import java predicate varArgsMethod(Method method, Array varargsType, int arity) { - exists(MethodAccess access | + exists(MethodCall access | access.getMethod() = method and arity = method.getNumberOfParameters() and not access.getNumArgument() = arity and @@ -36,7 +36,7 @@ predicate equivalent(Array declared, Array used) { declared.getDimension() = used.getDimension() } -from Method target, MethodAccess access, Array declaredType, Array usedType, int params +from Method target, MethodCall access, Array declaredType, Array usedType, int params where varArgsMethod(target, declaredType, params) and target = access.getMethod() and diff --git a/java/ql/src/experimental/Security/CWE/CWE-016/SpringBootActuators.qll b/java/ql/src/experimental/Security/CWE/CWE-016/SpringBootActuators.qll index b782642d89f2..195de7a1b8be 100644 --- a/java/ql/src/experimental/Security/CWE/CWE-016/SpringBootActuators.qll +++ b/java/ql/src/experimental/Security/CWE/CWE-016/SpringBootActuators.qll @@ -40,7 +40,7 @@ class TypeEndpointRequest extends Class { } /** A call to `EndpointRequest.toAnyEndpoint` method. */ -class ToAnyEndpointCall extends MethodAccess { +class ToAnyEndpointCall extends MethodCall { ToAnyEndpointCall() { this.getMethod().hasName("toAnyEndpoint") and this.getMethod().getDeclaringType() instanceof TypeEndpointRequest @@ -50,7 +50,7 @@ class ToAnyEndpointCall extends MethodAccess { /** * A call to `HttpSecurity.requestMatcher` method with argument `RequestMatcher.toAnyEndpoint()`. */ -class RequestMatcherCall extends MethodAccess { +class RequestMatcherCall extends MethodCall { RequestMatcherCall() { this.getMethod().hasName("requestMatcher") and this.getMethod().getDeclaringType() instanceof TypeHttpSecurity and @@ -62,7 +62,7 @@ class RequestMatcherCall extends MethodAccess { * A call to `HttpSecurity.requestMatchers` method with lambda argument * `RequestMatcher.toAnyEndpoint()`. */ -class RequestMatchersCall extends MethodAccess { +class RequestMatchersCall extends MethodCall { RequestMatchersCall() { this.getMethod().hasName("requestMatchers") and this.getMethod().getDeclaringType() instanceof TypeHttpSecurity and @@ -71,7 +71,7 @@ class RequestMatchersCall extends MethodAccess { } /** A call to `HttpSecurity.authorizeRequests` method. */ -class AuthorizeRequestsCall extends MethodAccess { +class AuthorizeRequestsCall extends MethodCall { AuthorizeRequestsCall() { this.getMethod().hasName("authorizeRequests") and this.getMethod().getDeclaringType() instanceof TypeHttpSecurity @@ -79,7 +79,7 @@ class AuthorizeRequestsCall extends MethodAccess { } /** A call to `AuthorizedUrl.permitAll` method. */ -class PermitAllCall extends MethodAccess { +class PermitAllCall extends MethodCall { PermitAllCall() { this.getMethod().hasName("permitAll") and this.getMethod().getDeclaringType() instanceof TypeAuthorizedUrl @@ -135,7 +135,7 @@ class PermitAllCall extends MethodAccess { } /** A call to `AbstractRequestMatcherRegistry.anyRequest` method. */ -class AnyRequestCall extends MethodAccess { +class AnyRequestCall extends MethodCall { AnyRequestCall() { this.getMethod().hasName("anyRequest") and this.getMethod().getDeclaringType() instanceof TypeAbstractRequestMatcherRegistry @@ -146,7 +146,7 @@ class AnyRequestCall extends MethodAccess { * A call to `AbstractRequestMatcherRegistry.requestMatchers` method with an argument * `RequestMatcher.toAnyEndpoint()`. */ -class RegistryRequestMatchersCall extends MethodAccess { +class RegistryRequestMatchersCall extends MethodCall { RegistryRequestMatchersCall() { this.getMethod().hasName("requestMatchers") and this.getMethod().getDeclaringType() instanceof TypeAbstractRequestMatcherRegistry and diff --git a/java/ql/src/experimental/Security/CWE/CWE-036/OpenStream.ql b/java/ql/src/experimental/Security/CWE/CWE-036/OpenStream.ql index fedde6f21a0b..4b71c297c230 100644 --- a/java/ql/src/experimental/Security/CWE/CWE-036/OpenStream.ql +++ b/java/ql/src/experimental/Security/CWE/CWE-036/OpenStream.ql @@ -36,7 +36,7 @@ module RemoteUrlToOpenStreamFlowConfig implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node source) { source instanceof ThreatModelFlowSource } predicate isSink(DataFlow::Node sink) { - exists(MethodAccess m | + exists(MethodCall m | sink.asExpr() = m.getQualifier() and m.getMethod() instanceof UrlOpenStreamMethod ) or @@ -55,7 +55,7 @@ module RemoteUrlToOpenStreamFlow = TaintTracking::Global; from CodeInjectionFlow::PathNode source, CodeInjectionFlow::PathNode sink where CodeInjectionFlow::flowPath(source, sink) -select sink.getNode().(CodeInjectionSink).getMethodAccess(), source, sink, "Jython evaluate $@.", +select sink.getNode().(CodeInjectionSink).getMethodCall(), source, sink, "Jython evaluate $@.", source.getNode(), "user input" diff --git a/java/ql/src/experimental/Security/CWE/CWE-094/ScriptInjection.ql b/java/ql/src/experimental/Security/CWE/CWE-094/ScriptInjection.ql index 21e36bbdd00a..0792d8e498ae 100644 --- a/java/ql/src/experimental/Security/CWE/CWE-094/ScriptInjection.ql +++ b/java/ql/src/experimental/Security/CWE/CWE-094/ScriptInjection.ql @@ -75,7 +75,7 @@ class RhinoDefineClassMethod extends Method { * Holds if `ma` is a call to a `ScriptEngineMethod` and `sink` is an argument that * will be executed. */ -predicate isScriptArgument(MethodAccess ma, Expr sink) { +predicate isScriptArgument(MethodCall ma, Expr sink) { exists(ScriptEngineMethod m | m = ma.getMethod() and if m.getDeclaringType().getAnAncestor().hasQualifiedName("javax.script", "ScriptEngineFactory") @@ -87,14 +87,14 @@ predicate isScriptArgument(MethodAccess ma, Expr sink) { /** * Holds if a Rhino expression evaluation method is vulnerable to code injection. */ -predicate evaluatesRhinoExpression(MethodAccess ma, Expr sink) { +predicate evaluatesRhinoExpression(MethodCall ma, Expr sink) { exists(RhinoEvaluateExpressionMethod m | m = ma.getMethod() | ( if ma.getMethod().getName() = "compileReader" then sink = ma.getArgument(0) // The first argument is the input reader else sink = ma.getArgument(1) // The second argument is the JavaScript or Java input ) and - not exists(MethodAccess ca | + not exists(MethodCall ca | ca.getMethod().hasName(["initSafeStandardObjects", "setClassShutter"]) and // safe mode or `ClassShutter` constraint is enforced ma.getQualifier() = ca.getQualifier().(VarAccess).getVariable().getAnAccess() ) @@ -104,20 +104,20 @@ predicate evaluatesRhinoExpression(MethodAccess ma, Expr sink) { /** * Holds if a Rhino expression compilation method is vulnerable to code injection. */ -predicate compilesScript(MethodAccess ma, Expr sink) { +predicate compilesScript(MethodCall ma, Expr sink) { exists(RhinoCompileClassMethod m | m = ma.getMethod() | sink = ma.getArgument(0)) } /** * Holds if a Rhino class loading method is vulnerable to code injection. */ -predicate definesRhinoClass(MethodAccess ma, Expr sink) { +predicate definesRhinoClass(MethodCall ma, Expr sink) { exists(RhinoDefineClassMethod m | m = ma.getMethod() | sink = ma.getArgument(1)) } /** A script injection sink. */ class ScriptInjectionSink extends DataFlow::ExprNode { - MethodAccess methodAccess; + MethodCall methodAccess; ScriptInjectionSink() { isScriptArgument(methodAccess, this.getExpr()) or @@ -127,7 +127,7 @@ class ScriptInjectionSink extends DataFlow::ExprNode { } /** An access to the method associated with this sink. */ - MethodAccess getMethodAccess() { result = methodAccess } + MethodCall getMethodCall() { result = methodAccess } } /** @@ -144,5 +144,5 @@ module ScriptInjectionFlow = TaintTracking::Global; from ScriptInjectionFlow::PathNode source, ScriptInjectionFlow::PathNode sink where ScriptInjectionFlow::flowPath(source, sink) -select sink.getNode().(ScriptInjectionSink).getMethodAccess(), source, sink, +select sink.getNode().(ScriptInjectionSink).getMethodCall(), source, sink, "Java Script Engine evaluate $@.", source.getNode(), "user input" diff --git a/java/ql/src/experimental/Security/CWE/CWE-094/SpringFrameworkLib.qll b/java/ql/src/experimental/Security/CWE/CWE-094/SpringFrameworkLib.qll index 964d1dcf86e7..baf0fbd034a9 100644 --- a/java/ql/src/experimental/Security/CWE/CWE-094/SpringFrameworkLib.qll +++ b/java/ql/src/experimental/Security/CWE/CWE-094/SpringFrameworkLib.qll @@ -6,7 +6,7 @@ import semmle.code.java.dataflow.DataFlow */ class WebRequestSource extends DataFlow::Node { WebRequestSource() { - exists(MethodAccess ma, Method m | ma.getMethod() = m | + exists(MethodCall ma, Method m | ma.getMethod() = m | m.getDeclaringType() instanceof WebRequest and ( m.hasName("getHeader") or diff --git a/java/ql/src/experimental/Security/CWE/CWE-094/SpringViewManipulationLib.qll b/java/ql/src/experimental/Security/CWE/CWE-094/SpringViewManipulationLib.qll index 943b946e95d4..310aafb30f5e 100644 --- a/java/ql/src/experimental/Security/CWE/CWE-094/SpringViewManipulationLib.qll +++ b/java/ql/src/experimental/Security/CWE/CWE-094/SpringViewManipulationLib.qll @@ -44,7 +44,7 @@ module SpringViewManipulationConfig implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node source) { source instanceof ThreatModelFlowSource or source instanceof WebRequestSource or - source.asExpr().(MethodAccess).getMethod() instanceof PortletRenderRequestMethod + source.asExpr().(MethodCall).getMethod() instanceof PortletRenderRequestMethod } predicate isSink(DataFlow::Node sink) { sink instanceof SpringViewManipulationSink } diff --git a/java/ql/src/experimental/Security/CWE/CWE-1004/SensitiveCookieNotHttpOnly.ql b/java/ql/src/experimental/Security/CWE/CWE-1004/SensitiveCookieNotHttpOnly.ql index 6a49279d3dc9..324566647951 100644 --- a/java/ql/src/experimental/Security/CWE/CWE-1004/SensitiveCookieNotHttpOnly.ql +++ b/java/ql/src/experimental/Security/CWE/CWE-1004/SensitiveCookieNotHttpOnly.ql @@ -51,8 +51,8 @@ class SensitiveCookieNameExpr extends Expr { } /** A method call that sets a `Set-Cookie` header. */ -class SetCookieMethodAccess extends MethodAccess { - SetCookieMethodAccess() { +class SetCookieMethodCall extends MethodCall { + SetCookieMethodCall() { ( this.getMethod() instanceof ResponseAddHeaderMethod or this.getMethod() instanceof ResponseSetHeaderMethod @@ -63,7 +63,7 @@ class SetCookieMethodAccess extends MethodAccess { /** * A taint configuration tracking flow from the text `httponly` to argument 1 of - * `SetCookieMethodAccess`. + * `SetCookieMethodCall`. */ module MatchesHttpOnlyConfig implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node source) { @@ -71,7 +71,7 @@ module MatchesHttpOnlyConfig implements DataFlow::ConfigSig { } predicate isSink(DataFlow::Node sink) { - sink.asExpr() = any(SetCookieMethodAccess ma).getArgument(1) + sink.asExpr() = any(SetCookieMethodCall ma).getArgument(1) } } @@ -91,26 +91,26 @@ predicate mayBeBooleanTrue(Expr expr) { } /** Holds if the method call may set the `HttpOnly` flag. */ -predicate setsCookieHttpOnly(MethodAccess ma) { +predicate setsCookieHttpOnly(MethodCall ma) { ma.getMethod().getName() = "setHttpOnly" and // any use of setHttpOnly(x) where x isn't false is probably safe mayBeBooleanTrue(ma.getArgument(0)) } /** Holds if `ma` removes a cookie. */ -predicate removesCookie(MethodAccess ma) { +predicate removesCookie(MethodCall ma) { ma.getMethod().getName() = "setMaxAge" and ma.getArgument(0).(IntegerLiteral).getIntValue() = 0 } /** - * Holds if the MethodAccess `ma` is a test method call indicated by: + * Holds if the MethodCall `ma` is a test method call indicated by: * a) in a test directory such as `src/test/java` * b) in a test package whose name has the word `test` * c) in a test class whose name has the word `test` * d) in a test class implementing a test framework such as JUnit or TestNG */ -predicate isTestMethod(MethodAccess ma) { +predicate isTestMethod(MethodCall ma) { exists(Method m | m = ma.getEnclosingCallable() and ( @@ -129,12 +129,12 @@ predicate isTestMethod(MethodAccess ma) { module SetHttpOnlyOrRemovesCookieConfig implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node source) { source.asExpr() = - any(MethodAccess ma | setsCookieHttpOnly(ma) or removesCookie(ma)).getQualifier() + any(MethodCall ma | setsCookieHttpOnly(ma) or removesCookie(ma)).getQualifier() } predicate isSink(DataFlow::Node sink) { sink.asExpr() = - any(MethodAccess ma | ma.getMethod() instanceof ResponseAddCookieMethod).getArgument(0) + any(MethodCall ma | ma.getMethod() instanceof ResponseAddCookieMethod).getArgument(0) } } @@ -146,13 +146,13 @@ module SetHttpOnlyOrRemovesCookieFlow = TaintTracking::Global; /** A `GET_CONTENT` `Intent` instances that is passed to `startActivityForResult`. */ class AndroidFileIntentInput extends DataFlow::Node { - MethodAccess ma; + MethodCall ma; AndroidFileIntentInput() { this.asExpr() = ma.getArgument(0) and diff --git a/java/ql/src/experimental/Security/CWE/CWE-200/AndroidWebResourceResponse.qll b/java/ql/src/experimental/Security/CWE/CWE-200/AndroidWebResourceResponse.qll index 05055bdfa845..0f9592321942 100644 --- a/java/ql/src/experimental/Security/CWE/CWE-200/AndroidWebResourceResponse.qll +++ b/java/ql/src/experimental/Security/CWE/CWE-200/AndroidWebResourceResponse.qll @@ -33,8 +33,8 @@ class ShouldInterceptRequestMethod extends Method { } /** A method call to `WebView.setWebViewClient`. */ -class SetWebViewClientMethodAccess extends MethodAccess { - SetWebViewClientMethodAccess() { +class SetWebViewClientMethodCall extends MethodCall { + SetWebViewClientMethodCall() { this.getMethod().hasName("setWebViewClient") and this.getMethod().getDeclaringType().getASupertype*() instanceof TypeWebView } @@ -66,7 +66,7 @@ private class FetchUrlStep extends AdditionalTaintStep { override predicate step(DataFlow::Node pred, DataFlow::Node succ) { exists( // webview.loadUrl(url) -> webview.setWebViewClient(new WebViewClient() { shouldInterceptRequest(view, url) }); - MethodAccess lma, ShouldInterceptRequestMethod im, SetWebViewClientMethodAccess sma + MethodCall lma, ShouldInterceptRequestMethod im, SetWebViewClientMethodCall sma | sma.getArgument(0).getType() = im.getDeclaringType().getASupertype*() and lma.getMethod() instanceof WebViewLoadUrlMethod and diff --git a/java/ql/src/experimental/Security/CWE/CWE-200/SensitiveAndroidFileLeak.ql b/java/ql/src/experimental/Security/CWE/CWE-200/SensitiveAndroidFileLeak.ql index 0a71647a5bcd..106782187c50 100644 --- a/java/ql/src/experimental/Security/CWE/CWE-200/SensitiveAndroidFileLeak.ql +++ b/java/ql/src/experimental/Security/CWE/CWE-200/SensitiveAndroidFileLeak.ql @@ -17,10 +17,10 @@ import AndroidFileIntentSource import AndroidFileLeakFlow::PathGraph private predicate startsWithSanitizer(Guard g, Expr e, boolean branch) { - exists(MethodAccess ma | + exists(MethodCall ma | g = ma and ma.getMethod().hasName("startsWith") and - e = [ma.getQualifier(), ma.getQualifier().(MethodAccess).getQualifier()] and + e = [ma.getQualifier(), ma.getQualifier().(MethodCall).getQualifier()] and branch = false ) } @@ -51,7 +51,7 @@ module AndroidFileLeakConfig implements DataFlow::ConfigSig { predicate isSink(DataFlow::Node sink) { sink instanceof AndroidFileSink } predicate isAdditionalFlowStep(DataFlow::Node prev, DataFlow::Node succ) { - exists(MethodAccess aema, AsyncTaskRunInBackgroundMethod arm | + exists(MethodCall aema, AsyncTaskRunInBackgroundMethod arm | // fileAsyncTask.execute(params) will invoke doInBackground(params) of FileAsyncTask aema.getQualifier().getType() = arm.getDeclaringType() and aema.getMethod() instanceof ExecuteAsyncTaskMethod and @@ -59,7 +59,7 @@ module AndroidFileLeakConfig implements DataFlow::ConfigSig { succ.asParameter() = arm.getParameter(0) ) or - exists(MethodAccess csma, ServiceOnStartCommandMethod ssm, ClassInstanceExpr ce | + exists(MethodCall csma, ServiceOnStartCommandMethod ssm, ClassInstanceExpr ce | // An intent passed to startService will later be passed to the onStartCommand event of the corresponding service csma.getMethod() instanceof ContextStartServiceMethod and ce.getConstructedType() instanceof TypeIntent and // Intent intent = new Intent(context, FileUploader.class); diff --git a/java/ql/src/experimental/Security/CWE/CWE-208/NonConstantTimeCheckOnSignatureQuery.qll b/java/ql/src/experimental/Security/CWE/CWE-208/NonConstantTimeCheckOnSignatureQuery.qll index 194ae34b792f..e865e18ecaa6 100644 --- a/java/ql/src/experimental/Security/CWE/CWE-208/NonConstantTimeCheckOnSignatureQuery.qll +++ b/java/ql/src/experimental/Security/CWE/CWE-208/NonConstantTimeCheckOnSignatureQuery.qll @@ -7,7 +7,7 @@ import semmle.code.java.dataflow.TaintTracking import semmle.code.java.dataflow.FlowSources /** A method call that produces cryptographic result. */ -abstract private class ProduceCryptoCall extends MethodAccess { +abstract private class ProduceCryptoCall extends MethodCall { Expr output; /** Gets the result of cryptographic operation. */ @@ -51,7 +51,7 @@ private class ProduceSignatureCall extends ProduceCryptoCall { */ private module InitializeEncryptorConfig implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node source) { - exists(MethodAccess ma | + exists(MethodCall ma | ma.getMethod().hasQualifiedName("javax.crypto", "Cipher", "init") and ma.getArgument(0).(VarAccess).getVariable().hasName("ENCRYPT_MODE") and ma.getQualifier() = source.asExpr() @@ -59,7 +59,7 @@ private module InitializeEncryptorConfig implements DataFlow::ConfigSig { } predicate isSink(DataFlow::Node sink) { - exists(MethodAccess ma | + exists(MethodCall ma | ma.getMethod().hasQualifiedName("javax.crypto", "Cipher", "doFinal") and ma.getQualifier() = sink.asExpr() ) @@ -96,7 +96,7 @@ private class ProduceCiphertextCall extends ProduceCryptoCall { /** Holds if `fromNode` to `toNode` is a dataflow step that updates a cryptographic operation. */ private predicate updateCryptoOperationStep(DataFlow2::Node fromNode, DataFlow2::Node toNode) { - exists(MethodAccess call, Method m | + exists(MethodCall call, Method m | m = call.getMethod() and call.getQualifier() = toNode.asExpr() and call.getArgument(0) = fromNode.asExpr() @@ -112,21 +112,21 @@ private predicate updateCryptoOperationStep(DataFlow2::Node fromNode, DataFlow2: /** Holds if `fromNode` to `toNode` is a dataflow step that creates a hash. */ private predicate createMessageDigestStep(DataFlow2::Node fromNode, DataFlow2::Node toNode) { - exists(MethodAccess ma, Method m | m = ma.getMethod() | + exists(MethodCall ma, Method m | m = ma.getMethod() | m.getDeclaringType().hasQualifiedName("java.security", "MessageDigest") and m.hasStringSignature("digest()") and ma.getQualifier() = fromNode.asExpr() and ma = toNode.asExpr() ) or - exists(MethodAccess ma, Method m | m = ma.getMethod() | + exists(MethodCall ma, Method m | m = ma.getMethod() | m.getDeclaringType().hasQualifiedName("java.security", "MessageDigest") and m.hasStringSignature("digest(byte[], int, int)") and ma.getQualifier() = fromNode.asExpr() and ma.getArgument(0) = toNode.asExpr() ) or - exists(MethodAccess ma, Method m | m = ma.getMethod() | + exists(MethodCall ma, Method m | m = ma.getMethod() | m.getDeclaringType().hasQualifiedName("java.security", "MessageDigest") and m.hasStringSignature("digest(byte[])") and ma.getArgument(0) = fromNode.asExpr() and @@ -136,7 +136,7 @@ private predicate createMessageDigestStep(DataFlow2::Node fromNode, DataFlow2::N /** Holds if `fromNode` to `toNode` is a dataflow step that updates a hash. */ private predicate updateMessageDigestStep(DataFlow2::Node fromNode, DataFlow2::Node toNode) { - exists(MethodAccess ma, Method m | m = ma.getMethod() | + exists(MethodCall ma, Method m | m = ma.getMethod() | m.hasQualifiedName("java.security", "MessageDigest", "update") and ma.getArgument(0) = fromNode.asExpr() and ma.getQualifier() = toNode.asExpr() @@ -190,7 +190,7 @@ class CryptoOperationSource extends DataFlow::Node { } /** Methods that use a non-constant-time algorithm for comparing inputs. */ -private class NonConstantTimeEqualsCall extends MethodAccess { +private class NonConstantTimeEqualsCall extends MethodCall { NonConstantTimeEqualsCall() { this.getMethod() .hasQualifiedName("java.lang", "String", ["equals", "contentEquals", "equalsIgnoreCase"]) or @@ -199,7 +199,7 @@ private class NonConstantTimeEqualsCall extends MethodAccess { } /** A static method that uses a non-constant-time algorithm for comparing inputs. */ -private class NonConstantTimeComparisonCall extends StaticMethodAccess { +private class NonConstantTimeComparisonCall extends StaticMethodCall { NonConstantTimeComparisonCall() { this.getMethod().hasQualifiedName("java.util", "Arrays", ["equals", "deepEquals"]) or this.getMethod().hasQualifiedName("java.util", "Objects", "deepEquals") or diff --git a/java/ql/src/experimental/Security/CWE/CWE-208/TimingAttackAgainstHeader.ql b/java/ql/src/experimental/Security/CWE/CWE-208/TimingAttackAgainstHeader.ql index 452eefab7906..05b91bf7f9d1 100644 --- a/java/ql/src/experimental/Security/CWE/CWE-208/TimingAttackAgainstHeader.ql +++ b/java/ql/src/experimental/Security/CWE/CWE-208/TimingAttackAgainstHeader.ql @@ -17,7 +17,7 @@ import semmle.code.java.dataflow.TaintTracking import NonConstantTimeComparisonFlow::PathGraph /** A static method that uses a non-constant-time algorithm for comparing inputs. */ -private class NonConstantTimeComparisonCall extends StaticMethodAccess { +private class NonConstantTimeComparisonCall extends StaticMethodCall { NonConstantTimeComparisonCall() { this.getMethod() .hasQualifiedName("org.apache.commons.lang3", "StringUtils", @@ -26,7 +26,7 @@ private class NonConstantTimeComparisonCall extends StaticMethodAccess { } /** Methods that use a non-constant-time algorithm for comparing inputs. */ -private class NonConstantTimeEqualsCall extends MethodAccess { +private class NonConstantTimeEqualsCall extends MethodCall { NonConstantTimeEqualsCall() { this.getMethod() .hasQualifiedName("java.lang", "String", ["equals", "contentEquals", "equalsIgnoreCase"]) @@ -43,7 +43,7 @@ private predicate isNonConstantComparisonCallArgument(Expr p) { class ClientSuppliedIpTokenCheck extends DataFlow::Node { ClientSuppliedIpTokenCheck() { - exists(MethodAccess ma | + exists(MethodCall ma | ma.getMethod().hasName("getHeader") and ma.getArgument(0).(CompileTimeConstantExpr).getStringValue().toLowerCase() in [ "x-auth-token", "x-csrf-token", "http_x_csrf_token", "x-csrf-param", "x-csrf-header", diff --git a/java/ql/src/experimental/Security/CWE/CWE-295/JxBrowserWithoutCertValidation.ql b/java/ql/src/experimental/Security/CWE/CWE-295/JxBrowserWithoutCertValidation.ql index a77c7900915d..e8a127b64d5b 100644 --- a/java/ql/src/experimental/Security/CWE/CWE-295/JxBrowserWithoutCertValidation.ql +++ b/java/ql/src/experimental/Security/CWE/CWE-295/JxBrowserWithoutCertValidation.ql @@ -74,7 +74,7 @@ private module JxBrowserFlowConfig implements DataFlow::ConfigSig { } predicate isSink(DataFlow::Node sink) { - exists(MethodAccess ma | ma.getMethod() instanceof JxBrowserSetLoadHandler | + exists(MethodCall ma | ma.getMethod() instanceof JxBrowserSetLoadHandler | ma.getArgument(0).getType() instanceof JxBrowserSafeLoadHandler and ma.getQualifier() = sink.asExpr() ) diff --git a/java/ql/src/experimental/Security/CWE/CWE-297/IgnoredHostnameVerification.ql b/java/ql/src/experimental/Security/CWE/CWE-297/IgnoredHostnameVerification.ql index 2a60ce988fc5..9ae5d439743f 100644 --- a/java/ql/src/experimental/Security/CWE/CWE-297/IgnoredHostnameVerification.ql +++ b/java/ql/src/experimental/Security/CWE/CWE-297/IgnoredHostnameVerification.ql @@ -15,7 +15,7 @@ import java import semmle.code.java.security.Encryption /** A `HostnameVerifier.verify()` call that is not wrapped in another `HostnameVerifier`. */ -private class HostnameVerificationCall extends MethodAccess { +private class HostnameVerificationCall extends MethodCall { HostnameVerificationCall() { this.getMethod() instanceof HostnameVerifierVerify and not this.getCaller() instanceof HostnameVerifierVerify diff --git a/java/ql/src/experimental/Security/CWE/CWE-297/InsecureLdapEndpoint.ql b/java/ql/src/experimental/Security/CWE/CWE-297/InsecureLdapEndpoint.ql index bba8213cf0a3..0004f691c6c6 100644 --- a/java/ql/src/experimental/Security/CWE/CWE-297/InsecureLdapEndpoint.ql +++ b/java/ql/src/experimental/Security/CWE/CWE-297/InsecureLdapEndpoint.ql @@ -67,7 +67,7 @@ predicate isBooleanTrue(Expr expr) { or expr.(BooleanLiteral).getBooleanValue() = true // true or - exists(MethodAccess ma | + exists(MethodCall ma | expr = ma and ma.getMethod() instanceof ToStringMethod and ma.getQualifier().(FieldAccess).getField().hasName("TRUE") and @@ -80,22 +80,22 @@ predicate isBooleanTrue(Expr expr) { } /** Holds if `ma` is in a test class or method. */ -predicate isTestMethod(MethodAccess ma) { +predicate isTestMethod(MethodCall ma) { ma.getEnclosingCallable() instanceof TestMethod or ma.getEnclosingCallable().getDeclaringType() instanceof TestClass or ma.getEnclosingCallable().getDeclaringType().getPackage().getName().matches("%test%") or ma.getEnclosingCallable().getDeclaringType().getName().toLowerCase().matches("%test%") } -/** Holds if `MethodAccess` ma disables SSL endpoint check. */ -predicate isInsecureSslEndpoint(MethodAccess ma) { +/** Holds if `MethodCall` ma disables SSL endpoint check. */ +predicate isInsecureSslEndpoint(MethodCall ma) { ( ma.getMethod() instanceof SetSystemPropertyMethod and isPropertyDisableLdapEndpointId(ma.getArgument(0)) and isBooleanTrue(ma.getArgument(1)) //com.sun.jndi.ldap.object.disableEndpointIdentification=true or ma.getMethod() instanceof SetSystemPropertiesMethod and - exists(MethodAccess ma2 | + exists(MethodCall ma2 | ma2.getMethod() instanceof SetPropertyMethod and isPropertyDisableLdapEndpointId(ma2.getArgument(0)) and isBooleanTrue(ma2.getArgument(1)) and //com.sun.jndi.ldap.object.disableEndpointIdentification=true @@ -104,7 +104,7 @@ predicate isInsecureSslEndpoint(MethodAccess ma) { ) } -from MethodAccess ma +from MethodCall ma where isInsecureSslEndpoint(ma) and not isTestMethod(ma) diff --git a/java/ql/src/experimental/Security/CWE/CWE-299/RevocationCheckingLib.qll b/java/ql/src/experimental/Security/CWE/CWE-299/RevocationCheckingLib.qll index ceed388b8061..50dc249a9eac 100644 --- a/java/ql/src/experimental/Security/CWE/CWE-299/RevocationCheckingLib.qll +++ b/java/ql/src/experimental/Security/CWE/CWE-299/RevocationCheckingLib.qll @@ -22,10 +22,10 @@ module DisabledRevocationCheckingFlow = TaintTracking::Global; */ class SslContextGetInstanceSink extends DataFlow::ExprNode { SslContextGetInstanceSink() { - exists(StaticMethodAccess ma, Method m | m = ma.getMethod() | + exists(StaticMethodCall ma, Method m | m = ma.getMethod() | m.getDeclaringType() instanceof SslContext and m.hasName("getInstance") and ma.getArgument(0) = this.asExpr() @@ -50,7 +50,7 @@ class CreateSslParametersSink extends DataFlow::ExprNode { */ class SslParametersSetProtocolsSink extends DataFlow::ExprNode { SslParametersSetProtocolsSink() { - exists(MethodAccess ma, Method m | m = ma.getMethod() | + exists(MethodCall ma, Method m | m = ma.getMethod() | m.getDeclaringType() instanceof SslParameters and m.hasName("setProtocols") and ma.getArgument(0) = this.asExpr() @@ -64,7 +64,7 @@ class SslParametersSetProtocolsSink extends DataFlow::ExprNode { */ class SetEnabledProtocolsSink extends DataFlow::ExprNode { SetEnabledProtocolsSink() { - exists(MethodAccess ma, Method m, RefType type | + exists(MethodCall ma, Method m, RefType type | m = ma.getMethod() and type = m.getDeclaringType() | ( diff --git a/java/ql/src/experimental/Security/CWE/CWE-346/UnvalidatedCors.ql b/java/ql/src/experimental/Security/CWE/CWE-346/UnvalidatedCors.ql index f9a86e1c5f4e..9d47e177a271 100644 --- a/java/ql/src/experimental/Security/CWE/CWE-346/UnvalidatedCors.ql +++ b/java/ql/src/experimental/Security/CWE/CWE-346/UnvalidatedCors.ql @@ -19,7 +19,7 @@ import CorsOriginFlow::PathGraph /** * Holds if `header` sets `Access-Control-Allow-Credentials` to `true`. This ensures fair chances of exploitability. */ -private predicate setsAllowCredentials(MethodAccess header) { +private predicate setsAllowCredentials(MethodCall header) { ( header.getMethod() instanceof ResponseSetHeaderMethod or header.getMethod() instanceof ResponseAddHeaderMethod @@ -29,7 +29,7 @@ private predicate setsAllowCredentials(MethodAccess header) { header.getArgument(1).(CompileTimeConstantExpr).getStringValue().toLowerCase() = "true" } -private class CorsProbableCheckAccess extends MethodAccess { +private class CorsProbableCheckAccess extends MethodCall { CorsProbableCheckAccess() { this.getMethod().hasName("contains") and this.getMethod().getDeclaringType().getASourceSupertype*() instanceof CollectionType @@ -66,7 +66,7 @@ private module CorsOriginConfig implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node source) { source instanceof ThreatModelFlowSource } predicate isSink(DataFlow::Node sink) { - exists(MethodAccess corsHeader, MethodAccess allowCredentialsHeader | + exists(MethodCall corsHeader, MethodCall allowCredentialsHeader | ( corsHeader.getMethod() instanceof ResponseSetHeaderMethod or corsHeader.getMethod() instanceof ResponseAddHeaderMethod diff --git a/java/ql/src/experimental/Security/CWE/CWE-348/ClientSuppliedIpUsedInSecurityCheck.ql b/java/ql/src/experimental/Security/CWE/CWE-348/ClientSuppliedIpUsedInSecurityCheck.ql index 75ac34491b8a..a548af9f83ba 100644 --- a/java/ql/src/experimental/Security/CWE/CWE-348/ClientSuppliedIpUsedInSecurityCheck.ql +++ b/java/ql/src/experimental/Security/CWE/CWE-348/ClientSuppliedIpUsedInSecurityCheck.ql @@ -32,7 +32,7 @@ module ClientSuppliedIpUsedInSecurityCheckConfig implements DataFlow::ConfigSig * later entries may originate from more-trustworthy intermediate proxies, not the original client. */ predicate isBarrier(DataFlow::Node node) { - exists(ArrayAccess aa, MethodAccess ma | aa.getArray() = ma | + exists(ArrayAccess aa, MethodCall ma | aa.getArray() = ma | ma.getQualifier() = node.asExpr() and ma.getMethod() instanceof SplitMethod and not aa.getIndexExpr().(CompileTimeConstantExpr).getIntValue() = 0 diff --git a/java/ql/src/experimental/Security/CWE/CWE-348/ClientSuppliedIpUsedInSecurityCheckLib.qll b/java/ql/src/experimental/Security/CWE/CWE-348/ClientSuppliedIpUsedInSecurityCheckLib.qll index 0e3d11420ba2..7896c49f5314 100644 --- a/java/ql/src/experimental/Security/CWE/CWE-348/ClientSuppliedIpUsedInSecurityCheckLib.qll +++ b/java/ql/src/experimental/Security/CWE/CWE-348/ClientSuppliedIpUsedInSecurityCheckLib.qll @@ -11,7 +11,7 @@ import semmle.code.java.security.QueryInjection */ class ClientSuppliedIpUsedInSecurityCheck extends DataFlow::Node { ClientSuppliedIpUsedInSecurityCheck() { - exists(MethodAccess ma | + exists(MethodCall ma | ma.getMethod().hasName("getHeader") and ma.getArgument(0).(CompileTimeConstantExpr).getStringValue().toLowerCase() in [ "x-forwarded-for", "x-real-ip", "proxy-client-ip", "wl-proxy-client-ip", @@ -34,7 +34,7 @@ abstract class ClientSuppliedIpUsedInSecurityCheckSink extends DataFlow::Node { */ private class CompareSink extends ClientSuppliedIpUsedInSecurityCheckSink { CompareSink() { - exists(MethodAccess ma | + exists(MethodCall ma | ma.getMethod().getName() in ["equals", "equalsIgnoreCase"] and ma.getMethod().getDeclaringType() instanceof TypeString and ma.getMethod().getNumberOfParameters() = 1 and @@ -49,7 +49,7 @@ private class CompareSink extends ClientSuppliedIpUsedInSecurityCheckSink { ) ) or - exists(MethodAccess ma | + exists(MethodCall ma | ma.getMethod().getName() in ["contains", "startsWith"] and ma.getMethod().getDeclaringType() instanceof TypeString and ma.getMethod().getNumberOfParameters() = 1 and @@ -57,7 +57,7 @@ private class CompareSink extends ClientSuppliedIpUsedInSecurityCheckSink { ma.getAnArgument().(CompileTimeConstantExpr).getStringValue().regexpMatch(getIpAddressRegex()) // Matches IP-address-like strings ) or - exists(MethodAccess ma | + exists(MethodCall ma | ma.getMethod().hasName("startsWith") and ma.getMethod() .getDeclaringType() @@ -67,7 +67,7 @@ private class CompareSink extends ClientSuppliedIpUsedInSecurityCheckSink { ma.getAnArgument().(CompileTimeConstantExpr).getStringValue().regexpMatch(getIpAddressRegex()) ) or - exists(MethodAccess ma | + exists(MethodCall ma | ma.getMethod().getName() in ["equals", "equalsIgnoreCase"] and ma.getMethod() .getDeclaringType() diff --git a/java/ql/src/experimental/Security/CWE/CWE-352/JsonStringLib.qll b/java/ql/src/experimental/Security/CWE/CWE-352/JsonStringLib.qll index 2edf03d02ef0..c6d6e6830037 100644 --- a/java/ql/src/experimental/Security/CWE/CWE-352/JsonStringLib.qll +++ b/java/ql/src/experimental/Security/CWE/CWE-352/JsonStringLib.qll @@ -13,7 +13,7 @@ abstract class JsonStringSource extends DataFlow::Node { } */ private class GsonString extends JsonStringSource { GsonString() { - exists(MethodAccess ma, Method m | ma.getMethod() = m | + exists(MethodCall ma, Method m | ma.getMethod() = m | m.hasName("toJson") and m.getDeclaringType().getAnAncestor().hasQualifiedName("com.google.gson", "Gson") and this.asExpr() = ma @@ -29,7 +29,7 @@ private class GsonString extends JsonStringSource { */ private class FastjsonString extends JsonStringSource { FastjsonString() { - exists(MethodAccess ma, Method m | ma.getMethod() = m | + exists(MethodCall ma, Method m | ma.getMethod() = m | m.hasName("toJSONString") and m.getDeclaringType().getAnAncestor().hasQualifiedName("com.alibaba.fastjson", "JSON") and this.asExpr() = ma @@ -45,7 +45,7 @@ private class FastjsonString extends JsonStringSource { */ private class JacksonString extends JsonStringSource { JacksonString() { - exists(MethodAccess ma, Method m | ma.getMethod() = m | + exists(MethodCall ma, Method m | ma.getMethod() = m | m.hasName("writeValueAsString") and m.getDeclaringType() .getAnAncestor() diff --git a/java/ql/src/experimental/Security/CWE/CWE-352/JsonpInjection.ql b/java/ql/src/experimental/Security/CWE/CWE-352/JsonpInjection.ql index 58448c0ed9d6..647175797be7 100644 --- a/java/ql/src/experimental/Security/CWE/CWE-352/JsonpInjection.ql +++ b/java/ql/src/experimental/Security/CWE/CWE-352/JsonpInjection.ql @@ -32,7 +32,7 @@ module RequestResponseFlowConfig implements DataFlow::ConfigSig { } predicate isAdditionalFlowStep(DataFlow::Node pred, DataFlow::Node succ) { - exists(MethodAccess ma | + exists(MethodCall ma | isRequestGetParamMethod(ma) and pred.asExpr() = ma.getQualifier() and succ.asExpr() = ma ) } diff --git a/java/ql/src/experimental/Security/CWE/CWE-352/JsonpInjectionLib.qll b/java/ql/src/experimental/Security/CWE/CWE-352/JsonpInjectionLib.qll index 84c189aac937..65a75392ef45 100644 --- a/java/ql/src/experimental/Security/CWE/CWE-352/JsonpInjectionLib.qll +++ b/java/ql/src/experimental/Security/CWE/CWE-352/JsonpInjectionLib.qll @@ -9,7 +9,7 @@ private import semmle.code.java.dataflow.FlowSources */ abstract class RequestGetMethod extends Method { RequestGetMethod() { - not exists(MethodAccess ma | + not exists(MethodCall ma | // Exclude apparent GET handlers that read a request entity, because this likely indicates this is not in fact a GET handler. // This is particularly a problem with Spring handlers, which can sometimes neglect to specify a request method. // Even if it is in fact a GET handler, such a request method will be unusable in the context `