Merge branch 'main' into redsun82/rust-ast-generator-mustache

This commit is contained in:
Paolo Tranquilli
2025-01-08 17:09:39 +01:00
194 changed files with 21863 additions and 9427 deletions

View File

@@ -1,4 +0,0 @@
---
category: majorAnalysis
---
* Added support for TypeScript 5.7.

64
Cargo.lock generated
View File

@@ -118,7 +118,7 @@ version = "0.1.0"
dependencies = [
"anyhow",
"either",
"itertools 0.12.1",
"itertools 0.14.0",
"mustache",
"proc-macro2",
"quote",
@@ -171,9 +171,9 @@ dependencies = [
[[package]]
name = "bstr"
version = "1.11.1"
version = "1.11.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "786a307d683a5bf92e6fd5fd69a7eb613751668d1d8d67d802846dfe367c62c8"
checksum = "531a9155a481e2ee699d4f98f43c0ca4ff8ee1bfd55c31e9e98fb29d2b176fe0"
dependencies = [
"memchr",
"serde",
@@ -187,9 +187,9 @@ checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c"
[[package]]
name = "bytemuck"
version = "1.20.0"
version = "1.21.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8b37c88a63ffd85d15b406896cc343916d7cf57838a847b3a6f2ca5d39a5695a"
checksum = "ef657dfab802224e671f5818e9a4935f9b1957ed18e58292690cc39e7a4092a3"
[[package]]
name = "byteorder"
@@ -231,9 +231,9 @@ dependencies = [
[[package]]
name = "cc"
version = "1.2.5"
version = "1.2.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c31a0499c1dc64f458ad13872de75c0eb7e3fdb0e67964610c914b034fc5956e"
checksum = "a012a0df96dd6d06ba9a1b29d6402d1a5d77c6befd2566afdc26e10603dc93d7"
dependencies = [
"shlex",
]
@@ -318,9 +318,9 @@ dependencies = [
[[package]]
name = "clap"
version = "4.5.23"
version = "4.5.24"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3135e7ec2ef7b10c6ed8950f0f792ed96ee093fa088608f1c76e569722700c84"
checksum = "9560b07a799281c7e0958b9296854d6fafd4c5f31444a7e5bb1ad6dde5ccf1bd"
dependencies = [
"clap_builder",
"clap_derive",
@@ -328,9 +328,9 @@ dependencies = [
[[package]]
name = "clap_builder"
version = "4.5.23"
version = "4.5.24"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "30582fc632330df2bd26877bde0c1f4470d57c582bbc070376afcd04d8cb4838"
checksum = "874e0dd3eb68bf99058751ac9712f622e61e6f393a94f7128fa26e3f02f5c7cd"
dependencies = [
"anstream",
"anstyle",
@@ -340,9 +340,9 @@ dependencies = [
[[package]]
name = "clap_derive"
version = "4.5.18"
version = "4.5.24"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4ac6a0c7b1a9e9a5186361f67dfa1b88213572f427fb9ab038efb2bd8c582dab"
checksum = "54b755194d6389280185988721fffba69495eed5ee9feeee9a599b53db80318c"
dependencies = [
"heck 0.5.0",
"proc-macro2",
@@ -414,7 +414,7 @@ dependencies = [
"dunce",
"figment",
"glob",
"itertools 0.13.0",
"itertools 0.14.0",
"log 0.4.22",
"num-traits",
"ra_ap_base_db",
@@ -746,9 +746,9 @@ dependencies = [
[[package]]
name = "glob"
version = "0.3.1"
version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b"
checksum = "a8d1add55171497b4705a648c6b583acafb01d58050a51727785f0b2c8e0a2b2"
[[package]]
name = "globset"
@@ -925,9 +925,9 @@ dependencies = [
[[package]]
name = "itertools"
version = "0.13.0"
version = "0.14.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "413ee7dfc52ee1a4949ceeb7dbc8a33f2d6c088194d9f922fb8318faf1f01186"
checksum = "2b192c782037fadd9cfa75548310488aabdbf3d2da73885b31bd0abd03351285"
dependencies = [
"either",
]
@@ -1272,9 +1272,9 @@ dependencies = [
[[package]]
name = "pin-project-lite"
version = "0.2.15"
version = "0.2.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "915a1e146535de9163f3987b8944ed8cf49a18bb0056bcebcdcece385cece4ff"
checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b"
[[package]]
name = "powerfmt"
@@ -1315,9 +1315,9 @@ dependencies = [
[[package]]
name = "quote"
version = "1.0.37"
version = "1.0.38"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af"
checksum = "0e4dccaaaf89514f546c693ddc140f729f958c247918a13380cccc6078391acc"
dependencies = [
"proc-macro2",
]
@@ -2058,18 +2058,18 @@ dependencies = [
[[package]]
name = "serde"
version = "1.0.216"
version = "1.0.217"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0b9781016e935a97e8beecf0c933758c97a5520d32930e460142b4cd80c6338e"
checksum = "02fc4265df13d6fa1d00ecff087228cc0a2b5f3c0e87e258d8b94a156e984c70"
dependencies = [
"serde_derive",
]
[[package]]
name = "serde_derive"
version = "1.0.216"
version = "1.0.217"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "46f859dbbf73865c6627ed570e78961cd3ac92407a2d117204c49232485da55e"
checksum = "5a9bf7cf98d04a2b28aead066b7496853d4779c9cc183c440dbac457641e19a0"
dependencies = [
"proc-macro2",
"quote",
@@ -2078,9 +2078,9 @@ dependencies = [
[[package]]
name = "serde_json"
version = "1.0.133"
version = "1.0.135"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c7fceb2473b9166b2294ef05efcb65a3db80803f0b03ef86a5fc88a2b85ee377"
checksum = "2b0d7ba2887406110130a978386c4e1befb98c674b4fba677954e4db976630d9"
dependencies = [
"itoa",
"memchr",
@@ -2201,9 +2201,9 @@ checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f"
[[package]]
name = "syn"
version = "2.0.90"
version = "2.0.95"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "919d3b74a5dd0ccd15aeb8f93e7006bd9e14c295087c9896a110f490752bcf31"
checksum = "46f71c0377baf4ef1cc3e3402ded576dccc315800fbc62dfc7fe04b009773b4a"
dependencies = [
"proc-macro2",
"quote",
@@ -2360,9 +2360,9 @@ dependencies = [
[[package]]
name = "tree-sitter"
version = "0.24.5"
version = "0.24.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8ac95b18f0f727aaaa012bd5179a1916706ee3ed071920fdbda738750b0c0bf5"
checksum = "5f2434c86ba59ed15af56039cc5bf1acf8ba76ce301e32ef08827388ef285ec5"
dependencies = [
"cc",
"regex",

View File

@@ -70,7 +70,7 @@ use_repo(py_deps, "vendor__anyhow-1.0.44", "vendor__cc-1.0.70", "vendor__clap-2.
# deps for ruby+rust
# keep in sync by running `misc/bazel/3rdparty/update_cargo_deps.sh`
tree_sitter_extractors_deps = use_extension("//misc/bazel/3rdparty:tree_sitter_extractors_extension.bzl", "r")
use_repo(tree_sitter_extractors_deps, "vendor__anyhow-1.0.95", "vendor__argfile-0.2.1", "vendor__chrono-0.4.39", "vendor__clap-4.5.23", "vendor__dunce-1.0.5", "vendor__either-1.13.0", "vendor__encoding-0.2.33", "vendor__figment-0.10.19", "vendor__flate2-1.0.35", "vendor__glob-0.3.1", "vendor__globset-0.4.15", "vendor__itertools-0.12.1", "vendor__itertools-0.13.0", "vendor__lazy_static-1.5.0", "vendor__log-0.4.22", "vendor__mustache-0.9.0", "vendor__num-traits-0.2.19", "vendor__num_cpus-1.16.0", "vendor__proc-macro2-1.0.92", "vendor__quote-1.0.37", "vendor__ra_ap_base_db-0.0.248", "vendor__ra_ap_cfg-0.0.248", "vendor__ra_ap_hir-0.0.248", "vendor__ra_ap_hir_def-0.0.248", "vendor__ra_ap_hir_expand-0.0.248", "vendor__ra_ap_ide_db-0.0.248", "vendor__ra_ap_intern-0.0.248", "vendor__ra_ap_load-cargo-0.0.248", "vendor__ra_ap_parser-0.0.248", "vendor__ra_ap_paths-0.0.248", "vendor__ra_ap_project_model-0.0.248", "vendor__ra_ap_span-0.0.248", "vendor__ra_ap_stdx-0.0.248", "vendor__ra_ap_syntax-0.0.248", "vendor__ra_ap_vfs-0.0.248", "vendor__rand-0.8.5", "vendor__rayon-1.10.0", "vendor__regex-1.11.1", "vendor__serde-1.0.216", "vendor__serde_json-1.0.133", "vendor__serde_with-3.12.0", "vendor__stderrlog-0.6.0", "vendor__syn-2.0.90", "vendor__tracing-0.1.41", "vendor__tracing-subscriber-0.3.19", "vendor__tree-sitter-0.24.5", "vendor__tree-sitter-embedded-template-0.23.2", "vendor__tree-sitter-json-0.24.8", "vendor__tree-sitter-ql-0.23.1", "vendor__tree-sitter-ruby-0.23.1", "vendor__triomphe-0.1.14", "vendor__ungrammar-1.16.1")
use_repo(tree_sitter_extractors_deps, "vendor__anyhow-1.0.95", "vendor__argfile-0.2.1", "vendor__chrono-0.4.39", "vendor__clap-4.5.24", "vendor__dunce-1.0.5", "vendor__either-1.13.0", "vendor__encoding-0.2.33", "vendor__figment-0.10.19", "vendor__flate2-1.0.35", "vendor__glob-0.3.2", "vendor__globset-0.4.15", "vendor__itertools-0.14.0", "vendor__lazy_static-1.5.0", "vendor__log-0.4.22", "vendor__mustache-0.9.0", "vendor__num-traits-0.2.19", "vendor__num_cpus-1.16.0", "vendor__proc-macro2-1.0.92", "vendor__quote-1.0.38", "vendor__ra_ap_base_db-0.0.248", "vendor__ra_ap_cfg-0.0.248", "vendor__ra_ap_hir-0.0.248", "vendor__ra_ap_hir_def-0.0.248", "vendor__ra_ap_hir_expand-0.0.248", "vendor__ra_ap_ide_db-0.0.248", "vendor__ra_ap_intern-0.0.248", "vendor__ra_ap_load-cargo-0.0.248", "vendor__ra_ap_parser-0.0.248", "vendor__ra_ap_paths-0.0.248", "vendor__ra_ap_project_model-0.0.248", "vendor__ra_ap_span-0.0.248", "vendor__ra_ap_stdx-0.0.248", "vendor__ra_ap_syntax-0.0.248", "vendor__ra_ap_vfs-0.0.248", "vendor__rand-0.8.5", "vendor__rayon-1.10.0", "vendor__regex-1.11.1", "vendor__serde-1.0.217", "vendor__serde_json-1.0.135", "vendor__serde_with-3.12.0", "vendor__stderrlog-0.6.0", "vendor__syn-2.0.95", "vendor__tracing-0.1.41", "vendor__tracing-subscriber-0.3.19", "vendor__tree-sitter-0.24.6", "vendor__tree-sitter-embedded-template-0.23.2", "vendor__tree-sitter-json-0.24.8", "vendor__tree-sitter-ql-0.23.1", "vendor__tree-sitter-ruby-0.23.1", "vendor__triomphe-0.1.14", "vendor__ungrammar-1.16.1")
http_archive = use_repo_rule("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,5 @@
description: Support concept templates
compatibility: full
concept_templates.rel: delete
concept_template_argument.rel: delete
concept_template_argument_value.rel: delete

View File

@@ -0,0 +1,5 @@
---
category: feature
---
* A new class `Concept` was introduced, which represents C++20 concepts.
* The `getTemplateArgumentType` and `getTemplateArgumentValue` predicates of the `Declaration` class now also yield template arguments of concepts.

View File

@@ -159,3 +159,32 @@ class ConceptIdExpr extends RequirementExpr, @concept_id {
override string getAPrimaryQlClass() { result = "ConceptIdExpr" }
}
/**
* A C++ concept.
*
* For example:
* ```cpp
* template<class T>
* concept C = std::is_same<T, int>::value;
* ```
*/
class Concept extends Declaration, @concept_template {
override string getAPrimaryQlClass() { result = "Concept" }
override Location getLocation() { concept_templates(underlyingElement(this), _, result) }
override string getName() { concept_templates(underlyingElement(this), result, _) }
/**
* Gets the constraint expression of the concept.
*
* For example, in
* ```cpp
* template<class T>
* concept C = std::is_same<T, int>::value;
* ```
* the constraint expression is `std::is_same<T, int>::value`.
*/
Expr getExpr() { result.getParent() = this }
}

View File

@@ -279,6 +279,8 @@ class Declaration extends Locatable, @declaration {
variable_template_argument(underlyingElement(this), index, unresolveElement(result))
or
template_template_argument(underlyingElement(this), index, unresolveElement(result))
or
concept_template_argument(underlyingElement(this), index, unresolveElement(result))
}
private Expr getTemplateArgumentValue(int index) {
@@ -289,6 +291,8 @@ class Declaration extends Locatable, @declaration {
variable_template_argument_value(underlyingElement(this), index, unresolveElement(result))
or
template_template_argument_value(underlyingElement(this), index, unresolveElement(result))
or
concept_template_argument_value(underlyingElement(this), index, unresolveElement(result))
}
}

View File

@@ -876,6 +876,24 @@ template_template_argument_value(
int arg_value: @expr ref
);
@concept = @concept_template | @concept_id;
concept_templates(
unique int concept_id: @concept_template,
string name: string ref,
int location: @location_default ref
);
concept_template_argument(
int concept_id: @concept ref,
int index: int ref,
int arg_type: @type ref
);
concept_template_argument_value(
int concept_id: @concept ref,
int index: int ref,
int arg_value: @expr ref
);
routinetypes(
unique int id: @routinetype,
int return_type: @type ref
@@ -1106,7 +1124,8 @@ frienddecls(
| @declaredtype
| @variable
| @enumconstant
| @frienddecl;
| @frienddecl
| @concept_template;
@member = @membervariable
| @function

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,2 @@
description: Support concept templates
compatibility: partial

View File

@@ -0,0 +1,9 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net9.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
</Project>

View File

@@ -0,0 +1,20 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<base href="/" />
<link rel="stylesheet" href="bootstrap/bootstrap.min.css" />
<link rel="stylesheet" href="app.css" />
<link rel="stylesheet" href="BlazorTest.styles.css" />
<link rel="icon" type="image/png" href="favicon.png" />
<HeadOutlet />
</head>
<body>
<Routes />
<script src="_framework/blazor.web.js"></script>
</body>
</html>

View File

@@ -0,0 +1,23 @@
@inherits LayoutComponentBase
<div class="page">
<div class="sidebar">
<NavMenu />
</div>
<main>
<div class="top-row px-4">
<a href="https://learn.microsoft.com/aspnet/core/" target="_blank">About</a>
</div>
<article class="content px-4">
@Body
</article>
</main>
</div>
<div id="blazor-error-ui">
An unhandled error has occurred.
<a href="" class="reload">Reload</a>
<a class="dismiss">🗙</a>
</div>

View File

@@ -0,0 +1,96 @@
.page {
position: relative;
display: flex;
flex-direction: column;
}
main {
flex: 1;
}
.sidebar {
background-image: linear-gradient(180deg, rgb(5, 39, 103) 0%, #3a0647 70%);
}
.top-row {
background-color: #f7f7f7;
border-bottom: 1px solid #d6d5d5;
justify-content: flex-end;
height: 3.5rem;
display: flex;
align-items: center;
}
.top-row ::deep a, .top-row ::deep .btn-link {
white-space: nowrap;
margin-left: 1.5rem;
text-decoration: none;
}
.top-row ::deep a:hover, .top-row ::deep .btn-link:hover {
text-decoration: underline;
}
.top-row ::deep a:first-child {
overflow: hidden;
text-overflow: ellipsis;
}
@media (max-width: 640.98px) {
.top-row {
justify-content: space-between;
}
.top-row ::deep a, .top-row ::deep .btn-link {
margin-left: 0;
}
}
@media (min-width: 641px) {
.page {
flex-direction: row;
}
.sidebar {
width: 250px;
height: 100vh;
position: sticky;
top: 0;
}
.top-row {
position: sticky;
top: 0;
z-index: 1;
}
.top-row.auth ::deep a:first-child {
flex: 1;
text-align: right;
width: 0;
}
.top-row, article {
padding-left: 2rem !important;
padding-right: 1.5rem !important;
}
}
#blazor-error-ui {
background: lightyellow;
bottom: 0;
box-shadow: 0 -1px 2px rgba(0, 0, 0, 0.2);
display: none;
left: 0;
padding: 0.6rem 1.25rem 0.7rem 1.25rem;
position: fixed;
width: 100%;
z-index: 1000;
}
#blazor-error-ui .dismiss {
cursor: pointer;
position: absolute;
right: 0.75rem;
top: 0.5rem;
}

View File

@@ -0,0 +1,19 @@
<div class="top-row ps-3 navbar navbar-dark">
<div class="container-fluid">
<a class="navbar-brand" href="">BlazorTest</a>
</div>
</div>
<input type="checkbox" title="Navigation menu" class="navbar-toggler" />
<div class="nav-scrollable" onclick="document.querySelector('.navbar-toggler').click()">
<nav class="flex-column">
<div class="nav-item px-3">
<NavLink class="nav-link" href="test">
<span class="bi bi-plus-square-fill-nav-menu" aria-hidden="true"></span> Test
</NavLink>
</div>
</nav>
</div>

View File

@@ -0,0 +1,105 @@
.navbar-toggler {
appearance: none;
cursor: pointer;
width: 3.5rem;
height: 2.5rem;
color: white;
position: absolute;
top: 0.5rem;
right: 1rem;
border: 1px solid rgba(255, 255, 255, 0.1);
background: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'%3e%3cpath stroke='rgba%28255, 255, 255, 0.55%29' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e") no-repeat center/1.75rem rgba(255, 255, 255, 0.1);
}
.navbar-toggler:checked {
background-color: rgba(255, 255, 255, 0.5);
}
.top-row {
height: 3.5rem;
background-color: rgba(0,0,0,0.4);
}
.navbar-brand {
font-size: 1.1rem;
}
.bi {
display: inline-block;
position: relative;
width: 1.25rem;
height: 1.25rem;
margin-right: 0.75rem;
top: -1px;
background-size: cover;
}
.bi-house-door-fill-nav-menu {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='white' class='bi bi-house-door-fill' viewBox='0 0 16 16'%3E%3Cpath d='M6.5 14.5v-3.505c0-.245.25-.495.5-.495h2c.25 0 .5.25.5.5v3.5a.5.5 0 0 0 .5.5h4a.5.5 0 0 0 .5-.5v-7a.5.5 0 0 0-.146-.354L13 5.793V2.5a.5.5 0 0 0-.5-.5h-1a.5.5 0 0 0-.5.5v1.293L8.354 1.146a.5.5 0 0 0-.708 0l-6 6A.5.5 0 0 0 1.5 7.5v7a.5.5 0 0 0 .5.5h4a.5.5 0 0 0 .5-.5Z'/%3E%3C/svg%3E");
}
.bi-plus-square-fill-nav-menu {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='white' class='bi bi-plus-square-fill' viewBox='0 0 16 16'%3E%3Cpath d='M2 0a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V2a2 2 0 0 0-2-2H2zm6.5 4.5v3h3a.5.5 0 0 1 0 1h-3v3a.5.5 0 0 1-1 0v-3h-3a.5.5 0 0 1 0-1h3v-3a.5.5 0 0 1 1 0z'/%3E%3C/svg%3E");
}
.bi-list-nested-nav-menu {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='white' class='bi bi-list-nested' viewBox='0 0 16 16'%3E%3Cpath fill-rule='evenodd' d='M4.5 11.5A.5.5 0 0 1 5 11h10a.5.5 0 0 1 0 1H5a.5.5 0 0 1-.5-.5zm-2-4A.5.5 0 0 1 3 7h10a.5.5 0 0 1 0 1H3a.5.5 0 0 1-.5-.5zm-2-4A.5.5 0 0 1 1 3h10a.5.5 0 0 1 0 1H1a.5.5 0 0 1-.5-.5z'/%3E%3C/svg%3E");
}
.nav-item {
font-size: 0.9rem;
padding-bottom: 0.5rem;
}
.nav-item:first-of-type {
padding-top: 1rem;
}
.nav-item:last-of-type {
padding-bottom: 1rem;
}
.nav-item ::deep .nav-link {
color: #d7d7d7;
background: none;
border: none;
border-radius: 4px;
height: 3rem;
display: flex;
align-items: center;
line-height: 3rem;
width: 100%;
}
.nav-item ::deep a.active {
background-color: rgba(255,255,255,0.37);
color: white;
}
.nav-item ::deep .nav-link:hover {
background-color: rgba(255,255,255,0.1);
color: white;
}
.nav-scrollable {
display: none;
}
.navbar-toggler:checked ~ .nav-scrollable {
display: block;
}
@media (min-width: 641px) {
.navbar-toggler {
display: none;
}
.nav-scrollable {
/* Never collapse the sidebar for wide screens */
display: block;
/* Allow sidebar to scroll for tall menus */
height: calc(100vh - 3.5rem);
overflow-y: auto;
}
}

View File

@@ -0,0 +1,20 @@
@rendermode InteractiveServer
<input @bind="Param1" @bind:event="onchange" @bind:after="Fire">
@code {
[Parameter]
public string? Param1 { get; set; } = "";
[Parameter]
public EventCallback<string?> ValueChanged { get; set; }
[Parameter]
public EventCallback<string?> Param1Changed { get; set; }
private void Fire()
{
ValueChanged.InvokeAsync(Param1);
Param1Changed.InvokeAsync(Param1);
}
}

View File

@@ -0,0 +1,11 @@
@rendermode InteractiveServer
<div>
<p>Value from InputText: @Value</p>
<p>Raw value from InputText: @(new MarkupString(Value))</p>
</div>
@code {
[Parameter]
public string Value { get; set; } = "";
}

View File

@@ -0,0 +1,36 @@
@page "/Error"
@using System.Diagnostics
<PageTitle>Error</PageTitle>
<h1 class="text-danger">Error.</h1>
<h2 class="text-danger">An error occurred while processing your request.</h2>
@if (ShowRequestId)
{
<p>
<strong>Request ID:</strong> <code>@RequestId</code>
</p>
}
<h3>Development Mode</h3>
<p>
Swapping to <strong>Development</strong> environment will display more detailed information about the error that occurred.
</p>
<p>
<strong>The Development environment shouldn't be enabled for deployed applications.</strong>
It can result in displaying sensitive information from exceptions to end users.
For local debugging, enable the <strong>Development</strong> environment by setting the <strong>ASPNETCORE_ENVIRONMENT</strong> environment variable to <strong>Development</strong>
and restarting the app.
</p>
@code{
[CascadingParameter]
private HttpContext? HttpContext { get; set; }
private string? RequestId { get; set; }
private bool ShowRequestId => !string.IsNullOrEmpty(RequestId);
protected override void OnInitialized() =>
RequestId = Activity.Current?.Id ?? HttpContext?.TraceIdentifier;
}

View File

@@ -0,0 +1,125 @@
@page "/"
@page "/test/{urlParam?}"
@rendermode InteractiveServer
<PageTitle>TestPage</PageTitle>
<div>
<h3>Route parameter</h3>
<p>Go to: <a href="/test/@XssUrl">/test/@XssUrl</a></p>
<p>Parameter from URL: @UrlParam</p>
<p>Raw parameter from URL: @((MarkupString)UrlParam)</p>
</div>
<hr />
<div>
<h3>Query parameter</h3>
<p>Go to: <a href="/test/?qs=@XssUrl">/test/?qs=@XssUrl</a></p>
<p>Parameter from query string: @QueryParam</p>
<p>Raw parameter from query string: @(new MarkupString(QueryParam))</p>
</div>
<hr />
<div>
<h3>Bind InputText component</h3>
<InputText @bind-Value="InputValue1" />
<p>Value from InputText: @InputValue1</p>
<p>Raw value from InputText: @(new MarkupString(InputValue1))</p>
</div>
<hr />
<div>
<h3>Bind input element</h3>
<input @bind="InputValue2">
<p>Value from InputText: @InputValue2</p>
<p>Raw value from InputText: @(new MarkupString(InputValue2))</p>
</div>
<hr />
<div>
<h3>Bind through object property</h3>
<input @bind="Container1.Value">
<p>Value from InputText: @Container1.Value</p>
<p>Raw value from InputText: @(new MarkupString(Container1.Value))</p>
</div>
<hr />
<div>
<h3>Input component with custom event</h3>
<MyInput Param1="@InputValue3" ValueChanged="MyInputChanged" />
<p>Value from InputText: @InputValue3</p>
<p>Raw value from InputText: @(new MarkupString(InputValue3))</p>
</div>
<hr />
<div>
<h3>Input component with binding</h3>
<MyInput @bind-Param1="InputValue4" />
<p>Value from InputText: @InputValue4</p>
<p>Raw value from InputText: @(new MarkupString(InputValue4))</p>
</div>
<hr />
<div>
<h3>Input, Output components</h3>
<MyInput @bind-Param1="InputValue5" />
<MyOutput Value="@InputValue5" />
</div>
<hr />
<div>
<h3>Bind InputText, Output component</h3>
<InputText @bind-Value="InputValue6" />
<MyOutput Value="@InputValue6" />
</div>
@code {
public class Container
{
public string? Value { get; set; } = "";
}
private const string XssUrl = "<b>aaaa<%2Fb>";
private const string XssUrl2 = "<b>aaaa</b>";
[Parameter]
public string UrlParam { get; set; } = "";
[SupplyParameterFromQuery(Name = "qs")]
public string QueryParam { get; set; } = "";
public string InputValue1 { get; set; } = "";
public string InputValue2 { get; set; } = "";
public string InputValue3 { get; set; } = "";
public string InputValue4 { get; set; } = "";
public string InputValue5 { get; set; } = "";
public string InputValue6 { get; set; } = "";
public Container Container1 { get; set; } = new Container();
protected override void OnInitialized()
{
InputValue1 = XssUrl2;
InputValue2 = XssUrl2;
Container1.Value = XssUrl2;
InputValue3 = XssUrl2;
InputValue4 = XssUrl2;
InputValue5 = XssUrl2;
InputValue6 = XssUrl2;
}
private void MyInputChanged(string value)
{
InputValue3 = value;
}
}

View File

@@ -0,0 +1,6 @@
<Router AppAssembly="typeof(Program).Assembly">
<Found Context="routeData">
<RouteView RouteData="routeData" DefaultLayout="typeof(Layout.MainLayout)" />
<FocusOnNavigate RouteData="routeData" Selector="h1" />
</Found>
</Router>

View File

@@ -0,0 +1,10 @@
@using System.Net.Http
@using System.Net.Http.Json
@using Microsoft.AspNetCore.Components.Forms
@using Microsoft.AspNetCore.Components.Routing
@using Microsoft.AspNetCore.Components.Web
@using static Microsoft.AspNetCore.Components.Web.RenderMode
@using Microsoft.AspNetCore.Components.Web.Virtualization
@using Microsoft.JSInterop
@using BlazorTest
@using BlazorTest.Components

View File

@@ -0,0 +1,27 @@
using BlazorTest.Components;
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddRazorComponents()
.AddInteractiveServerComponents();
var app = builder.Build();
// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error", createScopeForErrors: true);
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseAntiforgery();
app.MapRazorComponents<App>()
.AddInteractiveServerRenderMode();
app.Run();

View File

@@ -0,0 +1,14 @@
{
"$schema": "http://json.schemastore.org/launchsettings.json",
"profiles": {
"http": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": true,
"applicationUrl": "http://localhost:5047",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
}
}
}

View File

@@ -0,0 +1,9 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"AllowedHosts": "*"
}

View File

@@ -0,0 +1,5 @@
{
"sdk": {
"version": "9.0.100"
}
}

View File

@@ -0,0 +1,51 @@
html, body {
font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
}
a, .btn-link {
color: #006bb7;
}
.btn-primary {
color: #fff;
background-color: #1b6ec2;
border-color: #1861ac;
}
.btn:focus, .btn:active:focus, .btn-link.nav-link:focus, .form-control:focus, .form-check-input:focus {
box-shadow: 0 0 0 0.1rem white, 0 0 0 0.25rem #258cfb;
}
.content {
padding-top: 1.1rem;
}
h1:focus {
outline: none;
}
.valid.modified:not([type=checkbox]) {
outline: 1px solid #26b050;
}
.invalid {
outline: 1px solid #e50000;
}
.validation-message {
color: #e50000;
}
.blazor-error-boundary {
background: url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTYiIGhlaWdodD0iNDkiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIG92ZXJmbG93PSJoaWRkZW4iPjxkZWZzPjxjbGlwUGF0aCBpZD0iY2xpcDAiPjxyZWN0IHg9IjIzNSIgeT0iNTEiIHdpZHRoPSI1NiIgaGVpZ2h0PSI0OSIvPjwvY2xpcFBhdGg+PC9kZWZzPjxnIGNsaXAtcGF0aD0idXJsKCNjbGlwMCkiIHRyYW5zZm9ybT0idHJhbnNsYXRlKC0yMzUgLTUxKSI+PHBhdGggZD0iTTI2My41MDYgNTFDMjY0LjcxNyA1MSAyNjUuODEzIDUxLjQ4MzcgMjY2LjYwNiA1Mi4yNjU4TDI2Ny4wNTIgNTIuNzk4NyAyNjcuNTM5IDUzLjYyODMgMjkwLjE4NSA5Mi4xODMxIDI5MC41NDUgOTIuNzk1IDI5MC42NTYgOTIuOTk2QzI5MC44NzcgOTMuNTEzIDI5MSA5NC4wODE1IDI5MSA5NC42NzgyIDI5MSA5Ny4wNjUxIDI4OS4wMzggOTkgMjg2LjYxNyA5OUwyNDAuMzgzIDk5QzIzNy45NjMgOTkgMjM2IDk3LjA2NTEgMjM2IDk0LjY3ODIgMjM2IDk0LjM3OTkgMjM2LjAzMSA5NC4wODg2IDIzNi4wODkgOTMuODA3MkwyMzYuMzM4IDkzLjAxNjIgMjM2Ljg1OCA5Mi4xMzE0IDI1OS40NzMgNTMuNjI5NCAyNTkuOTYxIDUyLjc5ODUgMjYwLjQwNyA1Mi4yNjU4QzI2MS4yIDUxLjQ4MzcgMjYyLjI5NiA1MSAyNjMuNTA2IDUxWk0yNjMuNTg2IDY2LjAxODNDMjYwLjczNyA2Ni4wMTgzIDI1OS4zMTMgNjcuMTI0NSAyNTkuMzEzIDY5LjMzNyAyNTkuMzEzIDY5LjYxMDIgMjU5LjMzMiA2OS44NjA4IDI1OS4zNzEgNzAuMDg4N0wyNjEuNzk1IDg0LjAxNjEgMjY1LjM4IDg0LjAxNjEgMjY3LjgyMSA2OS43NDc1QzI2Ny44NiA2OS43MzA5IDI2Ny44NzkgNjkuNTg3NyAyNjcuODc5IDY5LjMxNzkgMjY3Ljg3OSA2Ny4xMTgyIDI2Ni40NDggNjYuMDE4MyAyNjMuNTg2IDY2LjAxODNaTTI2My41NzYgODYuMDU0N0MyNjEuMDQ5IDg2LjA1NDcgMjU5Ljc4NiA4Ny4zMDA1IDI1OS43ODYgODkuNzkyMSAyNTkuNzg2IDkyLjI4MzcgMjYxLjA0OSA5My41Mjk1IDI2My41NzYgOTMuNTI5NSAyNjYuMTE2IDkzLjUyOTUgMjY3LjM4NyA5Mi4yODM3IDI2Ny4zODcgODkuNzkyMSAyNjcuMzg3IDg3LjMwMDUgMjY2LjExNiA4Ni4wNTQ3IDI2My41NzYgODYuMDU0N1oiIGZpbGw9IiNGRkU1MDAiIGZpbGwtcnVsZT0iZXZlbm9kZCIvPjwvZz48L3N2Zz4=) no-repeat 1rem/1.8rem, #b32121;
padding: 1rem 1rem 1rem 3.7rem;
color: white;
}
.blazor-error-boundary::after {
content: "An error has occurred."
}
.darker-border-checkbox.form-check-input {
border-color: #929292;
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@@ -0,0 +1,22 @@
| BlazorTest/Components/App.razor:0:0:0:0 | BlazorTest/Components/App.razor |
| BlazorTest/Components/Layout/MainLayout.razor:0:0:0:0 | BlazorTest/Components/Layout/MainLayout.razor |
| BlazorTest/Components/Layout/NavMenu.razor:0:0:0:0 | BlazorTest/Components/Layout/NavMenu.razor |
| BlazorTest/Components/MyInput.razor:0:0:0:0 | BlazorTest/Components/MyInput.razor |
| BlazorTest/Components/MyOutput.razor:0:0:0:0 | BlazorTest/Components/MyOutput.razor |
| BlazorTest/Components/Pages/Error.razor:0:0:0:0 | BlazorTest/Components/Pages/Error.razor |
| BlazorTest/Components/Pages/TestPage.razor:0:0:0:0 | BlazorTest/Components/Pages/TestPage.razor |
| BlazorTest/Components/Routes.razor:0:0:0:0 | BlazorTest/Components/Routes.razor |
| BlazorTest/Components/_Imports.razor:0:0:0:0 | BlazorTest/Components/_Imports.razor |
| BlazorTest/Program.cs:0:0:0:0 | BlazorTest/Program.cs |
| BlazorTest/obj/Debug/net9.0/.NETCoreApp,Version=v9.0.AssemblyAttributes.cs:0:0:0:0 | BlazorTest/obj/Debug/net9.0/.NETCoreApp,Version=v9.0.AssemblyAttributes.cs |
| BlazorTest/obj/Debug/net9.0/BlazorTest.AssemblyInfo.cs:0:0:0:0 | BlazorTest/obj/Debug/net9.0/BlazorTest.AssemblyInfo.cs |
| BlazorTest/obj/Debug/net9.0/BlazorTest.GlobalUsings.g.cs:0:0:0:0 | BlazorTest/obj/Debug/net9.0/BlazorTest.GlobalUsings.g.cs |
| BlazorTest/obj/Debug/net9.0/generated/Microsoft.CodeAnalysis.Razor.Compiler/Microsoft.NET.Sdk.Razor.SourceGenerators.RazorSourceGenerator/Components_App_razor.g.cs:0:0:0:0 | BlazorTest/obj/Debug/net9.0/generated/Microsoft.CodeAnalysis.Razor.Compiler/Microsoft.NET.Sdk.Razor.SourceGenerators.RazorSourceGenerator/Components_App_razor.g.cs |
| BlazorTest/obj/Debug/net9.0/generated/Microsoft.CodeAnalysis.Razor.Compiler/Microsoft.NET.Sdk.Razor.SourceGenerators.RazorSourceGenerator/Components_Layout_MainLayout_razor.g.cs:0:0:0:0 | BlazorTest/obj/Debug/net9.0/generated/Microsoft.CodeAnalysis.Razor.Compiler/Microsoft.NET.Sdk.Razor.SourceGenerators.RazorSourceGenerator/Components_Layout_MainLayout_razor.g.cs |
| BlazorTest/obj/Debug/net9.0/generated/Microsoft.CodeAnalysis.Razor.Compiler/Microsoft.NET.Sdk.Razor.SourceGenerators.RazorSourceGenerator/Components_Layout_NavMenu_razor.g.cs:0:0:0:0 | BlazorTest/obj/Debug/net9.0/generated/Microsoft.CodeAnalysis.Razor.Compiler/Microsoft.NET.Sdk.Razor.SourceGenerators.RazorSourceGenerator/Components_Layout_NavMenu_razor.g.cs |
| BlazorTest/obj/Debug/net9.0/generated/Microsoft.CodeAnalysis.Razor.Compiler/Microsoft.NET.Sdk.Razor.SourceGenerators.RazorSourceGenerator/Components_MyInput_razor.g.cs:0:0:0:0 | BlazorTest/obj/Debug/net9.0/generated/Microsoft.CodeAnalysis.Razor.Compiler/Microsoft.NET.Sdk.Razor.SourceGenerators.RazorSourceGenerator/Components_MyInput_razor.g.cs |
| BlazorTest/obj/Debug/net9.0/generated/Microsoft.CodeAnalysis.Razor.Compiler/Microsoft.NET.Sdk.Razor.SourceGenerators.RazorSourceGenerator/Components_MyOutput_razor.g.cs:0:0:0:0 | BlazorTest/obj/Debug/net9.0/generated/Microsoft.CodeAnalysis.Razor.Compiler/Microsoft.NET.Sdk.Razor.SourceGenerators.RazorSourceGenerator/Components_MyOutput_razor.g.cs |
| BlazorTest/obj/Debug/net9.0/generated/Microsoft.CodeAnalysis.Razor.Compiler/Microsoft.NET.Sdk.Razor.SourceGenerators.RazorSourceGenerator/Components_Pages_Error_razor.g.cs:0:0:0:0 | BlazorTest/obj/Debug/net9.0/generated/Microsoft.CodeAnalysis.Razor.Compiler/Microsoft.NET.Sdk.Razor.SourceGenerators.RazorSourceGenerator/Components_Pages_Error_razor.g.cs |
| BlazorTest/obj/Debug/net9.0/generated/Microsoft.CodeAnalysis.Razor.Compiler/Microsoft.NET.Sdk.Razor.SourceGenerators.RazorSourceGenerator/Components_Pages_TestPage_razor.g.cs:0:0:0:0 | BlazorTest/obj/Debug/net9.0/generated/Microsoft.CodeAnalysis.Razor.Compiler/Microsoft.NET.Sdk.Razor.SourceGenerators.RazorSourceGenerator/Components_Pages_TestPage_razor.g.cs |
| BlazorTest/obj/Debug/net9.0/generated/Microsoft.CodeAnalysis.Razor.Compiler/Microsoft.NET.Sdk.Razor.SourceGenerators.RazorSourceGenerator/Components_Routes_razor.g.cs:0:0:0:0 | BlazorTest/obj/Debug/net9.0/generated/Microsoft.CodeAnalysis.Razor.Compiler/Microsoft.NET.Sdk.Razor.SourceGenerators.RazorSourceGenerator/Components_Routes_razor.g.cs |
| BlazorTest/obj/Debug/net9.0/generated/Microsoft.CodeAnalysis.Razor.Compiler/Microsoft.NET.Sdk.Razor.SourceGenerators.RazorSourceGenerator/Components__Imports_razor.g.cs:0:0:0:0 | BlazorTest/obj/Debug/net9.0/generated/Microsoft.CodeAnalysis.Razor.Compiler/Microsoft.NET.Sdk.Razor.SourceGenerators.RazorSourceGenerator/Components__Imports_razor.g.cs |

View File

@@ -0,0 +1,5 @@
import csharp
from File f
where f.fromSource() or f.getExtension() = "razor"
select f

View File

@@ -0,0 +1,8 @@
| BlazorTest/Components/MyOutput.razor:5:53:5:57 | access to property Value |
| BlazorTest/Components/Pages/TestPage.razor:11:48:11:55 | access to property UrlParam |
| BlazorTest/Components/Pages/TestPage.razor:20:60:20:69 | access to property QueryParam |
| BlazorTest/Components/Pages/TestPage.razor:29:53:29:63 | access to property InputValue1 |
| BlazorTest/Components/Pages/TestPage.razor:38:53:38:63 | access to property InputValue2 |
| BlazorTest/Components/Pages/TestPage.razor:47:53:47:68 | access to property Value |
| BlazorTest/Components/Pages/TestPage.razor:56:53:56:63 | access to property InputValue3 |
| BlazorTest/Components/Pages/TestPage.razor:65:53:65:63 | access to property InputValue4 |

View File

@@ -0,0 +1,7 @@
import semmle.code.csharp.security.dataflow.flowsinks.Html
from HtmlSink sink, File f
where
sink.getLocation().getFile() = f and
(f.fromSource() or f.getExtension() = "razor")
select sink

View File

@@ -0,0 +1,2 @@
def test(codeql, csharp):
codeql.database.create(source_root="BlazorTest")

View File

@@ -0,0 +1,9 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
</Project>

View File

@@ -0,0 +1,20 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<base href="/" />
<link rel="stylesheet" href="bootstrap/bootstrap.min.css" />
<link rel="stylesheet" href="app.css" />
<link rel="stylesheet" href="BlazorTest.styles.css" />
<link rel="icon" type="image/png" href="favicon.png" />
<HeadOutlet />
</head>
<body>
<Routes />
<script src="_framework/blazor.web.js"></script>
</body>
</html>

View File

@@ -0,0 +1,23 @@
@inherits LayoutComponentBase
<div class="page">
<div class="sidebar">
<NavMenu />
</div>
<main>
<div class="top-row px-4">
<a href="https://learn.microsoft.com/aspnet/core/" target="_blank">About</a>
</div>
<article class="content px-4">
@Body
</article>
</main>
</div>
<div id="blazor-error-ui">
An unhandled error has occurred.
<a href="" class="reload">Reload</a>
<a class="dismiss">🗙</a>
</div>

View File

@@ -0,0 +1,96 @@
.page {
position: relative;
display: flex;
flex-direction: column;
}
main {
flex: 1;
}
.sidebar {
background-image: linear-gradient(180deg, rgb(5, 39, 103) 0%, #3a0647 70%);
}
.top-row {
background-color: #f7f7f7;
border-bottom: 1px solid #d6d5d5;
justify-content: flex-end;
height: 3.5rem;
display: flex;
align-items: center;
}
.top-row ::deep a, .top-row ::deep .btn-link {
white-space: nowrap;
margin-left: 1.5rem;
text-decoration: none;
}
.top-row ::deep a:hover, .top-row ::deep .btn-link:hover {
text-decoration: underline;
}
.top-row ::deep a:first-child {
overflow: hidden;
text-overflow: ellipsis;
}
@media (max-width: 640.98px) {
.top-row {
justify-content: space-between;
}
.top-row ::deep a, .top-row ::deep .btn-link {
margin-left: 0;
}
}
@media (min-width: 641px) {
.page {
flex-direction: row;
}
.sidebar {
width: 250px;
height: 100vh;
position: sticky;
top: 0;
}
.top-row {
position: sticky;
top: 0;
z-index: 1;
}
.top-row.auth ::deep a:first-child {
flex: 1;
text-align: right;
width: 0;
}
.top-row, article {
padding-left: 2rem !important;
padding-right: 1.5rem !important;
}
}
#blazor-error-ui {
background: lightyellow;
bottom: 0;
box-shadow: 0 -1px 2px rgba(0, 0, 0, 0.2);
display: none;
left: 0;
padding: 0.6rem 1.25rem 0.7rem 1.25rem;
position: fixed;
width: 100%;
z-index: 1000;
}
#blazor-error-ui .dismiss {
cursor: pointer;
position: absolute;
right: 0.75rem;
top: 0.5rem;
}

View File

@@ -0,0 +1,19 @@
<div class="top-row ps-3 navbar navbar-dark">
<div class="container-fluid">
<a class="navbar-brand" href="">BlazorTest</a>
</div>
</div>
<input type="checkbox" title="Navigation menu" class="navbar-toggler" />
<div class="nav-scrollable" onclick="document.querySelector('.navbar-toggler').click()">
<nav class="flex-column">
<div class="nav-item px-3">
<NavLink class="nav-link" href="test">
<span class="bi bi-plus-square-fill-nav-menu" aria-hidden="true"></span> Test
</NavLink>
</div>
</nav>
</div>

View File

@@ -0,0 +1,105 @@
.navbar-toggler {
appearance: none;
cursor: pointer;
width: 3.5rem;
height: 2.5rem;
color: white;
position: absolute;
top: 0.5rem;
right: 1rem;
border: 1px solid rgba(255, 255, 255, 0.1);
background: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'%3e%3cpath stroke='rgba%28255, 255, 255, 0.55%29' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e") no-repeat center/1.75rem rgba(255, 255, 255, 0.1);
}
.navbar-toggler:checked {
background-color: rgba(255, 255, 255, 0.5);
}
.top-row {
height: 3.5rem;
background-color: rgba(0,0,0,0.4);
}
.navbar-brand {
font-size: 1.1rem;
}
.bi {
display: inline-block;
position: relative;
width: 1.25rem;
height: 1.25rem;
margin-right: 0.75rem;
top: -1px;
background-size: cover;
}
.bi-house-door-fill-nav-menu {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='white' class='bi bi-house-door-fill' viewBox='0 0 16 16'%3E%3Cpath d='M6.5 14.5v-3.505c0-.245.25-.495.5-.495h2c.25 0 .5.25.5.5v3.5a.5.5 0 0 0 .5.5h4a.5.5 0 0 0 .5-.5v-7a.5.5 0 0 0-.146-.354L13 5.793V2.5a.5.5 0 0 0-.5-.5h-1a.5.5 0 0 0-.5.5v1.293L8.354 1.146a.5.5 0 0 0-.708 0l-6 6A.5.5 0 0 0 1.5 7.5v7a.5.5 0 0 0 .5.5h4a.5.5 0 0 0 .5-.5Z'/%3E%3C/svg%3E");
}
.bi-plus-square-fill-nav-menu {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='white' class='bi bi-plus-square-fill' viewBox='0 0 16 16'%3E%3Cpath d='M2 0a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V2a2 2 0 0 0-2-2H2zm6.5 4.5v3h3a.5.5 0 0 1 0 1h-3v3a.5.5 0 0 1-1 0v-3h-3a.5.5 0 0 1 0-1h3v-3a.5.5 0 0 1 1 0z'/%3E%3C/svg%3E");
}
.bi-list-nested-nav-menu {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='white' class='bi bi-list-nested' viewBox='0 0 16 16'%3E%3Cpath fill-rule='evenodd' d='M4.5 11.5A.5.5 0 0 1 5 11h10a.5.5 0 0 1 0 1H5a.5.5 0 0 1-.5-.5zm-2-4A.5.5 0 0 1 3 7h10a.5.5 0 0 1 0 1H3a.5.5 0 0 1-.5-.5zm-2-4A.5.5 0 0 1 1 3h10a.5.5 0 0 1 0 1H1a.5.5 0 0 1-.5-.5z'/%3E%3C/svg%3E");
}
.nav-item {
font-size: 0.9rem;
padding-bottom: 0.5rem;
}
.nav-item:first-of-type {
padding-top: 1rem;
}
.nav-item:last-of-type {
padding-bottom: 1rem;
}
.nav-item ::deep .nav-link {
color: #d7d7d7;
background: none;
border: none;
border-radius: 4px;
height: 3rem;
display: flex;
align-items: center;
line-height: 3rem;
width: 100%;
}
.nav-item ::deep a.active {
background-color: rgba(255,255,255,0.37);
color: white;
}
.nav-item ::deep .nav-link:hover {
background-color: rgba(255,255,255,0.1);
color: white;
}
.nav-scrollable {
display: none;
}
.navbar-toggler:checked ~ .nav-scrollable {
display: block;
}
@media (min-width: 641px) {
.navbar-toggler {
display: none;
}
.nav-scrollable {
/* Never collapse the sidebar for wide screens */
display: block;
/* Allow sidebar to scroll for tall menus */
height: calc(100vh - 3.5rem);
overflow-y: auto;
}
}

View File

@@ -0,0 +1,20 @@
@rendermode InteractiveServer
<input @bind="Param1" @bind:event="onchange" @bind:after="Fire">
@code {
[Parameter]
public string? Param1 { get; set; } = "";
[Parameter]
public EventCallback<string?> ValueChanged { get; set; }
[Parameter]
public EventCallback<string?> Param1Changed { get; set; }
private void Fire()
{
ValueChanged.InvokeAsync(Param1);
Param1Changed.InvokeAsync(Param1);
}
}

View File

@@ -0,0 +1,11 @@
@rendermode InteractiveServer
<div>
<p>Value from InputText: @Value</p>
<p>Raw value from InputText: @(new MarkupString(Value))</p>
</div>
@code {
[Parameter]
public string Value { get; set; } = "";
}

View File

@@ -0,0 +1,36 @@
@page "/Error"
@using System.Diagnostics
<PageTitle>Error</PageTitle>
<h1 class="text-danger">Error.</h1>
<h2 class="text-danger">An error occurred while processing your request.</h2>
@if (ShowRequestId)
{
<p>
<strong>Request ID:</strong> <code>@RequestId</code>
</p>
}
<h3>Development Mode</h3>
<p>
Swapping to <strong>Development</strong> environment will display more detailed information about the error that occurred.
</p>
<p>
<strong>The Development environment shouldn't be enabled for deployed applications.</strong>
It can result in displaying sensitive information from exceptions to end users.
For local debugging, enable the <strong>Development</strong> environment by setting the <strong>ASPNETCORE_ENVIRONMENT</strong> environment variable to <strong>Development</strong>
and restarting the app.
</p>
@code{
[CascadingParameter]
private HttpContext? HttpContext { get; set; }
private string? RequestId { get; set; }
private bool ShowRequestId => !string.IsNullOrEmpty(RequestId);
protected override void OnInitialized() =>
RequestId = Activity.Current?.Id ?? HttpContext?.TraceIdentifier;
}

View File

@@ -0,0 +1,125 @@
@page "/"
@page "/test/{urlParam?}"
@rendermode InteractiveServer
<PageTitle>TestPage</PageTitle>
<div>
<h3>Route parameter</h3>
<p>Go to: <a href="/test/@XssUrl">/test/@XssUrl</a></p>
<p>Parameter from URL: @UrlParam</p>
<p>Raw parameter from URL: @((MarkupString)UrlParam)</p>
</div>
<hr />
<div>
<h3>Query parameter</h3>
<p>Go to: <a href="/test/?qs=@XssUrl">/test/?qs=@XssUrl</a></p>
<p>Parameter from query string: @QueryParam</p>
<p>Raw parameter from query string: @(new MarkupString(QueryParam))</p>
</div>
<hr />
<div>
<h3>Bind InputText component</h3>
<InputText @bind-Value="InputValue1" />
<p>Value from InputText: @InputValue1</p>
<p>Raw value from InputText: @(new MarkupString(InputValue1))</p>
</div>
<hr />
<div>
<h3>Bind input element</h3>
<input @bind="InputValue2">
<p>Value from InputText: @InputValue2</p>
<p>Raw value from InputText: @(new MarkupString(InputValue2))</p>
</div>
<hr />
<div>
<h3>Bind through object property</h3>
<input @bind="Container1.Value">
<p>Value from InputText: @Container1.Value</p>
<p>Raw value from InputText: @(new MarkupString(Container1.Value))</p>
</div>
<hr />
<div>
<h3>Input component with custom event</h3>
<MyInput Param1="@InputValue3" ValueChanged="MyInputChanged" />
<p>Value from InputText: @InputValue3</p>
<p>Raw value from InputText: @(new MarkupString(InputValue3))</p>
</div>
<hr />
<div>
<h3>Input component with binding</h3>
<MyInput @bind-Param1="InputValue4" />
<p>Value from InputText: @InputValue4</p>
<p>Raw value from InputText: @(new MarkupString(InputValue4))</p>
</div>
<hr />
<div>
<h3>Input, Output components</h3>
<MyInput @bind-Param1="InputValue5" />
<MyOutput Value="@InputValue5" />
</div>
<hr />
<div>
<h3>Bind InputText, Output component</h3>
<InputText @bind-Value="InputValue6" />
<MyOutput Value="@InputValue6" />
</div>
@code {
public class Container
{
public string? Value { get; set; } = "";
}
private const string XssUrl = "<b>aaaa<%2Fb>";
private const string XssUrl2 = "<b>aaaa</b>";
[Parameter]
public string UrlParam { get; set; } = "";
[SupplyParameterFromQuery(Name = "qs")]
public string QueryParam { get; set; } = "";
public string InputValue1 { get; set; } = "";
public string InputValue2 { get; set; } = "";
public string InputValue3 { get; set; } = "";
public string InputValue4 { get; set; } = "";
public string InputValue5 { get; set; } = "";
public string InputValue6 { get; set; } = "";
public Container Container1 { get; set; } = new Container();
protected override void OnInitialized()
{
InputValue1 = XssUrl2;
InputValue2 = XssUrl2;
Container1.Value = XssUrl2;
InputValue3 = XssUrl2;
InputValue4 = XssUrl2;
InputValue5 = XssUrl2;
InputValue6 = XssUrl2;
}
private void MyInputChanged(string value)
{
InputValue3 = value;
}
}

View File

@@ -0,0 +1,6 @@
<Router AppAssembly="typeof(Program).Assembly">
<Found Context="routeData">
<RouteView RouteData="routeData" DefaultLayout="typeof(Layout.MainLayout)" />
<FocusOnNavigate RouteData="routeData" Selector="h1" />
</Found>
</Router>

View File

@@ -0,0 +1,10 @@
@using System.Net.Http
@using System.Net.Http.Json
@using Microsoft.AspNetCore.Components.Forms
@using Microsoft.AspNetCore.Components.Routing
@using Microsoft.AspNetCore.Components.Web
@using static Microsoft.AspNetCore.Components.Web.RenderMode
@using Microsoft.AspNetCore.Components.Web.Virtualization
@using Microsoft.JSInterop
@using BlazorTest
@using BlazorTest.Components

View File

@@ -0,0 +1,27 @@
using BlazorTest.Components;
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddRazorComponents()
.AddInteractiveServerComponents();
var app = builder.Build();
// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error", createScopeForErrors: true);
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseAntiforgery();
app.MapRazorComponents<App>()
.AddInteractiveServerRenderMode();
app.Run();

View File

@@ -0,0 +1,14 @@
{
"$schema": "http://json.schemastore.org/launchsettings.json",
"profiles": {
"http": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": true,
"applicationUrl": "http://localhost:5047",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
}
}
}

View File

@@ -0,0 +1,9 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"AllowedHosts": "*"
}

View File

@@ -0,0 +1,5 @@
{
"sdk": {
"version": "8.0.401"
}
}

View File

@@ -0,0 +1,51 @@
html, body {
font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
}
a, .btn-link {
color: #006bb7;
}
.btn-primary {
color: #fff;
background-color: #1b6ec2;
border-color: #1861ac;
}
.btn:focus, .btn:active:focus, .btn-link.nav-link:focus, .form-control:focus, .form-check-input:focus {
box-shadow: 0 0 0 0.1rem white, 0 0 0 0.25rem #258cfb;
}
.content {
padding-top: 1.1rem;
}
h1:focus {
outline: none;
}
.valid.modified:not([type=checkbox]) {
outline: 1px solid #26b050;
}
.invalid {
outline: 1px solid #e50000;
}
.validation-message {
color: #e50000;
}
.blazor-error-boundary {
background: url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTYiIGhlaWdodD0iNDkiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIG92ZXJmbG93PSJoaWRkZW4iPjxkZWZzPjxjbGlwUGF0aCBpZD0iY2xpcDAiPjxyZWN0IHg9IjIzNSIgeT0iNTEiIHdpZHRoPSI1NiIgaGVpZ2h0PSI0OSIvPjwvY2xpcFBhdGg+PC9kZWZzPjxnIGNsaXAtcGF0aD0idXJsKCNjbGlwMCkiIHRyYW5zZm9ybT0idHJhbnNsYXRlKC0yMzUgLTUxKSI+PHBhdGggZD0iTTI2My41MDYgNTFDMjY0LjcxNyA1MSAyNjUuODEzIDUxLjQ4MzcgMjY2LjYwNiA1Mi4yNjU4TDI2Ny4wNTIgNTIuNzk4NyAyNjcuNTM5IDUzLjYyODMgMjkwLjE4NSA5Mi4xODMxIDI5MC41NDUgOTIuNzk1IDI5MC42NTYgOTIuOTk2QzI5MC44NzcgOTMuNTEzIDI5MSA5NC4wODE1IDI5MSA5NC42NzgyIDI5MSA5Ny4wNjUxIDI4OS4wMzggOTkgMjg2LjYxNyA5OUwyNDAuMzgzIDk5QzIzNy45NjMgOTkgMjM2IDk3LjA2NTEgMjM2IDk0LjY3ODIgMjM2IDk0LjM3OTkgMjM2LjAzMSA5NC4wODg2IDIzNi4wODkgOTMuODA3MkwyMzYuMzM4IDkzLjAxNjIgMjM2Ljg1OCA5Mi4xMzE0IDI1OS40NzMgNTMuNjI5NCAyNTkuOTYxIDUyLjc5ODUgMjYwLjQwNyA1Mi4yNjU4QzI2MS4yIDUxLjQ4MzcgMjYyLjI5NiA1MSAyNjMuNTA2IDUxWk0yNjMuNTg2IDY2LjAxODNDMjYwLjczNyA2Ni4wMTgzIDI1OS4zMTMgNjcuMTI0NSAyNTkuMzEzIDY5LjMzNyAyNTkuMzEzIDY5LjYxMDIgMjU5LjMzMiA2OS44NjA4IDI1OS4zNzEgNzAuMDg4N0wyNjEuNzk1IDg0LjAxNjEgMjY1LjM4IDg0LjAxNjEgMjY3LjgyMSA2OS43NDc1QzI2Ny44NiA2OS43MzA5IDI2Ny44NzkgNjkuNTg3NyAyNjcuODc5IDY5LjMxNzkgMjY3Ljg3OSA2Ny4xMTgyIDI2Ni40NDggNjYuMDE4MyAyNjMuNTg2IDY2LjAxODNaTTI2My41NzYgODYuMDU0N0MyNjEuMDQ5IDg2LjA1NDcgMjU5Ljc4NiA4Ny4zMDA1IDI1OS43ODYgODkuNzkyMSAyNTkuNzg2IDkyLjI4MzcgMjYxLjA0OSA5My41Mjk1IDI2My41NzYgOTMuNTI5NSAyNjYuMTE2IDkzLjUyOTUgMjY3LjM4NyA5Mi4yODM3IDI2Ny4zODcgODkuNzkyMSAyNjcuMzg3IDg3LjMwMDUgMjY2LjExNiA4Ni4wNTQ3IDI2My41NzYgODYuMDU0N1oiIGZpbGw9IiNGRkU1MDAiIGZpbGwtcnVsZT0iZXZlbm9kZCIvPjwvZz48L3N2Zz4=) no-repeat 1rem/1.8rem, #b32121;
padding: 1rem 1rem 1rem 3.7rem;
color: white;
}
.blazor-error-boundary::after {
content: "An error has occurred."
}
.darker-border-checkbox.form-check-input {
border-color: #929292;
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@@ -0,0 +1,22 @@
| BlazorTest/Components/App.razor:0:0:0:0 | BlazorTest/Components/App.razor |
| BlazorTest/Components/Layout/MainLayout.razor:0:0:0:0 | BlazorTest/Components/Layout/MainLayout.razor |
| BlazorTest/Components/Layout/NavMenu.razor:0:0:0:0 | BlazorTest/Components/Layout/NavMenu.razor |
| BlazorTest/Components/MyInput.razor:0:0:0:0 | BlazorTest/Components/MyInput.razor |
| BlazorTest/Components/MyOutput.razor:0:0:0:0 | BlazorTest/Components/MyOutput.razor |
| BlazorTest/Components/Pages/Error.razor:0:0:0:0 | BlazorTest/Components/Pages/Error.razor |
| BlazorTest/Components/Pages/TestPage.razor:0:0:0:0 | BlazorTest/Components/Pages/TestPage.razor |
| BlazorTest/Components/Routes.razor:0:0:0:0 | BlazorTest/Components/Routes.razor |
| BlazorTest/Components/_Imports.razor:0:0:0:0 | BlazorTest/Components/_Imports.razor |
| BlazorTest/Program.cs:0:0:0:0 | BlazorTest/Program.cs |
| BlazorTest/obj/Debug/net8.0/.NETCoreApp,Version=v8.0.AssemblyAttributes.cs:0:0:0:0 | BlazorTest/obj/Debug/net8.0/.NETCoreApp,Version=v8.0.AssemblyAttributes.cs |
| BlazorTest/obj/Debug/net8.0/BlazorTest.AssemblyInfo.cs:0:0:0:0 | BlazorTest/obj/Debug/net8.0/BlazorTest.AssemblyInfo.cs |
| BlazorTest/obj/Debug/net8.0/BlazorTest.GlobalUsings.g.cs:0:0:0:0 | BlazorTest/obj/Debug/net8.0/BlazorTest.GlobalUsings.g.cs |
| BlazorTest/obj/Debug/net8.0/generated/Microsoft.CodeAnalysis.Razor.Compiler/Microsoft.NET.Sdk.Razor.SourceGenerators.RazorSourceGenerator/Components_App_razor.g.cs:0:0:0:0 | BlazorTest/obj/Debug/net8.0/generated/Microsoft.CodeAnalysis.Razor.Compiler/Microsoft.NET.Sdk.Razor.SourceGenerators.RazorSourceGenerator/Components_App_razor.g.cs |
| BlazorTest/obj/Debug/net8.0/generated/Microsoft.CodeAnalysis.Razor.Compiler/Microsoft.NET.Sdk.Razor.SourceGenerators.RazorSourceGenerator/Components_Layout_MainLayout_razor.g.cs:0:0:0:0 | BlazorTest/obj/Debug/net8.0/generated/Microsoft.CodeAnalysis.Razor.Compiler/Microsoft.NET.Sdk.Razor.SourceGenerators.RazorSourceGenerator/Components_Layout_MainLayout_razor.g.cs |
| BlazorTest/obj/Debug/net8.0/generated/Microsoft.CodeAnalysis.Razor.Compiler/Microsoft.NET.Sdk.Razor.SourceGenerators.RazorSourceGenerator/Components_Layout_NavMenu_razor.g.cs:0:0:0:0 | BlazorTest/obj/Debug/net8.0/generated/Microsoft.CodeAnalysis.Razor.Compiler/Microsoft.NET.Sdk.Razor.SourceGenerators.RazorSourceGenerator/Components_Layout_NavMenu_razor.g.cs |
| BlazorTest/obj/Debug/net8.0/generated/Microsoft.CodeAnalysis.Razor.Compiler/Microsoft.NET.Sdk.Razor.SourceGenerators.RazorSourceGenerator/Components_MyInput_razor.g.cs:0:0:0:0 | BlazorTest/obj/Debug/net8.0/generated/Microsoft.CodeAnalysis.Razor.Compiler/Microsoft.NET.Sdk.Razor.SourceGenerators.RazorSourceGenerator/Components_MyInput_razor.g.cs |
| BlazorTest/obj/Debug/net8.0/generated/Microsoft.CodeAnalysis.Razor.Compiler/Microsoft.NET.Sdk.Razor.SourceGenerators.RazorSourceGenerator/Components_MyOutput_razor.g.cs:0:0:0:0 | BlazorTest/obj/Debug/net8.0/generated/Microsoft.CodeAnalysis.Razor.Compiler/Microsoft.NET.Sdk.Razor.SourceGenerators.RazorSourceGenerator/Components_MyOutput_razor.g.cs |
| BlazorTest/obj/Debug/net8.0/generated/Microsoft.CodeAnalysis.Razor.Compiler/Microsoft.NET.Sdk.Razor.SourceGenerators.RazorSourceGenerator/Components_Pages_Error_razor.g.cs:0:0:0:0 | BlazorTest/obj/Debug/net8.0/generated/Microsoft.CodeAnalysis.Razor.Compiler/Microsoft.NET.Sdk.Razor.SourceGenerators.RazorSourceGenerator/Components_Pages_Error_razor.g.cs |
| BlazorTest/obj/Debug/net8.0/generated/Microsoft.CodeAnalysis.Razor.Compiler/Microsoft.NET.Sdk.Razor.SourceGenerators.RazorSourceGenerator/Components_Pages_TestPage_razor.g.cs:0:0:0:0 | BlazorTest/obj/Debug/net8.0/generated/Microsoft.CodeAnalysis.Razor.Compiler/Microsoft.NET.Sdk.Razor.SourceGenerators.RazorSourceGenerator/Components_Pages_TestPage_razor.g.cs |
| BlazorTest/obj/Debug/net8.0/generated/Microsoft.CodeAnalysis.Razor.Compiler/Microsoft.NET.Sdk.Razor.SourceGenerators.RazorSourceGenerator/Components_Routes_razor.g.cs:0:0:0:0 | BlazorTest/obj/Debug/net8.0/generated/Microsoft.CodeAnalysis.Razor.Compiler/Microsoft.NET.Sdk.Razor.SourceGenerators.RazorSourceGenerator/Components_Routes_razor.g.cs |
| BlazorTest/obj/Debug/net8.0/generated/Microsoft.CodeAnalysis.Razor.Compiler/Microsoft.NET.Sdk.Razor.SourceGenerators.RazorSourceGenerator/Components__Imports_razor.g.cs:0:0:0:0 | BlazorTest/obj/Debug/net8.0/generated/Microsoft.CodeAnalysis.Razor.Compiler/Microsoft.NET.Sdk.Razor.SourceGenerators.RazorSourceGenerator/Components__Imports_razor.g.cs |

View File

@@ -0,0 +1,5 @@
import csharp
from File f
where f.fromSource() or f.getExtension() = "razor"
select f

View File

@@ -0,0 +1,8 @@
| BlazorTest/Components/MyOutput.razor:5:53:5:57 | access to property Value |
| BlazorTest/Components/Pages/TestPage.razor:11:48:11:55 | access to property UrlParam |
| BlazorTest/Components/Pages/TestPage.razor:20:60:20:69 | access to property QueryParam |
| BlazorTest/Components/Pages/TestPage.razor:29:53:29:63 | access to property InputValue1 |
| BlazorTest/Components/Pages/TestPage.razor:38:53:38:63 | access to property InputValue2 |
| BlazorTest/Components/Pages/TestPage.razor:47:53:47:68 | access to property Value |
| BlazorTest/Components/Pages/TestPage.razor:56:53:56:63 | access to property InputValue3 |
| BlazorTest/Components/Pages/TestPage.razor:65:53:65:63 | access to property InputValue4 |

View File

@@ -0,0 +1,7 @@
import semmle.code.csharp.security.dataflow.flowsinks.Html
from HtmlSink sink, File f
where
sink.getLocation().getFile() = f and
(f.fromSource() or f.getExtension() = "razor")
select sink

View File

@@ -0,0 +1,2 @@
def test(codeql, csharp):
codeql.database.create(source_root="BlazorTest")

View File

@@ -33,7 +33,7 @@
.. [2] Objective-C, Objective-C++, C++/CLI, and C++/CX are not supported.
.. [3] Support for the clang-cl compiler is preliminary.
.. [4] Support for the Arm Compiler (armcc) is preliminary.
.. [5] Builds that execute on Java 7 to 22 can be analyzed. The analysis understands Java 22 standard language features.
.. [5] Builds that execute on Java 7 to 22 can be analyzed. The analysis understands standard language features in Java 8 to 22; "preview" and "incubator" features are not supported. Source code using Java language versions older than Java 8 are analyzed as Java 8 code.
.. [6] ECJ is supported when the build invokes it via the Maven Compiler plugin or the Takari Lifecycle plugin.
.. [7] JSX and Flow code, YAML, JSON, HTML, and XML files may also be analyzed with JavaScript files.
.. [8] The extractor requires Python 3 to run. To analyze Python 2.7 you should install both versions of Python.

View File

@@ -10,7 +10,7 @@ toolchain go1.23.1
// bazel mod tidy
require (
golang.org/x/mod v0.22.0
golang.org/x/tools v0.28.0
golang.org/x/tools v0.29.0
)
require golang.org/x/sync v0.10.0 // indirect

View File

@@ -4,5 +4,5 @@ golang.org/x/mod v0.22.0 h1:D4nJWe9zXqHOmWqj4VMOJhvzj7bEZg4wEYa759z1pH4=
golang.org/x/mod v0.22.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY=
golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ=
golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/tools v0.28.0 h1:WuB6qZ4RPCQo5aP3WdKZS7i595EdWqWR8vqJTlwTVK8=
golang.org/x/tools v0.28.0/go.mod h1:dcIOrVd3mfQKTgrDVQHqCPMWy6lnhfhtX3hLXYVLfRw=
golang.org/x/tools v0.29.0 h1:Xx0h3TtM9rzQpQuR4dKLrdglAmCEN5Oi+P74JdhdzXE=
golang.org/x/tools v0.29.0/go.mod h1:KMQVMRsVxU6nHCFXrBPhDB8XncLNLM0lIy/F14RP588=

View File

@@ -0,0 +1,4 @@
---
category: minorAnalysis
---
* `database` local source models have been added for the `database/sql` and `database/sql/driver` packages.

View File

@@ -0,0 +1,5 @@
---
category: minorAnalysis
---
* Added `database` source models for database methods from the `gorm.io/gorm` package.
`

View File

@@ -1,4 +1,12 @@
extensions:
- addsTo:
pack: codeql/go-all
extensible: sourceModel
data:
- ["database/sql/driver", "Queryer", True, "Query", "", "", "ReturnValue[0]", "database", "manual"]
- ["database/sql/driver", "QueryerContext", True, "QueryContext", "", "", "ReturnValue[0]", "database", "manual"]
- ["database/sql/driver", "Stmt", True, "Query", "", "", "ReturnValue[0]", "database", "manual"]
- ["database/sql/driver", "StmtQueryContext", True, "QueryContext", "", "", "ReturnValue[0]", "database", "manual"]
- addsTo:
pack: codeql/go-all
extensible: sinkModel
@@ -15,5 +23,6 @@ extensions:
data:
- ["database/sql/driver", "Conn", True, "Prepare", "", "", "Argument[0]", "ReturnValue[0]", "taint", "manual"]
- ["database/sql/driver", "ConnPrepareContext", True, "PrepareContext", "", "", "Argument[1]", "ReturnValue[0]", "taint", "manual"]
- ["database/sql/driver", "Rows", True, "Next", "", "", "Argument[receiver]", "Argument[0]", "taint", "manual"]
- ["database/sql/driver", "ValueConverter", True, "ConvertValue", "", "", "Argument[0]", "ReturnValue[0]", "taint", "manual"]
- ["database/sql/driver", "Valuer", True, "Value", "", "", "Argument[receiver]", "ReturnValue[0]", "taint", "manual"]

View File

@@ -1,4 +1,22 @@
extensions:
- addsTo:
pack: codeql/go-all
extensible: sourceModel
data:
- ["database/sql", "Conn", True, "QueryContext", "", "", "ReturnValue[0]", "database", "manual"]
- ["database/sql", "Conn", True, "QueryRowContext", "", "", "ReturnValue", "database", "manual"]
- ["database/sql", "DB", True, "Query", "", "", "ReturnValue[0]", "database", "manual"]
- ["database/sql", "DB", True, "QueryContext", "", "", "ReturnValue[0]", "database", "manual"]
- ["database/sql", "DB", True, "QueryRow", "", "", "ReturnValue", "database", "manual"]
- ["database/sql", "DB", True, "QueryRowContext", "", "", "ReturnValue", "database", "manual"]
- ["database/sql", "Stmt", True, "Query", "", "", "ReturnValue[0]", "database", "manual"]
- ["database/sql", "Stmt", True, "QueryContext", "", "", "ReturnValue[0]", "database", "manual"]
- ["database/sql", "Stmt", True, "QueryRow", "", "", "ReturnValue", "database", "manual"]
- ["database/sql", "Stmt", True, "QueryRowContext", "", "", "ReturnValue", "database", "manual"]
- ["database/sql", "Tx", True, "Query", "", "", "ReturnValue[0]", "database", "manual"]
- ["database/sql", "Tx", True, "QueryContext", "", "", "ReturnValue[0]", "database", "manual"]
- ["database/sql", "Tx", True, "QueryRow", "", "", "ReturnValue", "database", "manual"]
- ["database/sql", "Tx", True, "QueryRowContext", "", "", "ReturnValue", "database", "manual"]
- addsTo:
pack: codeql/go-all
extensible: sinkModel
@@ -35,6 +53,8 @@ extensions:
- ["database/sql", "Conn", True, "PrepareContext", "", "", "Argument[1]", "ReturnValue[0]", "taint", "manual"]
- ["database/sql", "DB", True, "Prepare", "", "", "Argument[0]", "ReturnValue[0]", "taint", "manual"]
- ["database/sql", "DB", True, "PrepareContext", "", "", "Argument[1]", "ReturnValue[0]", "taint", "manual"]
- ["database/sql", "Row", True, "Scan", "", "", "Argument[receiver]", "Argument[0].ArrayElement", "taint", "manual"]
- ["database/sql", "Rows", True, "Scan", "", "", "Argument[receiver]", "Argument[0].ArrayElement", "taint", "manual"]
- ["database/sql", "Scanner", True, "Scan", "", "", "Argument[0]", "Argument[receiver]", "taint", "manual"]
- ["database/sql", "Tx", True, "Prepare", "", "", "Argument[0]", "ReturnValue[0]", "taint", "manual"]
- ["database/sql", "Tx", True, "PrepareContext", "", "", "Argument[1]", "ReturnValue[0]", "taint", "manual"]

View File

@@ -6,6 +6,25 @@ extensions:
- ["gorm", "gorm.io/gorm"]
- ["gorm", "github.com/jinzhu/gorm"]
- ["gorm", "github.com/go-gorm/gorm"]
- addsTo:
pack: codeql/go-all
extensible: sourceModel
data:
- ["group:gorm", "Association", True, "Find", "", "", "Argument[0]", "database", "manual"]
- ["group:gorm", "ConnPool", True, "QueryContext", "", "", "ReturnValue[0]", "database", "manual"]
- ["group:gorm", "ConnPool", True, "QueryRowContext", "", "", "ReturnValue", "database", "manual"]
- ["group:gorm", "DB", True, "Find", "", "", "Argument[0]", "database", "manual"]
- ["group:gorm", "DB", True, "FindInBatches", "", "", "Argument[0]", "database", "manual"]
- ["group:gorm", "DB", True, "First", "", "", "Argument[0]", "database", "manual"]
- ["group:gorm", "DB", True, "FirstOrCreate", "", "", "Argument[0]", "database", "manual"]
- ["group:gorm", "DB", True, "FirstOrInit", "", "", "Argument[0]", "database", "manual"]
- ["group:gorm", "DB", True, "Last", "", "", "Argument[0]", "database", "manual"]
- ["group:gorm", "DB", True, "Model", "", "", "Argument[0]", "database", "manual"]
- ["group:gorm", "DB", True, "Pluck", "", "", "Argument[1]", "database", "manual"]
- ["group:gorm", "DB", True, "Row", "", "", "ReturnValue", "database", "manual"]
- ["group:gorm", "DB", True, "Rows", "", "", "ReturnValue[0]", "database", "manual"]
- ["group:gorm", "DB", True, "Scan", "", "", "Argument[0]", "database", "manual"]
- ["group:gorm", "DB", True, "Take", "", "", "Argument[0]", "database", "manual"]
- addsTo:
pack: codeql/go-all
extensible: sinkModel
@@ -23,3 +42,8 @@ extensions:
- ["group:gorm", "DB", True, "Exec", "", "", "Argument[0]", "sql-injection", "manual"]
- ["group:gorm", "DB", True, "Distinct", "", "", "Argument[0]", "sql-injection", "manual"]
- ["group:gorm", "DB", True, "Pluck", "", "", "Argument[0]", "sql-injection", "manual"]
- addsTo:
pack: codeql/go-all
extensible: summaryModel
data:
- ["group:gorm", "DB", True, "ScanRows", "", "", "Argument[0]", "Argument[1]", "taint", "manual"]

View File

@@ -66,24 +66,4 @@ module DatabaseSql {
result = this.getReceiver().getAPredecessor*().(DataFlow::MethodCallNode).getAnArgument()
}
}
// These are expressed using TaintTracking::FunctionModel because varargs functions don't work with Models-as-Data sumamries yet.
private class SqlMethodModels extends TaintTracking::FunctionModel, Method {
FunctionInput inp;
FunctionOutput outp;
SqlMethodModels() {
// signature: func (*Row) Scan(dest ...interface{}) error
this.hasQualifiedName("database/sql", "Row", "Scan") and
(inp.isReceiver() and outp.isParameter(_))
or
// signature: func (*Rows) Scan(dest ...interface{}) error
this.hasQualifiedName("database/sql", "Rows", "Scan") and
(inp.isReceiver() and outp.isParameter(_))
}
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
input = inp and output = outp
}
}
}

View File

@@ -0,0 +1,7 @@
module test
go 1.22.5
require (
gorm.io/gorm v1.23.0
)

View File

@@ -0,0 +1,5 @@
package test
func sink(x ...any) {}
func ignore(...any) {}

View File

@@ -0,0 +1,2 @@
testFailures
invalidModelRow

View File

@@ -0,0 +1,6 @@
extensions:
- addsTo:
pack: codeql/threat-models
extensible: threatModelConfiguration
data:
- ["database", true, 0]

View File

@@ -0,0 +1,19 @@
import go
import ModelValidation
import utils.test.InlineExpectationsTest
module SourceTest implements TestSig {
string getARelevantTag() { result = "source" }
predicate hasActualResult(Location location, string element, string tag, string value) {
exists(ActiveThreatModelSource s |
s.hasLocationInfo(location.getFile().getAbsolutePath(), location.getStartLine(),
location.getStartColumn(), location.getEndLine(), location.getEndColumn()) and
element = s.toString() and
value = "" and
tag = "source"
)
}
}
import MakeTest<SourceTest>

View File

@@ -0,0 +1,2 @@
testFailures
invalidModelRow

View File

@@ -0,0 +1,7 @@
extensions:
- addsTo:
pack: codeql/threat-models
extensible: threatModelConfiguration
data:
- ["database", true, 0]

View File

@@ -0,0 +1,15 @@
import go
import semmle.go.dataflow.ExternalFlow
import ModelValidation
import experimental.frameworks.CleverGo
import utils.test.InlineFlowTest
module Config implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node source) { source instanceof ActiveThreatModelSource }
predicate isSink(DataFlow::Node sink) {
sink.asExpr() = any(CallExpr c | c.getTarget().getName() = "sink").getAnArgument()
}
}
import TaintFlowTest<Config>

View File

@@ -0,0 +1,157 @@
package test
import (
"database/sql"
)
// test querying a Conn
func testConnQuery(conn *sql.Conn) {
rows, err := conn.QueryContext(nil, "SELECT * FROM users") // $ source
if err != nil {
return
}
defer rows.Close()
for rows.Next() {
var id int
var name string
err = rows.Scan(&id, &name)
if err != nil {
return
}
sink(id, name) // $ hasTaintFlow="id" hasTaintFlow="name"
}
row := conn.QueryRowContext(nil, "SELECT * FROM users WHERE id = 1") // $ source
var id int
var name string
err = row.Scan(&id, &name)
sink(id, name) // $ hasTaintFlow="id" hasTaintFlow="name"
}
// test querying a DB
func testDBQuery(db *sql.DB) {
example, err := db.Query("SELECT * FROM users") // $ source
ignore(example)
rows, err := db.QueryContext(nil, "SELECT * FROM users") // $ source
if err != nil {
return
}
defer rows.Close()
for rows.Next() {
var id int
var name string
err = rows.Scan(&id, &name)
if err != nil {
return
}
sink(id, name) // $ hasTaintFlow="id" hasTaintFlow="name"
}
row := db.QueryRowContext(nil, "SELECT * FROM users WHERE id = 1") // $ source
var id int
var name string
err = row.Scan(&id, &name)
sink(id, name) // $ hasTaintFlow="id" hasTaintFlow="name"
dog := db.QueryRow("SELECT * FROM dogs WHERE id = 1") // $ source
ignore(dog)
}
// test querying a Stmt
func testStmtQuery(stmt *sql.Stmt) {
example, err := stmt.Query("SELECT * FROM users") // $ source
ignore(example)
rows, err := stmt.QueryContext(nil, "SELECT * FROM users") // $ source
if err != nil {
return
}
defer rows.Close()
for rows.Next() {
var id int
var name string
err = rows.Scan(&id, &name)
if err != nil {
return
}
sink(id, name) // $ hasTaintFlow="id" hasTaintFlow="name"
}
row := stmt.QueryRowContext(nil, "SELECT * FROM users WHERE id = 1") // $ source
var id int
var name string
err = row.Scan(&id, &name)
if err != nil {
return
}
sink(id, name) // $ hasTaintFlow="id" hasTaintFlow="name"
dog := stmt.QueryRow("SELECT * FROM dogs WHERE id = 1") // $ source
ignore(dog)
}
// test querying a Tx
func testTxQuery(tx *sql.Tx) {
example, err := tx.Query("SELECT * FROM users") // $ source
ignore(example)
rows, err := tx.QueryContext(nil, "SELECT * FROM users") // $ source
if err != nil {
return
}
defer rows.Close()
for rows.Next() {
var id int
var name string
err = rows.Scan(&id, &name)
if err != nil {
return
}
sink(id, name) // $ hasTaintFlow="id" hasTaintFlow="name"
}
row := tx.QueryRowContext(nil, "SELECT * FROM users WHERE id = 1") // $ source
var id int
var name string
err = row.Scan(&id, &name)
if err != nil {
return
}
sink(id, name) // $ hasTaintFlow="id" hasTaintFlow="name"
dog := tx.QueryRow("SELECT * FROM dogs WHERE id = 1") // $ source
ignore(dog)
}

View File

@@ -0,0 +1,23 @@
package test
import "database/sql/driver"
func testQueryer(q driver.Queryer) {
rows, err := q.Query("SELECT * FROM users", make([]driver.Value, 0)) // $ source
ignore(rows, err)
}
func testQueryerContext(q driver.QueryerContext) {
rows, err := q.QueryContext(nil, "SELECT * FROM users", make([]driver.NamedValue, 0)) // $ source
ignore(rows, err)
}
func testStmt(stmt driver.Stmt) {
rows, err := stmt.Query(make([]driver.Value, 0)) // $ source
ignore(rows, err)
}
func testStmtContext(stmt driver.StmtQueryContext) {
rows, err := stmt.QueryContext(nil, make([]driver.NamedValue, 0)) // $ source
ignore(rows, err)
}

View File

@@ -0,0 +1,59 @@
package test
import "gorm.io/gorm"
// test querying an Association
func test_gorm_AssociationQuery(association *gorm.Association) {
association.Find(&User{}) // $ source
}
// test querying a ConnPool
func test_gorm_ConnPoolQuery(connPool gorm.ConnPool) {
rows, err := connPool.QueryContext(nil, "SELECT * FROM users") // $ source
if err != nil {
return
}
defer rows.Close()
userRow := connPool.QueryRowContext(nil, "SELECT * FROM users WHERE id = 1") // $ source
ignore(userRow)
}
// test querying a DB
func test_gorm_db(db *gorm.DB) {
db.Find(&User{}) // $ source
db.FindInBatches(&User{}, 10, nil) // $ source
db.FirstOrCreate(&User{}) // $ source
db.FirstOrInit(&User{}) // $ source
db.First(&User{}) // $ source
db.Last(&User{}) // $ source
db.Take(&User{}) // $ source
db.Scan(&User{}) // $ source
var user User
db.Model(&user) // $ source
row := db.Row() // $ source
ignore(row)
rows, err := db.Rows() // $ source
ignore(err)
var user2 User
db.ScanRows(rows, &user2)
sink(user2) // $ hasTaintFlow="user2"
var names []string
db.Pluck("name", &names) // $ source
}

View File

@@ -0,0 +1,3 @@
package test
type User struct{}

View File

@@ -0,0 +1,77 @@
package gorm
import (
"context"
"database/sql"
)
type DB struct{}
func (db *DB) Find(dest interface{}, conds ...interface{}) *DB {
return db
}
func (db *DB) FindInBatches(dest interface{}, batchSize int, fc func(tx *DB, batch int) error) *DB {
return db
}
func (db *DB) FirstOrCreate(dest interface{}, conds ...interface{}) *DB {
return db
}
func (db *DB) FirstOrInit(dest interface{}, conds ...interface{}) *DB {
return db
}
func (db *DB) First(dest interface{}, conds ...interface{}) *DB {
return db
}
func (db *DB) Model(value interface{}) *DB {
return db
}
func (db *DB) Last(dest interface{}, conds ...interface{}) *DB {
return db
}
func (db *DB) Pluck(column string, dest interface{}) *DB {
return db
}
func (db *DB) Take(dest interface{}, conds ...interface{}) *DB {
return db
}
func (db *DB) Scan(dest interface{}) *DB {
return db
}
func (db *DB) ScanRows(rows *sql.Rows, result interface{}) error {
return nil
}
func (db *DB) Row() *sql.Row {
return nil
}
func (db *DB) Rows() (*sql.Rows, error) {
return nil, nil
}
type Association struct {
DB *DB
}
func (a *Association) Find(dest interface{}) *Association {
return a
}
type ConnPool interface {
PrepareContext(ctx context.Context, query string) (*sql.Stmt, error)
ExecContext(ctx context.Context, query string, args ...interface{}) (sql.Result, error)
QueryContext(ctx context.Context, query string, args ...interface{}) (*sql.Rows, error)
QueryRowContext(ctx context.Context, query string, args ...interface{}) *sql.Row
}
type Model interface{}

View File

@@ -0,0 +1,3 @@
# gorm.io/gorm v1.23.0
## explicit
gorm.io/gorm

View File

@@ -1,16 +1,22 @@
#select
| StoredCommand.go:14:22:14:28 | cmdName | StoredCommand.go:11:2:11:27 | ... := ...[0] | StoredCommand.go:14:22:14:28 | cmdName | This command depends on a $@. | StoredCommand.go:11:2:11:27 | ... := ...[0] | stored value |
edges
| StoredCommand.go:11:2:11:27 | ... := ...[0] | StoredCommand.go:13:2:13:5 | rows | provenance | |
| StoredCommand.go:13:2:13:5 | rows | StoredCommand.go:13:12:13:19 | &... | provenance | FunctionModel |
| StoredCommand.go:11:2:11:27 | ... := ...[0] | StoredCommand.go:13:2:13:5 | rows | provenance | Src:MaD:2 |
| StoredCommand.go:13:2:13:5 | rows | StoredCommand.go:13:2:13:20 | []type{args} | provenance | MaD:3 |
| StoredCommand.go:13:2:13:5 | rows | StoredCommand.go:13:2:13:20 | []type{args} [array] | provenance | MaD:3 |
| StoredCommand.go:13:2:13:20 | []type{args} | StoredCommand.go:13:12:13:19 | &... | provenance | |
| StoredCommand.go:13:2:13:20 | []type{args} | StoredCommand.go:14:22:14:28 | cmdName | provenance | Sink:MaD:1 |
| StoredCommand.go:13:2:13:20 | []type{args} [array] | StoredCommand.go:13:12:13:19 | &... | provenance | |
| StoredCommand.go:13:12:13:19 | &... | StoredCommand.go:13:2:13:20 | []type{args} [array] | provenance | |
| StoredCommand.go:13:12:13:19 | &... | StoredCommand.go:14:22:14:28 | cmdName | provenance | Sink:MaD:1 |
models
| 1 | Sink: os/exec; ; false; Command; ; ; Argument[0]; command-injection; manual |
| 2 | Source: database/sql; DB; true; Query; ; ; ReturnValue[0]; database; manual |
| 3 | Summary: database/sql; Rows; true; Scan; ; ; Argument[receiver]; Argument[0].ArrayElement; taint; manual |
nodes
| StoredCommand.go:11:2:11:27 | ... := ...[0] | semmle.label | ... := ...[0] |
| StoredCommand.go:13:2:13:5 | rows | semmle.label | rows |
| StoredCommand.go:13:2:13:20 | []type{args} | semmle.label | []type{args} |
| StoredCommand.go:13:2:13:20 | []type{args} [array] | semmle.label | []type{args} [array] |
| StoredCommand.go:13:12:13:19 | &... | semmle.label | &... |
| StoredCommand.go:14:22:14:28 | cmdName | semmle.label | cmdName |

View File

@@ -1,19 +1,30 @@
#select
| StoredXss.go:13:21:13:36 | ...+... | StoredXss.go:13:21:13:31 | call to Name | StoredXss.go:13:21:13:36 | ...+... | Stored cross-site scripting vulnerability due to $@. | StoredXss.go:13:21:13:31 | call to Name | stored value |
| stored.go:30:22:30:25 | name | stored.go:18:3:18:28 | ... := ...[0] | stored.go:30:22:30:25 | name | Stored cross-site scripting vulnerability due to $@. | stored.go:18:3:18:28 | ... := ...[0] | stored value |
| stored.go:61:22:61:25 | path | stored.go:59:30:59:33 | definition of path | stored.go:61:22:61:25 | path | Stored cross-site scripting vulnerability due to $@. | stored.go:59:30:59:33 | definition of path | stored value |
edges
| StoredXss.go:13:21:13:31 | call to Name | StoredXss.go:13:21:13:36 | ...+... | provenance | |
| stored.go:18:3:18:28 | ... := ...[0] | stored.go:25:14:25:17 | rows | provenance | |
| stored.go:25:14:25:17 | rows | stored.go:25:24:25:26 | &... | provenance | FunctionModel |
| stored.go:25:14:25:17 | rows | stored.go:25:29:25:33 | &... | provenance | FunctionModel |
| stored.go:18:3:18:28 | ... := ...[0] | stored.go:25:14:25:17 | rows | provenance | Src:MaD:1 |
| stored.go:25:14:25:17 | rows | stored.go:25:14:25:34 | []type{args} | provenance | MaD:2 |
| stored.go:25:14:25:17 | rows | stored.go:25:14:25:34 | []type{args} [array] | provenance | MaD:2 |
| stored.go:25:14:25:34 | []type{args} | stored.go:25:24:25:26 | &... | provenance | |
| stored.go:25:14:25:34 | []type{args} | stored.go:25:29:25:33 | &... | provenance | |
| stored.go:25:14:25:34 | []type{args} | stored.go:30:22:30:25 | name | provenance | |
| stored.go:25:14:25:34 | []type{args} [array] | stored.go:25:24:25:26 | &... | provenance | |
| stored.go:25:14:25:34 | []type{args} [array] | stored.go:25:29:25:33 | &... | provenance | |
| stored.go:25:24:25:26 | &... | stored.go:25:14:25:34 | []type{args} [array] | provenance | |
| stored.go:25:29:25:33 | &... | stored.go:25:14:25:34 | []type{args} [array] | provenance | |
| stored.go:25:29:25:33 | &... | stored.go:30:22:30:25 | name | provenance | |
| stored.go:59:30:59:33 | definition of path | stored.go:61:22:61:25 | path | provenance | |
models
| 1 | Source: database/sql; DB; true; Query; ; ; ReturnValue[0]; database; manual |
| 2 | Summary: database/sql; Rows; true; Scan; ; ; Argument[receiver]; Argument[0].ArrayElement; taint; manual |
nodes
| StoredXss.go:13:21:13:31 | call to Name | semmle.label | call to Name |
| StoredXss.go:13:21:13:36 | ...+... | semmle.label | ...+... |
| stored.go:18:3:18:28 | ... := ...[0] | semmle.label | ... := ...[0] |
| stored.go:25:14:25:17 | rows | semmle.label | rows |
| stored.go:25:14:25:34 | []type{args} | semmle.label | []type{args} |
| stored.go:25:14:25:34 | []type{args} [array] | semmle.label | []type{args} [array] |
| stored.go:25:24:25:26 | &... | semmle.label | &... |
| stored.go:25:29:25:33 | &... | semmle.label | &... |
@@ -21,7 +32,3 @@ nodes
| stored.go:59:30:59:33 | definition of path | semmle.label | definition of path |
| stored.go:61:22:61:25 | path | semmle.label | path |
subpaths
#select
| StoredXss.go:13:21:13:36 | ...+... | StoredXss.go:13:21:13:31 | call to Name | StoredXss.go:13:21:13:36 | ...+... | Stored cross-site scripting vulnerability due to $@. | StoredXss.go:13:21:13:31 | call to Name | stored value |
| stored.go:30:22:30:25 | name | stored.go:18:3:18:28 | ... := ...[0] | stored.go:30:22:30:25 | name | Stored cross-site scripting vulnerability due to $@. | stored.go:18:3:18:28 | ... := ...[0] | stored value |
| stored.go:61:22:61:25 | path | stored.go:59:30:59:33 | definition of path | stored.go:61:22:61:25 | path | Stored cross-site scripting vulnerability due to $@. | stored.go:59:30:59:33 | definition of path | stored value |

View File

@@ -24,6 +24,16 @@ where
c.hasNoParameters() and
not c.isPrivate()
) and
// Assume if an object replaces itself prior to serialization,
// then it is unlikely to be directly deserialized.
// That means it won't need to comply with default serialization rules,
// such as non-serializable super-classes having a no-argument constructor.
not exists(Method m |
m = serial.getAMethod() and
m.hasName("writeReplace") and
m.getReturnType() instanceof TypeObject and
m.hasNoParameters()
) and
serial.fromSource()
select serial,
"This class is serializable, but its non-serializable " +

View File

@@ -0,0 +1,4 @@
---
category: fix
---
* Classes that define a `writeReplace` method are no longer flagged by the `java/missing-no-arg-constructor-on-serializable` query on the assumption they are unlikely to be deserialized using the default algorithm.

View File

@@ -0,0 +1 @@
| Test.java:12:7:12:7 | A | This class is serializable, but its non-serializable super-class $@ does not declare a no-argument constructor. | Test.java:4:7:4:21 | NonSerializable | NonSerializable |

View File

@@ -0,0 +1 @@
Likely Bugs/Serialization/MissingVoidConstructorsOnSerializable.ql

View File

@@ -0,0 +1,24 @@
import java.io.ObjectStreamException;
import java.io.Serializable;
class NonSerializable {
// Has no default constructor
public NonSerializable(int x) { }
}
// BAD: Serializable but its parent cannot be instantiated
class A extends NonSerializable implements Serializable {
public A() { super(1); }
}
// GOOD: writeReplaces itself, so unlikely to be deserialized
// according to default rules.
class B extends NonSerializable implements Serializable {
public B() { super(2); }
public Object writeReplace() throws ObjectStreamException {
return null;
}
}

View File

@@ -83,6 +83,6 @@ rust_library(
}),
version = "0.6.0",
deps = [
"@vendor__bytemuck-1.20.0//:bytemuck",
"@vendor__bytemuck-1.21.0//:bytemuck",
],
)

View File

@@ -51,7 +51,7 @@ alias(
alias(
name = "clap",
actual = "@vendor__clap-4.5.23//:clap",
actual = "@vendor__clap-4.5.24//:clap",
tags = ["manual"],
)
@@ -87,7 +87,7 @@ alias(
alias(
name = "glob",
actual = "@vendor__glob-0.3.1//:glob",
actual = "@vendor__glob-0.3.2//:glob",
tags = ["manual"],
)
@@ -98,14 +98,8 @@ alias(
)
alias(
name = "itertools-0.12.1",
actual = "@vendor__itertools-0.12.1//:itertools",
tags = ["manual"],
)
alias(
name = "itertools-0.13.0",
actual = "@vendor__itertools-0.13.0//:itertools",
name = "itertools",
actual = "@vendor__itertools-0.14.0//:itertools",
tags = ["manual"],
)
@@ -147,7 +141,7 @@ alias(
alias(
name = "quote",
actual = "@vendor__quote-1.0.37//:quote",
actual = "@vendor__quote-1.0.38//:quote",
tags = ["manual"],
)
@@ -261,13 +255,13 @@ alias(
alias(
name = "serde",
actual = "@vendor__serde-1.0.216//:serde",
actual = "@vendor__serde-1.0.217//:serde",
tags = ["manual"],
)
alias(
name = "serde_json",
actual = "@vendor__serde_json-1.0.133//:serde_json",
actual = "@vendor__serde_json-1.0.135//:serde_json",
tags = ["manual"],
)
@@ -285,7 +279,7 @@ alias(
alias(
name = "syn",
actual = "@vendor__syn-2.0.90//:syn",
actual = "@vendor__syn-2.0.95//:syn",
tags = ["manual"],
)
@@ -303,7 +297,7 @@ alias(
alias(
name = "tree-sitter",
actual = "@vendor__tree-sitter-0.24.5//:tree_sitter",
actual = "@vendor__tree-sitter-0.24.6//:tree_sitter",
tags = ["manual"],
)

View File

@@ -81,7 +81,7 @@ rust_library(
"@rules_rust//rust/platform:x86_64-unknown-none": [],
"//conditions:default": ["@platforms//:incompatible"],
}),
version = "1.11.1",
version = "1.11.3",
deps = [
"@vendor__memchr-2.7.4//:memchr",
],

View File

@@ -77,5 +77,5 @@ rust_library(
"@rules_rust//rust/platform:x86_64-unknown-none": [],
"//conditions:default": ["@platforms//:incompatible"],
}),
version = "1.20.0",
version = "1.21.0",
)

View File

@@ -85,7 +85,7 @@ rust_library(
version = "1.1.9",
deps = [
"@vendor__camino-1.1.9//:build_script_build",
"@vendor__serde-1.0.216//:serde",
"@vendor__serde-1.0.217//:serde",
],
)

View File

@@ -79,6 +79,6 @@ rust_library(
}),
version = "0.1.9",
deps = [
"@vendor__serde-1.0.216//:serde",
"@vendor__serde-1.0.217//:serde",
],
)

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