Merge branch 'main' into modelnoise

This commit is contained in:
Geoffrey White
2025-04-17 09:42:43 +01:00
365 changed files with 40558 additions and 2644 deletions

View File

@@ -10,7 +10,7 @@ ungrammar = "1.16.1"
proc-macro2 = "1.0.94"
quote = "1.0.40"
either = "1.15.0"
stdx = {package = "ra_ap_stdx", version = "0.0.270"}
stdx = {package = "ra_ap_stdx", version = "0.0.273"}
itertools = "0.14.0"
mustache = "0.9.0"
serde = { version = "1.0.219", features = ["derive"] }

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,4 @@
description: Remove `struct_field_is_unsafe` table
compatibility: backwards
struct_field_is_unsafe.rel: delete

View File

@@ -7,24 +7,24 @@ license = "MIT"
# When updating these dependencies, run `rust/update_cargo_deps.sh`
[dependencies]
anyhow = "1.0.97"
clap = { version = "4.5.32", features = ["derive"] }
clap = { version = "4.5.35", features = ["derive"] }
figment = { version = "0.10.19", features = ["env", "yaml"] }
num-traits = "0.2.19"
ra_ap_base_db = "0.0.270"
ra_ap_hir = "0.0.270"
ra_ap_hir_def = "0.0.270"
ra_ap_ide_db = "0.0.270"
ra_ap_hir_ty = "0.0.270"
ra_ap_hir_expand = "0.0.270"
ra_ap_load-cargo = "0.0.270"
ra_ap_paths = "0.0.270"
ra_ap_project_model = "0.0.270"
ra_ap_syntax = "0.0.270"
ra_ap_vfs = "0.0.270"
ra_ap_parser = "0.0.270"
ra_ap_span = "0.0.270"
ra_ap_cfg = "0.0.270"
ra_ap_intern = "0.0.270"
ra_ap_base_db = "0.0.273"
ra_ap_hir = "0.0.273"
ra_ap_hir_def = "0.0.273"
ra_ap_ide_db = "0.0.273"
ra_ap_hir_ty = "0.0.273"
ra_ap_hir_expand = "0.0.273"
ra_ap_load-cargo = "0.0.273"
ra_ap_paths = "0.0.273"
ra_ap_project_model = "0.0.273"
ra_ap_syntax = "0.0.273"
ra_ap_vfs = "0.0.273"
ra_ap_parser = "0.0.273"
ra_ap_span = "0.0.273"
ra_ap_cfg = "0.0.273"
ra_ap_intern = "0.0.273"
serde = "1.0.219"
serde_with = "3.12.0"
triomphe = "0.1.14"

View File

@@ -18,15 +18,18 @@ use ra_ap_hir_def::{
};
use ra_ap_hir_def::{HasModule, visibility::VisibilityExplicitness};
use ra_ap_hir_def::{ModuleId, resolver::HasResolver};
use ra_ap_hir_ty::TraitRefExt;
use ra_ap_hir_ty::Ty;
use ra_ap_hir_ty::TyExt;
use ra_ap_hir_ty::WhereClause;
use ra_ap_hir_ty::{Binders, FnPointer};
use ra_ap_hir_ty::{Interner, ProjectionTy};
use ra_ap_hir_ty::{TraitRefExt, from_assoc_type_id};
use ra_ap_ide_db::RootDatabase;
use ra_ap_vfs::{Vfs, VfsPath};
use ra_ap_hir_def::data::ConstFlags;
use ra_ap_hir_def::item_tree::StaticFlags;
use ra_ap_hir_ty::db::InternedCallableDefId;
use std::hash::Hasher;
use std::{cmp::Ordering, collections::HashMap, path::PathBuf};
use std::{hash::Hash, vec};
@@ -374,7 +377,7 @@ fn emit_const(
attrs: vec![],
body: None,
is_const: true,
is_default: konst.has_body,
is_default: konst.flags.contains(ConstFlags::HAS_BODY),
type_repr,
visibility,
})
@@ -407,9 +410,9 @@ fn emit_static(
body: None,
type_repr,
visibility,
is_mut: statik.mutable,
is_mut: statik.flags.contains(StaticFlags::MUTABLE),
is_static: true,
is_unsafe: statik.has_unsafe_kw,
is_unsafe: statik.flags.contains(StaticFlags::HAS_UNSAFE_KW),
})
.into(),
);
@@ -774,7 +777,9 @@ fn const_or_function(
let type_: &chalk_ir::Ty<Interner> = type_.skip_binders();
match type_.kind(ra_ap_hir_ty::Interner) {
chalk_ir::TyKind::FnDef(fn_def_id, parameters) => {
let data = db.fn_def_datum(*fn_def_id);
let callable_def_id =
db.lookup_intern_callable_def(InternedCallableDefId::from(*fn_def_id));
let data = db.fn_def_datum(callable_def_id);
let sig = ra_ap_hir_ty::CallableSig::from_def(db, *fn_def_id, parameters);
let params = sig
@@ -1200,7 +1205,7 @@ fn emit_hir_ty(
substitution: _,
}))
| chalk_ir::TyKind::AssociatedType(associated_ty_id, _) => {
let assoc_ty_data = db.associated_ty_data(*associated_ty_id);
let assoc_ty_data = db.associated_ty_data(from_assoc_type_id(*associated_ty_id));
let _name = db
.type_alias_data(assoc_ty_data.name)
@@ -1302,6 +1307,7 @@ fn emit_variant_data(trap: &mut TrapFile, db: &dyn HirDatabase, variant_id: Vari
trap.emit(generated::StructField {
id: trap::TrapId::Star,
attrs: vec![],
is_unsafe: false,
name,
type_repr,
visibility,

View File

@@ -1,2 +1,2 @@
mod.rs 4bcb9def847469aae9d8649461546b7c21ec97cf6e63d3cf394e339915ce65d7 4bcb9def847469aae9d8649461546b7c21ec97cf6e63d3cf394e339915ce65d7
top.rs 50fa90457102611ea7892153e4beb7512d3704a1c78d9bb8e75eb96b98b31740 50fa90457102611ea7892153e4beb7512d3704a1c78d9bb8e75eb96b98b31740
top.rs 060225ccbae440eef117e2ef0a82f3deba29e6ba2d35f00281f9c0e6a945e692 060225ccbae440eef117e2ef0a82f3deba29e6ba2d35f00281f9c0e6a945e692

View File

@@ -2612,6 +2612,7 @@ pub struct StructField {
pub id: trap::TrapId<StructField>,
pub attrs: Vec<trap::Label<Attr>>,
pub default: Option<trap::Label<Expr>>,
pub is_unsafe: bool,
pub name: Option<trap::Label<Name>>,
pub type_repr: Option<trap::Label<TypeRepr>>,
pub visibility: Option<trap::Label<Visibility>>,
@@ -2630,6 +2631,9 @@ impl trap::TrapEntry for StructField {
if let Some(v) = self.default {
out.add_tuple("struct_field_defaults", vec![id.into(), v.into()]);
}
if self.is_unsafe {
out.add_tuple("struct_field_is_unsafe", vec![id.into()]);
}
if let Some(v) = self.name {
out.add_tuple("struct_field_names", vec![id.into(), v.into()]);
}

View File

@@ -1,5 +1,5 @@
use itertools::Itertools;
use ra_ap_base_db::{EditionedFileId, RootQueryDb, SourceDatabase};
use ra_ap_base_db::{EditionedFileId, FileText, RootQueryDb, SourceDatabase};
use ra_ap_hir::Semantics;
use ra_ap_ide_db::RootDatabase;
use ra_ap_load_cargo::{LoadCargoConfig, load_workspace_at};
@@ -7,7 +7,6 @@ use ra_ap_paths::{AbsPath, Utf8PathBuf};
use ra_ap_project_model::ProjectManifest;
use ra_ap_project_model::{CargoConfig, ManifestPath};
use ra_ap_span::Edition;
use ra_ap_span::EditionedFileId as SpanEditionedFileId;
use ra_ap_span::TextRange;
use ra_ap_span::TextSize;
use ra_ap_syntax::SourceFile;
@@ -54,7 +53,6 @@ impl<'a> RustAnalyzer<'a> {
) -> Option<(RootDatabase, Vfs)> {
let progress = |t| (trace!("progress: {}", t));
let manifest = project.manifest_path();
match load_workspace_at(manifest.as_ref(), config, load_config, &progress) {
Ok((db, vfs, _macro_server)) => Some((db, vfs)),
Err(err) => {
@@ -66,67 +64,70 @@ impl<'a> RustAnalyzer<'a> {
pub fn new(vfs: &'a Vfs, semantics: &'a Semantics<'a, RootDatabase>) -> Self {
RustAnalyzer::WithSemantics { vfs, semantics }
}
pub fn parse(&self, path: &Path) -> ParseResult {
let no_semantics_reason;
fn get_file_data(
&self,
path: &Path,
) -> Result<(&Semantics<RootDatabase>, EditionedFileId, FileText), &str> {
match self {
RustAnalyzer::WithoutSemantics { reason } => Err(reason),
RustAnalyzer::WithSemantics { vfs, semantics } => {
if let Some(file_id) = path_to_file_id(path, vfs) {
if let Ok(input) = std::panic::catch_unwind(|| semantics.db.file_text(file_id))
{
let file_id = EditionedFileId::new(
semantics.db,
SpanEditionedFileId::current_edition(file_id),
);
let source_file = semantics.parse(file_id);
let errors = semantics
.db
.parse_errors(file_id)
.into_iter()
.flat_map(|x| x.to_vec())
.collect();
return ParseResult {
ast: source_file,
text: input.text(semantics.db),
errors,
semantics_info: Ok(FileSemanticInformation { file_id, semantics }),
};
}
debug!(
"No text available for file_id '{:?}', falling back to loading file '{}' from disk.",
file_id,
path.to_string_lossy()
);
no_semantics_reason = "no text available for the file in the project";
} else {
no_semantics_reason = "file not found in project";
}
}
RustAnalyzer::WithoutSemantics { reason } => {
no_semantics_reason = reason;
let file_id = path_to_file_id(path, vfs).ok_or("file not found in project")?;
let input = std::panic::catch_unwind(|| semantics.db.file_text(file_id))
.or(Err("no text available for the file in the project"))?;
let editioned_file_id = semantics
.attach_first_edition(file_id)
.ok_or("failed to determine rust edition")?;
Ok((
semantics,
EditionedFileId::new(semantics.db, editioned_file_id),
input,
))
}
}
let mut errors = Vec::new();
let input = match std::fs::read(path) {
Ok(data) => data,
Err(e) => {
errors.push(SyntaxError::new(
format!("Could not read {}: {}", path.to_string_lossy(), e),
TextRange::empty(TextSize::default()),
));
vec![]
}
};
let (input, err) = from_utf8_lossy(&input);
}
let parse = ra_ap_syntax::ast::SourceFile::parse(&input, Edition::CURRENT);
errors.extend(parse.errors());
errors.extend(err);
ParseResult {
ast: parse.tree(),
text: input.as_ref().into(),
errors,
semantics_info: Err(no_semantics_reason),
pub fn parse(&self, path: &Path) -> ParseResult {
match self.get_file_data(path) {
Ok((semantics, file_id, input)) => {
let source_file = semantics.parse(file_id);
let errors = semantics
.db
.parse_errors(file_id)
.into_iter()
.flat_map(|x| x.to_vec())
.collect();
ParseResult {
ast: source_file,
text: input.text(semantics.db),
errors,
semantics_info: Ok(FileSemanticInformation { file_id, semantics }),
}
}
Err(reason) => {
let mut errors = Vec::new();
let input = match std::fs::read(path) {
Ok(data) => data,
Err(e) => {
errors.push(SyntaxError::new(
format!("Could not read {}: {}", path.to_string_lossy(), e),
TextRange::empty(TextSize::default()),
));
vec![]
}
};
let (input, err) = from_utf8_lossy(&input);
let parse = ra_ap_syntax::ast::SourceFile::parse(&input, Edition::CURRENT);
errors.extend(parse.errors());
errors.extend(err);
ParseResult {
ast: parse.tree(),
text: input.as_ref().into(),
errors,
semantics_info: Err(reason),
}
}
}
}
}
@@ -173,8 +174,10 @@ impl TomlReader {
}
fn workspace_members_match(workspace_dir: &AbsPath, members: &[String], target: &AbsPath) -> bool {
members.iter().any(|p| {
glob::Pattern::new(workspace_dir.join(p).as_str()).is_ok_and(|p| p.matches(target.as_str()))
target.strip_prefix(workspace_dir).is_some_and(|rel_path| {
members
.iter()
.any(|p| glob::Pattern::new(p).is_ok_and(|p| p.matches(rel_path.as_str())))
})
}

View File

@@ -1850,6 +1850,7 @@ impl Translator<'_> {
if self.should_be_excluded(&node) { return None; }
let attrs = node.attrs().filter_map(|x| self.emit_attr(x)).collect();
let default = node.expr().and_then(|x| self.emit_expr(x));
let is_unsafe = node.unsafe_token().is_some();
let name = node.name().and_then(|x| self.emit_name(x));
let type_repr = node.ty().and_then(|x| self.emit_type(x));
let visibility = node.visibility().and_then(|x| self.emit_visibility(x));
@@ -1857,6 +1858,7 @@ impl Translator<'_> {
id: TrapId::Star,
attrs,
default,
is_unsafe,
name,
type_repr,
visibility,

View File

@@ -579,7 +579,7 @@ lib/codeql/rust/elements/internal/generated/ParamList.qll c808c9d84dd7800573832b
lib/codeql/rust/elements/internal/generated/ParenExpr.qll bc0731505bfe88516205ec360582a4222d2681d11342c93e15258590ddee82f2 d4bd6e0c80cf1d63746c88d4bcb3a01d4c75732e5da09e3ebd9437ced227fb60
lib/codeql/rust/elements/internal/generated/ParenPat.qll 4f168ef5d5bb87a903251cc31b2e44a759b099ec69c90af31783fbb15778c940 0e34f94a45a13396fd57d94c245dc64d1adde2ab0e22b56946f7e94c04e297fc
lib/codeql/rust/elements/internal/generated/ParenTypeRepr.qll 40ab5c592e7699c621787793743e33988de71ff42ca27599f5ab3ddb70e3f7d8 12c0a6eed2202ee3e892f61da3b3ce77ac3190854cdf3097e8d2be98aa3cb91d
lib/codeql/rust/elements/internal/generated/ParentChild.qll 3a9dd595f34bc5841d21f91882b01f2882b18b70e8c718e81d491b4b33bad82b fb40a76aff319ec5f7dae9a05da083b337887b0918b3702641b39342213ddf6f
lib/codeql/rust/elements/internal/generated/ParentChild.qll d1770632e8d0c649ebcbcab9cbc653531ecf521bbf5d891941db8c0927ae6796 fb40a76aff319ec5f7dae9a05da083b337887b0918b3702641b39342213ddf6f
lib/codeql/rust/elements/internal/generated/ParenthesizedArgList.qll c5fa328ea60d3a3333d7c7bb3480969c1873166c7ac8ebb9d0afad7a8099d1a8 2dbbb6200d96f7db7dea4a55bdeab8d67b14d39a43e0bd54ada019f7e466f163
lib/codeql/rust/elements/internal/generated/Pat.qll 3605ac062be2f294ee73336e9669027b8b655f4ad55660e1eab35266275154ee 7f9400db2884d336dd1d21df2a8093759c2a110be9bf6482ce8e80ae0fd74ed4
lib/codeql/rust/elements/internal/generated/Path.qll 9b12afb46fc5a9ad3a811b05472621bbecccb900c47504feb7f29d96b28421ca bcacbffc36fb3e0c9b26523b5963af0ffa9fd6b19f00a2a31bdb2316071546bd
@@ -594,7 +594,7 @@ lib/codeql/rust/elements/internal/generated/PtrTypeRepr.qll 51d1e9e683fc79dddbff
lib/codeql/rust/elements/internal/generated/PureSynthConstructors.qll e5b8e69519012bbaae29dcb82d53f7f7ecce368c0358ec27ef6180b228a0057f e5b8e69519012bbaae29dcb82d53f7f7ecce368c0358ec27ef6180b228a0057f
lib/codeql/rust/elements/internal/generated/RangeExpr.qll 23cca03bf43535f33b22a38894f70d669787be4e4f5b8fe5c8f7b964d30e9027 18624cef6c6b679eeace2a98737e472432e0ead354cca02192b4d45330f047c9
lib/codeql/rust/elements/internal/generated/RangePat.qll 80826a6a6868a803aa2372e31c52a03e1811a3f1f2abdb469f91ca0bfdd9ecb6 34ee1e208c1690cba505dff2c588837c0cd91e185e2a87d1fe673191962276a9
lib/codeql/rust/elements/internal/generated/Raw.qll 4a73b51a4e7c995c42d68cf64ff8aff351d898f306ceedf70a009bf86bbf7d84 f7ccdbc4841d87dae7bbf6f58556901176c930a9a797a59dbc04269ca3b516ce
lib/codeql/rust/elements/internal/generated/Raw.qll 6e33d9fa21ee3287a0ebc27856a09f4fdc4d587b5a31ff1c4337106de7ca1a2e eece38e6accb6b9d8838fd05edd7cbaf6f7ee37190adbef2b023ad91064d1622
lib/codeql/rust/elements/internal/generated/RefExpr.qll 7d995884e3dc1c25fc719f5d7253179344d63650e217e9ff6530285fe7a57f64 f2c3c12551deea4964b66553fb9b6423ee16fec53bd63db4796191aa60dc6c66
lib/codeql/rust/elements/internal/generated/RefPat.qll 456ede39837463ee22a630ec7ab6c8630d3664a8ea206fcc6e4f199e92fa564c 5622062765f32930465ba6b170e986706f159f6070f48adee3c20e24e8df4e05
lib/codeql/rust/elements/internal/generated/RefTypeRepr.qll 3d8c0bd296d33b91a81633f697a43269a6538df06d277262d3990d3f6880ef57 13680f39e89bcd8299c218aba396f3deec804597e6f7cb7d4a7e7c748b6faa77
@@ -615,7 +615,7 @@ lib/codeql/rust/elements/internal/generated/Struct.qll b54a48c32d99345f22f189da8
lib/codeql/rust/elements/internal/generated/StructExpr.qll c6d861eaa0123b103fd9ffd2485423419ef9b7e0b4af9ed2a2090d8ec534f65d 50da99ee44771e1239ed8919f711991dd3ec98589fbe49b49b68c88074a07d74
lib/codeql/rust/elements/internal/generated/StructExprField.qll 6bdc52ed325fd014495410c619536079b8c404e2247bd2435aa7685dd56c3833 501a30650cf813176ff325a1553da6030f78d14be3f84fea6d38032f4262c6b0
lib/codeql/rust/elements/internal/generated/StructExprFieldList.qll b19b6869a6828c7a39a7312539eb29fd21734ff47dfd02281de74194fd565d7e 3cadebffaa937e367a5e1da6741e4e9e5c9a9c7f7555e28cfa70639afd19db7c
lib/codeql/rust/elements/internal/generated/StructField.qll bcbaa836d9b9889c87ba57c6ea733cdc85425168d9df05aca5cfd051851d8cd1 a17034896bc7fa25c84e40b460109d122ca1e85632cf8ac620f66f3eb0ff81b5
lib/codeql/rust/elements/internal/generated/StructField.qll 18b62eb2ea7d3fe109308540cb219763e968b866c8600226b44f81159d3c549b 1acfc0da7ae1d8d4b3fa2cdcc440cc1423c5cd885da03c0e8b2c81a2b089cbbb
lib/codeql/rust/elements/internal/generated/StructFieldList.qll 8911a44217d091b05f488da4e012cb026aed0630caa84ca301bbcbd054c9a28c a433383fea7e42f20750aa43e6070c23baad761a4264be99257541c1004ead31
lib/codeql/rust/elements/internal/generated/StructPat.qll c76fa005c2fd0448a8803233e1e8818c4123301eb66ac5cf69d0b9eaafc61e98 6e0dffccdce24bca20e87d5ba0f0995c9a1ae8983283e71e7dbfcf6fffc67a58
lib/codeql/rust/elements/internal/generated/StructPatField.qll 5b5c7302dbc4a902ca8e69ff31875c867e295a16a626ba3cef29cd0aa248f179 4e192a0df79947f5cb0d47fdbbba7986137a6a40a1be92ae119873e2fad67edf
@@ -1087,7 +1087,7 @@ test/extractor-tests/generated/StructExprFieldList/StructExprFieldList.ql 33dc3f
test/extractor-tests/generated/StructExprFieldList/StructExprFieldList_getAttr.ql cd7f5236f6b660fc064f3a04f3a58d720ed4e81916cbd1a049c1fac7171108ed 61317928d0833f7bb55255a5045bedc0913db1266e963ede97d597ee43e3ddd9
test/extractor-tests/generated/StructExprFieldList/StructExprFieldList_getField.ql 1292aec1141bdb75fd8e0993f683035f396a0e6c841b76ee86a0a1d3dce0dbc4 450eccbd07cc0aa81cef698f43d60aeb55f8952a573eaf84a389a6449c3d63a7
test/extractor-tests/generated/StructExprFieldList/StructExprFieldList_getSpread.ql d0470b9846323d0408e0f26444cdc5322d78ce1ac203073ff4f556dac5343be7 280712a0b3714256aff4c2a4370fd43e70c418f526e383ed7100d61cdf790c36
test/extractor-tests/generated/StructField/StructField.ql 7943d00e32171da93fae8215456c79b2df590cffa7241f4c0e78b0d7d525b1b2 6d5e3825075d2cb4438adf699a5a92ce22301ea58888d63ea336118bf29c0205
test/extractor-tests/generated/StructField/StructField.ql 5ec75ec3c1a18299259dfa041790e9b4a791ceb1706aadea3537d0a67e7e65bb cba580a8678547dc88a736bd639cc4d8e84ec32a9ad1095e50f7e03047c37f1c
test/extractor-tests/generated/StructField/StructField_getAttr.ql a01715bc688d5fa48c9dd4bfab21d0909169f851a290895c13a181f22c0e73a9 fa6ffcf007492d9e1b7f90d571b9747bd47b2dc29e558a8e1c3013c5949dcdb7
test/extractor-tests/generated/StructField/StructField_getDefault.ql deccc63b81892cd1b293d8b328ad5b3efdf32892efc8b161dfcd89330ca6b5a2 9a9f306f63208ce30d26f91dd15b94867a7d9affd31a0f51a3d1d2ce50786abc
test/extractor-tests/generated/StructField/StructField_getName.ql 4c5a7e00b758a744a719bff63d493ee7d31ff8b3010e00c1d1449034d00130ec 9b284d848e5c86eac089f33deca7586441a89d927e7703cb4f98bb7c65a7238c

View File

@@ -2,13 +2,35 @@ import pytest
import json
import commands
import pathlib
import tomllib
@pytest.fixture(params=[2018, 2021, 2024])
def rust_edition(request):
return request.param
@pytest.fixture
def cargo(cwd):
assert (cwd / "Cargo.toml").exists()
def cargo(cwd, rust_edition):
manifest_file = cwd / "Cargo.toml"
assert manifest_file.exists()
(cwd / "rust-project.json").unlink(missing_ok=True)
def update(file):
contents = file.read_text()
m = tomllib.loads(contents)
if 'package' in m:
# tomllib does not support writing, and we don't want to use further dependencies
# so we just do a dumb search and replace
contents = contents.replace(f'edition = "{m["package"]["edition"]}"', f'edition = "{rust_edition}"')
file.write_text(contents)
if 'members' in m.get('workspace', ()):
for member in m['workspace']['members']:
update(file.parent / member / "Cargo.toml")
update(manifest_file)
@pytest.fixture(scope="session")
def rust_sysroot_src() -> str:
rust_sysroot = pathlib.Path(commands.run("rustc --print sysroot", _capture=True))
@@ -16,15 +38,19 @@ def rust_sysroot_src() -> str:
assert ret.exists()
return str(ret)
@pytest.fixture
def rust_project(cwd, rust_sysroot_src):
def rust_project(cwd, rust_sysroot_src, rust_edition):
project_file = cwd / "rust-project.json"
assert project_file.exists()
project = json.loads(project_file.read_text())
project["sysroot_src"] = rust_sysroot_src
for c in project["crates"]:
c["edition"] = str(rust_edition)
project_file.write_text(json.dumps(project, indent=4))
(cwd / "Cargo.toml").unlink(missing_ok=True)
@pytest.fixture
def rust_check_diagnostics(check_diagnostics):
check_diagnostics.redact += [

View File

@@ -2,6 +2,6 @@
[package]
name = "hello-cargo"
version = "0.1.0"
edition = "2021"
edition = "2021" # replaced in test
[dependencies]

View File

@@ -1,7 +1,7 @@
[package]
name = "exe"
version = "0.1.0"
edition = "2021"
edition = "2021" # replaced in test
[dependencies]
lib = { path = "../lib" }

View File

@@ -1,6 +1,6 @@
[package]
name = "lib"
version = "0.1.0"
edition = "2021"
edition = "2021" # replaced in test
[dependencies]

View File

@@ -21,4 +21,4 @@
"deps": []
}
]
}
}

View File

@@ -1,6 +1,5 @@
import pytest
@pytest.mark.ql_test("steps.ql", expected=".cargo.expected")
@pytest.mark.ql_test("summary.qlref", expected=".cargo.expected")
def test_cargo(codeql, rust, cargo, check_source_archive, rust_check_diagnostics):

View File

@@ -1,3 +1,7 @@
## 0.1.6
No user-facing changes.
## 0.1.5
No user-facing changes.

View File

@@ -0,0 +1,3 @@
## 0.1.6
No user-facing changes.

View File

@@ -1,2 +1,2 @@
---
lastReleaseVersion: 0.1.5
lastReleaseVersion: 0.1.6

View File

@@ -955,6 +955,11 @@ module Raw {
*/
Expr getDefault() { struct_field_defaults(this, result) }
/**
* Holds if this struct field is unsafe.
*/
predicate isUnsafe() { struct_field_is_unsafe(this) }
/**
* Gets the name of this struct field, if it exists.
*/

View File

@@ -64,6 +64,11 @@ module Generated {
*/
final predicate hasDefault() { exists(this.getDefault()) }
/**
* Holds if this struct field is unsafe.
*/
predicate isUnsafe() { Synth::convertStructFieldToRaw(this).(Raw::StructField).isUnsafe() }
/**
* Gets the name of this struct field, if it exists.
*/

View File

@@ -3,5 +3,12 @@ extensions:
pack: codeql/rust-all
extensible: sourceModel
data:
# Alloc
- ["repo:https://github.com/rust-lang/libc:libc", "::free", "Argument[0]", "pointer-invalidate", "manual"]
- addsTo:
pack: codeql/rust-all
extensible: sinkModel
data:
- ["repo:https://github.com/rust-lang/libc:libc", "::malloc", "Argument[0]", "alloc-size", "manual"]
- ["repo:https://github.com/rust-lang/libc:libc", "::aligned_alloc", "Argument[1]", "alloc-size", "manual"]
- ["repo:https://github.com/rust-lang/libc:libc", "::calloc", "Argument[0,1]", "alloc-size", "manual"]
- ["repo:https://github.com/rust-lang/libc:libc", "::realloc", "Argument[1]", "alloc-size", "manual"]

View File

@@ -1,4 +1,30 @@
extensions:
- addsTo:
pack: codeql/rust-all
extensible: sourceModel
data:
# Alloc
- ["lang:alloc", "crate::alloc::dealloc", "Argument[0]", "pointer-invalidate", "manual"]
- addsTo:
pack: codeql/rust-all
extensible: sinkModel
data:
# Alloc
- ["lang:alloc", "crate::alloc::alloc", "Argument[0]", "alloc-layout", "manual"]
- ["lang:alloc", "crate::alloc::alloc_zeroed", "Argument[0]", "alloc-layout", "manual"]
- ["lang:alloc", "crate::alloc::realloc", "Argument[2]", "alloc-size", "manual"]
- ["lang:std", "<crate::alloc::System as crate::alloc::global::GlobalAlloc>::alloc", "Argument[0]", "alloc-layout", "manual"]
- ["lang:std", "<crate::alloc::System as crate::alloc::global::GlobalAlloc>::alloc_zeroed", "Argument[0]", "alloc-layout", "manual"]
- ["lang:std", "<crate::alloc::System as crate::alloc::Allocator>::allocate", "Argument[0]", "alloc-layout", "manual"]
- ["lang:std", "<crate::alloc::System as crate::alloc::Allocator>::allocate_zeroed", "Argument[0]", "alloc-layout", "manual"]
- ["lang:std", "<crate::alloc::System as crate::alloc::Allocator>::grow", "Argument[2]", "alloc-layout", "manual"]
- ["lang:std", "<crate::alloc::System as crate::alloc::Allocator>::grow_zeroed", "Argument[2]", "alloc-layout", "manual"]
- ["lang:alloc", "<crate::alloc::Global as crate::alloc::global::GlobalAlloc>::alloc", "Argument[0]", "alloc-layout", "manual"]
- ["lang:alloc", "<crate::alloc::Global as crate::alloc::global::GlobalAlloc>::alloc_zeroed", "Argument[0]", "alloc-layout", "manual"]
- ["lang:alloc", "<crate::alloc::Global as crate::alloc::Allocator>::allocate", "Argument[0]", "alloc-layout", "manual"]
- ["lang:alloc", "<crate::alloc::Global as crate::alloc::Allocator>::allocate_zeroed", "Argument[0]", "alloc-layout", "manual"]
- ["lang:alloc", "<crate::alloc::Global as crate::alloc::Allocator>::grow", "Argument[2]", "alloc-layout", "manual"]
- ["lang:alloc", "<crate::alloc::Global as crate::alloc::Allocator>::grow_zeroed", "Argument[2]", "alloc-layout", "manual"]
- addsTo:
pack: codeql/rust-all
extensible: summaryModel
@@ -9,9 +35,3 @@ extensions:
- ["lang:alloc", "<crate::string::String>::as_str", "Argument[self]", "ReturnValue", "taint", "manual"]
- ["lang:alloc", "<crate::string::String>::as_bytes", "Argument[self]", "ReturnValue", "taint", "manual"]
- ["lang:alloc", "<_ as crate::string::ToString>::to_string", "Argument[self]", "ReturnValue", "taint", "manual"]
- addsTo:
pack: codeql/rust-all
extensible: sourceModel
data:
# Alloc
- ["lang:alloc", "crate::alloc::dealloc", "Argument[0]", "pointer-invalidate", "manual"]

View File

@@ -17,6 +17,21 @@ extensions:
- ["lang:core", "<crate::slice::iter::Iter as crate::iter::traits::iterator::Iterator>::collect", "Argument[self].Element", "ReturnValue.Element", "value", "manual"]
- ["lang:core", "<crate::slice::iter::Iter as crate::iter::traits::iterator::Iterator>::map", "Argument[self].Element", "Argument[0].Parameter[0]", "value", "manual"]
- ["lang:core", "<crate::slice::iter::Iter as crate::iter::traits::iterator::Iterator>::for_each", "Argument[self].Element", "Argument[0].Parameter[0]", "value", "manual"]
# Layout
- ["lang:core", "<crate::alloc::layout::Layout>::from_size_align", "Argument[0]", "ReturnValue.Field[crate::result::Result::Ok(0)]", "taint", "manual"]
- ["lang:core", "<crate::alloc::layout::Layout>::from_size_align_unchecked", "Argument[0]", "ReturnValue", "taint", "manual"]
- ["lang:core", "<crate::alloc::layout::Layout>::array", "Argument[0]", "ReturnValue.Field[crate::result::Result::Ok(0)]", "taint", "manual"]
- ["lang:core", "<crate::alloc::layout::Layout>::repeat", "Argument[self]", "ReturnValue.Field[crate::result::Result::Ok(0)].Field[0]", "taint", "manual"]
- ["lang:core", "<crate::alloc::layout::Layout>::repeat", "Argument[0]", "ReturnValue.Field[crate::result::Result::Ok(0)].Field[0]", "taint", "manual"]
- ["lang:core", "<crate::alloc::layout::Layout>::repeat_packed", "Argument[self]", "ReturnValue.Field[crate::result::Result::Ok(0)]", "taint", "manual"]
- ["lang:core", "<crate::alloc::layout::Layout>::repeat_packed", "Argument[0]", "ReturnValue.Field[crate::result::Result::Ok(0)]", "taint", "manual"]
- ["lang:core", "<crate::alloc::layout::Layout>::extend", "Argument[self]", "ReturnValue.Field[crate::result::Result::Ok(0)].Field[0]", "taint", "manual"]
- ["lang:core", "<crate::alloc::layout::Layout>::extend", "Argument[0]", "ReturnValue.Field[crate::result::Result::Ok(0)].Field[0]", "taint", "manual"]
- ["lang:core", "<crate::alloc::layout::Layout>::extend_packed", "Argument[self]", "ReturnValue.Field[crate::result::Result::Ok(0)]", "taint", "manual"]
- ["lang:core", "<crate::alloc::layout::Layout>::extend_packed", "Argument[0]", "ReturnValue.Field[crate::result::Result::Ok(0)]", "taint", "manual"]
- ["lang:core", "<crate::alloc::layout::Layout>::align_to", "Argument[self]", "ReturnValue.Field[crate::result::Result::Ok(0)]", "taint", "manual"]
- ["lang:core", "<crate::alloc::layout::Layout>::pad_to_align", "Argument[self]", "ReturnValue", "taint", "manual"]
- ["lang:core", "<crate::alloc::layout::Layout>::size", "Argument[self]", "ReturnValue", "taint", "manual"]
# Ptr
- ["lang:core", "crate::ptr::read", "Argument[0].Reference", "ReturnValue", "value", "manual"]
- ["lang:core", "crate::ptr::read_unaligned", "Argument[0].Reference", "ReturnValue", "value", "manual"]

View File

@@ -178,7 +178,7 @@ abstract class ItemNode extends Locatable {
Stages::PathResolutionStage::ref() and
result = this.getASuccessorRec(name)
or
preludeEdge(this, name, result)
preludeEdge(this, name, result) and not declares(this, _, name)
or
name = "super" and
if this instanceof Module or this instanceof SourceFile

View File

@@ -0,0 +1,95 @@
/**
* Provides classes and predicates for reasoning about uncontrolled allocation
* size vulnerabilities.
*/
import rust
private import codeql.rust.Concepts
private import codeql.rust.dataflow.DataFlow
private import codeql.rust.dataflow.FlowSink
private import codeql.rust.controlflow.ControlFlowGraph as Cfg
private import codeql.rust.controlflow.CfgNodes as CfgNodes
/**
* Provides default sources, sinks and barriers for detecting uncontrolled
* allocation size vulnerabilities, as well as extension points for adding your own.
*/
module UncontrolledAllocationSize {
/**
* A data flow sink for uncontrolled allocation size vulnerabilities.
*/
abstract class Sink extends QuerySink::Range {
override string getSinkType() { result = "UncontrolledAllocationSize" }
}
/**
* A barrier for uncontrolled allocation size vulnerabilities.
*/
abstract class Barrier extends DataFlow::Node { }
/**
* A sink for uncontrolled allocation size from model data.
*/
private class ModelsAsDataSink extends Sink {
ModelsAsDataSink() { sinkNode(this, ["alloc-size", "alloc-layout"]) }
}
/**
* A barrier for uncontrolled allocation size that is an upper bound check / guard.
*/
private class UpperBoundCheckBarrier extends Barrier {
UpperBoundCheckBarrier() {
this = DataFlow::BarrierGuard<isUpperBoundCheck/3>::getABarrierNode()
}
}
/**
* Gets the operand on the "greater" (or "greater-or-equal") side
* of this relational expression, that is, the side that is larger
* if the overall expression evaluates to `true`; for example on
* `x <= 20` this is the `20`, and on `y > 0` it is `y`.
*/
private Expr getGreaterOperand(BinaryExpr op) {
op.getOperatorName() = ["<", "<="] and
result = op.getRhs()
or
op.getOperatorName() = [">", ">="] and
result = op.getLhs()
}
/**
* Gets the operand on the "lesser" (or "lesser-or-equal") side
* of this relational expression, that is, the side that is smaller
* if the overall expression evaluates to `true`; for example on
* `x <= 20` this is `x`, and on `y > 0` it is the `0`.
*/
private Expr getLesserOperand(BinaryExpr op) {
op.getOperatorName() = ["<", "<="] and
result = op.getLhs()
or
op.getOperatorName() = [">", ">="] and
result = op.getRhs()
}
/**
* Holds if comparison `g` having result `branch` indicates an upper bound for the sub-expression
* `node`. For example when the comparison `x < 10` is true, we have an upper bound for `x`.
*/
private predicate isUpperBoundCheck(CfgNodes::AstCfgNode g, Cfg::CfgNode node, boolean branch) {
exists(BinaryExpr cmp | g = cmp.getACfgNode() |
node = getLesserOperand(cmp).getACfgNode() and
branch = true
or
node = getGreaterOperand(cmp).getACfgNode() and
branch = false
or
cmp.getOperatorName() = "==" and
[cmp.getLhs(), cmp.getRhs()].getACfgNode() = node and
branch = true
or
cmp.getOperatorName() = "!=" and
[cmp.getLhs(), cmp.getRhs()].getACfgNode() = node and
branch = false
)
}
}

View File

@@ -1,9 +1,10 @@
name: codeql/rust-all
version: 0.1.6-dev
version: 0.1.7-dev
groups: rust
extractor: rust
dbscheme: rust.dbscheme
library: true
upgrades: upgrades
dependencies:
codeql/controlflow: ${workspace}
codeql/dataflow: ${workspace}

View File

@@ -976,6 +976,11 @@ struct_field_defaults(
int default: @expr ref
);
#keyset[id]
struct_field_is_unsafe(
int id: @struct_field ref
);
#keyset[id]
struct_field_names(
int id: @struct_field ref,

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: Add `struct_field_is_unsafe` table
compatibility: backwards

View File

@@ -1,3 +1,7 @@
## 0.1.6
No user-facing changes.
## 0.1.5
No user-facing changes.

View File

@@ -0,0 +1,3 @@
## 0.1.6
No user-facing changes.

View File

@@ -1,2 +1,2 @@
---
lastReleaseVersion: 0.1.5
lastReleaseVersion: 0.1.6

View File

@@ -1,5 +1,5 @@
name: codeql/rust-queries
version: 0.1.6-dev
version: 0.1.7-dev
groups:
- rust
- queries

View File

@@ -0,0 +1,41 @@
<!DOCTYPE qhelp PUBLIC
"-//Semmle//qhelp//EN"
"qhelp.dtd">
<qhelp>
<overview>
<p>Allocating memory with a size based on user input may allow arbitrary amounts of memory to be
allocated, leading to a crash or a denial-of-service (DoS) attack.</p>
<p>If the user input is multiplied by a constant, such as the size of a type, the result may
overflow. In a build with the <code>--release</code> flag, Rust performs two's complement wrapping,
with the result that less memory than expected may be allocated. This can lead to buffer overflow
incidents.</p>
</overview>
<recommendation>
<p>Implement a guard to limit the amount of memory that is allocated, and reject the request if
the guard is not met. Ensure that any multiplications in the calculation cannot overflow, either
by guarding their inputs, or using a multiplication routine such as <code>checked_mul</code> that
does not wrap around.</p>
</recommendation>
<example>
<p>In the following example, an arbitrary amount of memory is allocated based on user input. In
addition, due to the multiplication operation, the result may overflow if a very large value is
provided. This may lead to less memory being allocated than expected by other parts of the program.</p>
<sample src="UncontrolledAllocationSizeBad.rs" />
<p>In the fixed example, the user input is checked against a maximum value. If the check fails, an
error is returned, and both the multiplication and allocation do not take place.</p>
<sample src="UncontrolledAllocationSizeGood.rs" />
</example>
<references>
<li>The Rust Programming Language: <a href="https://doc.rust-lang.org/book/ch03-02-data-types.html#integer-overflow">Data Types - Integer Overflow</a>.</li>
</references>
</qhelp>

View File

@@ -0,0 +1,45 @@
/**
* @name Uncontrolled allocation size
* @description Allocating memory with a size controlled by an external user can result in
* arbitrary amounts of memory being allocated, leading to a crash or a
* denial-of-service (DoS) attack.
* @kind path-problem
* @problem.severity recommendation
* @security-severity 7.5
* @precision high
* @id rust/uncontrolled-allocation-size
* @tags reliability
* security
* external/cwe/cwe-770
* external/cwe/cwe-789
*/
import rust
import codeql.rust.Concepts
import codeql.rust.dataflow.DataFlow
import codeql.rust.dataflow.TaintTracking
import codeql.rust.dataflow.internal.DataFlowImpl
import codeql.rust.security.UncontrolledAllocationSizeExtensions
/**
* A taint-tracking configuration for uncontrolled allocation size vulnerabilities.
*/
module UncontrolledAllocationConfig implements DataFlow::ConfigSig {
import UncontrolledAllocationSize
predicate isSource(DataFlow::Node source) { source instanceof ActiveThreatModelSource }
predicate isSink(DataFlow::Node sink) { sink instanceof Sink }
predicate isBarrier(DataFlow::Node barrier) { barrier instanceof Barrier }
}
module UncontrolledAllocationFlow = TaintTracking::Global<UncontrolledAllocationConfig>;
import UncontrolledAllocationFlow::PathGraph
from UncontrolledAllocationFlow::PathNode source, UncontrolledAllocationFlow::PathNode sink
where UncontrolledAllocationFlow::flowPath(source, sink)
select sink.getNode(), source, sink,
"This allocation size is derived from a $@ and could allocate arbitrary amounts of memory.",
source.getNode(), "user-provided value"

View File

@@ -0,0 +1,11 @@
fn allocate_buffer(user_input: String) -> Result<*mut u8, Error> {
let num_bytes = user_input.parse::<usize>()? * std::mem::size_of::<u64>();
let layout = std::alloc::Layout::from_size_align(num_bytes, 1).unwrap();
unsafe {
let buffer = std::alloc::alloc(layout); // BAD: uncontrolled allocation size
Ok(buffer)
}
}

View File

@@ -0,0 +1,17 @@
const BUFFER_LIMIT: usize = 10 * 1024;
fn allocate_buffer(user_input: String) -> Result<*mut u8, Error> {
let size = user_input.parse::<usize>()?;
if size > BUFFER_LIMIT {
return Err("Size exceeds limit".into());
}
let num_bytes = size * std::mem::size_of::<u64>();
let layout = std::alloc::Layout::from_size_align(num_bytes, 1).unwrap();
unsafe {
let buffer = std::alloc::alloc(layout); // GOOD
Ok(buffer)
}
}

View File

@@ -22,6 +22,7 @@ private import codeql.rust.security.CleartextLoggingExtensions
private import codeql.rust.security.CleartextTransmissionExtensions
private import codeql.rust.security.SqlInjectionExtensions
private import codeql.rust.security.TaintedPathExtensions
private import codeql.rust.security.UncontrolledAllocationSizeExtensions
private import codeql.rust.security.WeakSensitiveDataHashingExtensions
/**

View File

@@ -3,15 +3,16 @@ import codeql.rust.elements
import TestUtils
from
StructField x, int getNumberOfAttrs, string hasDefault, string hasName, string hasTypeRepr,
string hasVisibility
StructField x, int getNumberOfAttrs, string hasDefault, string isUnsafe, string hasName,
string hasTypeRepr, string hasVisibility
where
toBeTested(x) and
not x.isUnknown() and
getNumberOfAttrs = x.getNumberOfAttrs() and
(if x.hasDefault() then hasDefault = "yes" else hasDefault = "no") and
(if x.isUnsafe() then isUnsafe = "yes" else isUnsafe = "no") and
(if x.hasName() then hasName = "yes" else hasName = "no") and
(if x.hasTypeRepr() then hasTypeRepr = "yes" else hasTypeRepr = "no") and
if x.hasVisibility() then hasVisibility = "yes" else hasVisibility = "no"
select x, "getNumberOfAttrs:", getNumberOfAttrs, "hasDefault:", hasDefault, "hasName:", hasName,
"hasTypeRepr:", hasTypeRepr, "hasVisibility:", hasVisibility
select x, "getNumberOfAttrs:", getNumberOfAttrs, "hasDefault:", hasDefault, "isUnsafe:", isUnsafe,
"hasName:", hasName, "hasTypeRepr:", hasTypeRepr, "hasVisibility:", hasVisibility

View File

@@ -1100,6 +1100,13 @@ storeStep
| file://:0:0:0:0 | [summary] to write: ReturnValue.Field[crate::result::Result::Err(0)].Reference in lang:core::_::<crate::result::Result>::as_ref | &ref | file://:0:0:0:0 | [summary] to write: ReturnValue.Field[crate::result::Result::Err(0)] in lang:core::_::<crate::result::Result>::as_ref |
| file://:0:0:0:0 | [summary] to write: ReturnValue.Field[crate::result::Result::Ok(0)] in lang:alloc::_::<crate::collections::btree::node::NodeRef>::search_tree_for_bifurcation | Ok | file://:0:0:0:0 | [summary] to write: ReturnValue in lang:alloc::_::<crate::collections::btree::node::NodeRef>::search_tree_for_bifurcation |
| file://:0:0:0:0 | [summary] to write: ReturnValue.Field[crate::result::Result::Ok(0)] in lang:alloc::_::<crate::string::String as crate::str::traits::FromStr>::from_str | Ok | file://:0:0:0:0 | [summary] to write: ReturnValue in lang:alloc::_::<crate::string::String as crate::str::traits::FromStr>::from_str |
| file://:0:0:0:0 | [summary] to write: ReturnValue.Field[crate::result::Result::Ok(0)] in lang:core::_::<crate::alloc::layout::Layout>::align_to | Ok | file://:0:0:0:0 | [summary] to write: ReturnValue in lang:core::_::<crate::alloc::layout::Layout>::align_to |
| file://:0:0:0:0 | [summary] to write: ReturnValue.Field[crate::result::Result::Ok(0)] in lang:core::_::<crate::alloc::layout::Layout>::array | Ok | file://:0:0:0:0 | [summary] to write: ReturnValue in lang:core::_::<crate::alloc::layout::Layout>::array |
| file://:0:0:0:0 | [summary] to write: ReturnValue.Field[crate::result::Result::Ok(0)] in lang:core::_::<crate::alloc::layout::Layout>::extend | Ok | file://:0:0:0:0 | [summary] to write: ReturnValue in lang:core::_::<crate::alloc::layout::Layout>::extend |
| file://:0:0:0:0 | [summary] to write: ReturnValue.Field[crate::result::Result::Ok(0)] in lang:core::_::<crate::alloc::layout::Layout>::extend_packed | Ok | file://:0:0:0:0 | [summary] to write: ReturnValue in lang:core::_::<crate::alloc::layout::Layout>::extend_packed |
| file://:0:0:0:0 | [summary] to write: ReturnValue.Field[crate::result::Result::Ok(0)] in lang:core::_::<crate::alloc::layout::Layout>::from_size_align | Ok | file://:0:0:0:0 | [summary] to write: ReturnValue in lang:core::_::<crate::alloc::layout::Layout>::from_size_align |
| file://:0:0:0:0 | [summary] to write: ReturnValue.Field[crate::result::Result::Ok(0)] in lang:core::_::<crate::alloc::layout::Layout>::repeat | Ok | file://:0:0:0:0 | [summary] to write: ReturnValue in lang:core::_::<crate::alloc::layout::Layout>::repeat |
| file://:0:0:0:0 | [summary] to write: ReturnValue.Field[crate::result::Result::Ok(0)] in lang:core::_::<crate::alloc::layout::Layout>::repeat_packed | Ok | file://:0:0:0:0 | [summary] to write: ReturnValue in lang:core::_::<crate::alloc::layout::Layout>::repeat_packed |
| file://:0:0:0:0 | [summary] to write: ReturnValue.Field[crate::result::Result::Ok(0)] in lang:core::_::<crate::cell::once::OnceCell>::try_insert | Ok | file://:0:0:0:0 | [summary] to write: ReturnValue in lang:core::_::<crate::cell::once::OnceCell>::try_insert |
| file://:0:0:0:0 | [summary] to write: ReturnValue.Field[crate::result::Result::Ok(0)] in lang:core::_::<crate::option::Option>::ok_or | Ok | file://:0:0:0:0 | [summary] to write: ReturnValue in lang:core::_::<crate::option::Option>::ok_or |
| file://:0:0:0:0 | [summary] to write: ReturnValue.Field[crate::result::Result::Ok(0)] in lang:core::_::<crate::option::Option>::ok_or_else | Ok | file://:0:0:0:0 | [summary] to write: ReturnValue in lang:core::_::<crate::option::Option>::ok_or_else |
@@ -1133,6 +1140,8 @@ storeStep
| file://:0:0:0:0 | [summary] to write: ReturnValue.Field[crate::result::Result::Ok(0)] in repo:https://github.com/seanmonstar/reqwest:reqwest::_::<crate::response::Response>::text_with_charset | Ok | file://:0:0:0:0 | [summary] to write: ReturnValue in repo:https://github.com/seanmonstar/reqwest:reqwest::_::<crate::response::Response>::text_with_charset |
| file://:0:0:0:0 | [summary] to write: ReturnValue.Field[crate::result::Result::Ok(0)] in repo:https://github.com/servo/rust-url:url::_::<crate::Url>::parse | Ok | file://:0:0:0:0 | [summary] to write: ReturnValue in repo:https://github.com/servo/rust-url:url::_::<crate::Url>::parse |
| file://:0:0:0:0 | [summary] to write: ReturnValue.Field[crate::result::Result::Ok(0)].Field[0] in lang:alloc::_::<crate::collections::btree::node::NodeRef>::search_tree_for_bifurcation | tuple.0 | file://:0:0:0:0 | [summary] to write: ReturnValue.Field[crate::result::Result::Ok(0)] in lang:alloc::_::<crate::collections::btree::node::NodeRef>::search_tree_for_bifurcation |
| file://:0:0:0:0 | [summary] to write: ReturnValue.Field[crate::result::Result::Ok(0)].Field[0] in lang:core::_::<crate::alloc::layout::Layout>::extend | tuple.0 | file://:0:0:0:0 | [summary] to write: ReturnValue.Field[crate::result::Result::Ok(0)] in lang:core::_::<crate::alloc::layout::Layout>::extend |
| file://:0:0:0:0 | [summary] to write: ReturnValue.Field[crate::result::Result::Ok(0)].Field[0] in lang:core::_::<crate::alloc::layout::Layout>::repeat | tuple.0 | file://:0:0:0:0 | [summary] to write: ReturnValue.Field[crate::result::Result::Ok(0)] in lang:core::_::<crate::alloc::layout::Layout>::repeat |
| file://:0:0:0:0 | [summary] to write: ReturnValue.Field[crate::result::Result::Ok(0)].Field[0] in lang:std::_::<crate::sync::poison::condvar::Condvar>::wait_timeout | tuple.0 | file://:0:0:0:0 | [summary] to write: ReturnValue.Field[crate::result::Result::Ok(0)] in lang:std::_::<crate::sync::poison::condvar::Condvar>::wait_timeout |
| file://:0:0:0:0 | [summary] to write: ReturnValue.Field[crate::result::Result::Ok(0)].Field[0] in lang:std::_::<crate::sync::poison::condvar::Condvar>::wait_timeout_ms | tuple.0 | file://:0:0:0:0 | [summary] to write: ReturnValue.Field[crate::result::Result::Ok(0)] in lang:std::_::<crate::sync::poison::condvar::Condvar>::wait_timeout_ms |
| file://:0:0:0:0 | [summary] to write: ReturnValue.Field[crate::result::Result::Ok(0)].Field[0] in lang:std::_::<crate::sync::poison::condvar::Condvar>::wait_timeout_while | tuple.0 | file://:0:0:0:0 | [summary] to write: ReturnValue.Field[crate::result::Result::Ok(0)] in lang:std::_::<crate::sync::poison::condvar::Condvar>::wait_timeout_while |

View File

@@ -16,3 +16,21 @@ mod my4 {
}
pub use my4::my5::f as nested_f; // $ item=I201
type Result<
T, // T
> = ::std::result::Result<
T, // $ item=T
String,
>; // my::Result
fn int_div(
x: i32, //
y: i32,
) -> Result<i32> // $ item=my::Result
{
if y == 0 {
return Err("Div by zero".to_string());
}
Ok(x / y)
}

View File

@@ -322,6 +322,13 @@ resolvePath
| my.rs:18:9:18:11 | my4 | my.rs:14:1:16:1 | mod my4 |
| my.rs:18:9:18:16 | ...::my5 | my.rs:15:5:15:16 | mod my5 |
| my.rs:18:9:18:19 | ...::f | my/my4/my5/mod.rs:1:1:3:1 | fn f |
| my.rs:22:5:22:9 | std | file:///RUSTUP_HOME/toolchain/lib/rustlib/src/rust/library/std/src/lib.rs:0:0:0:0 | Crate(std@0.0.0) |
| my.rs:22:5:22:17 | ...::result | file://:0:0:0:0 | mod result |
| my.rs:22:5:25:1 | ...::Result::<...> | file://:0:0:0:0 | enum Result |
| my.rs:23:5:23:5 | T | my.rs:21:5:21:5 | T |
| my.rs:30:6:30:16 | Result::<...> | my.rs:20:1:25:2 | type Result<...> |
| my.rs:33:16:33:18 | Err | file://:0:0:0:0 | Err |
| my.rs:35:5:35:6 | Ok | file://:0:0:0:0 | Ok |
| my/nested.rs:9:13:9:13 | f | my/nested.rs:3:9:5:9 | fn f |
| my/nested.rs:15:9:15:15 | nested2 | my/nested.rs:2:5:11:5 | mod nested2 |
| my/nested.rs:15:9:15:18 | ...::f | my/nested.rs:3:9:5:9 | fn f |

View File

@@ -5,6 +5,17 @@ import TestUtils
query predicate mod(Module m) { toBeTested(m) }
query predicate resolvePath(Path p, ItemNode i) {
class ItemNodeLoc extends Locatable instanceof ItemNode {
predicate hasLocationInfo(
string filepath, int startline, int startcolumn, int endline, int endcolumn
) {
exists(string file |
super.getLocation().hasLocationInfo(file, startline, startcolumn, endline, endcolumn) and
filepath = file.regexpReplaceAll("^/.*/.rustup/toolchains/[^/]+/", "/RUSTUP_HOME/toolchain/")
)
}
}
query predicate resolvePath(Path p, ItemNodeLoc i) {
toBeTested(p) and not p.isInMacroExpansion() and i = resolvePath(p)
}

View File

@@ -2,16 +2,21 @@
| main.rs:6:25:6:30 | &regex | main.rs:4:20:4:32 | ...::var | main.rs:6:25:6:30 | &regex | This regular expression is constructed from a $@. | main.rs:4:20:4:32 | ...::var | user-provided value |
edges
| main.rs:4:9:4:16 | username | main.rs:5:25:5:44 | MacroExpr | provenance | |
| main.rs:4:20:4:32 | ...::var | main.rs:4:20:4:40 | ...::var(...) [Ok] | provenance | Src:MaD:66 |
| main.rs:4:20:4:40 | ...::var(...) [Ok] | main.rs:4:20:4:66 | ... .unwrap_or(...) | provenance | MaD:1641 |
| main.rs:4:20:4:32 | ...::var | main.rs:4:20:4:40 | ...::var(...) [Ok] | provenance | Src:MaD:1 |
| main.rs:4:20:4:40 | ...::var(...) [Ok] | main.rs:4:20:4:66 | ... .unwrap_or(...) | provenance | MaD:3 |
| main.rs:4:20:4:66 | ... .unwrap_or(...) | main.rs:4:9:4:16 | username | provenance | |
| main.rs:5:9:5:13 | regex | main.rs:6:26:6:30 | regex | provenance | |
| main.rs:5:17:5:45 | res | main.rs:5:25:5:44 | { ... } | provenance | |
| main.rs:5:25:5:44 | ...::format(...) | main.rs:5:17:5:45 | res | provenance | |
| main.rs:5:25:5:44 | ...::must_use(...) | main.rs:5:9:5:13 | regex | provenance | |
| main.rs:5:25:5:44 | MacroExpr | main.rs:5:25:5:44 | ...::format(...) | provenance | MaD:102 |
| main.rs:5:25:5:44 | { ... } | main.rs:5:25:5:44 | ...::must_use(...) | provenance | MaD:3064 |
| main.rs:5:25:5:44 | MacroExpr | main.rs:5:25:5:44 | ...::format(...) | provenance | MaD:2 |
| main.rs:5:25:5:44 | { ... } | main.rs:5:25:5:44 | ...::must_use(...) | provenance | MaD:4 |
| main.rs:6:26:6:30 | regex | main.rs:6:25:6:30 | &regex | provenance | |
models
| 1 | Source: lang:std; crate::env::var; environment-source; ReturnValue.Field[crate::result::Result::Ok(0)] |
| 2 | Summary: lang:alloc; crate::fmt::format; Argument[0]; ReturnValue; taint |
| 3 | Summary: lang:core; <crate::result::Result>::unwrap_or; Argument[self].Field[crate::result::Result::Ok(0)]; ReturnValue; value |
| 4 | Summary: lang:core; crate::hint::must_use; Argument[0]; ReturnValue; value |
nodes
| main.rs:4:9:4:16 | username | semmle.label | username |
| main.rs:4:20:4:32 | ...::var | semmle.label | ...::var |

View File

@@ -1,2 +1,4 @@
query: queries/security/CWE-020/RegexInjection.ql
postprocess: utils/test/InlineExpectationsTestQuery.ql
postprocess:
- utils/test/PrettyPrintModels.ql
- utils/test/InlineExpectationsTestQuery.ql

View File

@@ -1,3 +0,0 @@
extractionWarning
| test_logging.rs:90:12:90:30 | expected R_PAREN |
| test_logging.rs:90:12:90:30 | macro expansion failed: the macro '$crate::__private_api::format_args' expands to ERROR but a Expr was expected |

View File

@@ -0,0 +1,503 @@
#select
| main.rs:18:13:18:31 | ...::realloc | main.rs:317:13:317:26 | ...::args | main.rs:18:13:18:31 | ...::realloc | This allocation size is derived from a $@ and could allocate arbitrary amounts of memory. | main.rs:317:13:317:26 | ...::args | user-provided value |
| main.rs:21:13:21:29 | ...::alloc | main.rs:317:13:317:26 | ...::args | main.rs:21:13:21:29 | ...::alloc | This allocation size is derived from a $@ and could allocate arbitrary amounts of memory. | main.rs:317:13:317:26 | ...::args | user-provided value |
| main.rs:22:13:22:29 | ...::alloc | main.rs:317:13:317:26 | ...::args | main.rs:22:13:22:29 | ...::alloc | This allocation size is derived from a $@ and could allocate arbitrary amounts of memory. | main.rs:317:13:317:26 | ...::args | user-provided value |
| main.rs:23:13:23:29 | ...::alloc | main.rs:317:13:317:26 | ...::args | main.rs:23:13:23:29 | ...::alloc | This allocation size is derived from a $@ and could allocate arbitrary amounts of memory. | main.rs:317:13:317:26 | ...::args | user-provided value |
| main.rs:24:13:24:36 | ...::alloc_zeroed | main.rs:317:13:317:26 | ...::args | main.rs:24:13:24:36 | ...::alloc_zeroed | This allocation size is derived from a $@ and could allocate arbitrary amounts of memory. | main.rs:317:13:317:26 | ...::args | user-provided value |
| main.rs:30:13:30:29 | ...::alloc | main.rs:317:13:317:26 | ...::args | main.rs:30:13:30:29 | ...::alloc | This allocation size is derived from a $@ and could allocate arbitrary amounts of memory. | main.rs:317:13:317:26 | ...::args | user-provided value |
| main.rs:33:13:33:29 | ...::alloc | main.rs:317:13:317:26 | ...::args | main.rs:33:13:33:29 | ...::alloc | This allocation size is derived from a $@ and could allocate arbitrary amounts of memory. | main.rs:317:13:317:26 | ...::args | user-provided value |
| main.rs:37:13:37:29 | ...::alloc | main.rs:317:13:317:26 | ...::args | main.rs:37:13:37:29 | ...::alloc | This allocation size is derived from a $@ and could allocate arbitrary amounts of memory. | main.rs:317:13:317:26 | ...::args | user-provided value |
| main.rs:40:13:40:29 | ...::alloc | main.rs:317:13:317:26 | ...::args | main.rs:40:13:40:29 | ...::alloc | This allocation size is derived from a $@ and could allocate arbitrary amounts of memory. | main.rs:317:13:317:26 | ...::args | user-provided value |
| main.rs:50:13:50:29 | ...::alloc | main.rs:317:13:317:26 | ...::args | main.rs:50:13:50:29 | ...::alloc | This allocation size is derived from a $@ and could allocate arbitrary amounts of memory. | main.rs:317:13:317:26 | ...::args | user-provided value |
| main.rs:51:13:51:29 | ...::alloc | main.rs:317:13:317:26 | ...::args | main.rs:51:13:51:29 | ...::alloc | This allocation size is derived from a $@ and could allocate arbitrary amounts of memory. | main.rs:317:13:317:26 | ...::args | user-provided value |
| main.rs:53:13:53:29 | ...::alloc | main.rs:317:13:317:26 | ...::args | main.rs:53:13:53:29 | ...::alloc | This allocation size is derived from a $@ and could allocate arbitrary amounts of memory. | main.rs:317:13:317:26 | ...::args | user-provided value |
| main.rs:54:13:54:29 | ...::alloc | main.rs:317:13:317:26 | ...::args | main.rs:54:13:54:29 | ...::alloc | This allocation size is derived from a $@ and could allocate arbitrary amounts of memory. | main.rs:317:13:317:26 | ...::args | user-provided value |
| main.rs:59:13:59:29 | ...::alloc | main.rs:317:13:317:26 | ...::args | main.rs:59:13:59:29 | ...::alloc | This allocation size is derived from a $@ and could allocate arbitrary amounts of memory. | main.rs:317:13:317:26 | ...::args | user-provided value |
| main.rs:61:13:61:29 | ...::alloc | main.rs:317:13:317:26 | ...::args | main.rs:61:13:61:29 | ...::alloc | This allocation size is derived from a $@ and could allocate arbitrary amounts of memory. | main.rs:317:13:317:26 | ...::args | user-provided value |
| main.rs:63:13:63:29 | ...::alloc | main.rs:317:13:317:26 | ...::args | main.rs:63:13:63:29 | ...::alloc | This allocation size is derived from a $@ and could allocate arbitrary amounts of memory. | main.rs:317:13:317:26 | ...::args | user-provided value |
| main.rs:64:13:64:29 | ...::alloc | main.rs:317:13:317:26 | ...::args | main.rs:64:13:64:29 | ...::alloc | This allocation size is derived from a $@ and could allocate arbitrary amounts of memory. | main.rs:317:13:317:26 | ...::args | user-provided value |
| main.rs:65:13:65:29 | ...::alloc | main.rs:317:13:317:26 | ...::args | main.rs:65:13:65:29 | ...::alloc | This allocation size is derived from a $@ and could allocate arbitrary amounts of memory. | main.rs:317:13:317:26 | ...::args | user-provided value |
| main.rs:68:13:68:29 | ...::alloc | main.rs:317:13:317:26 | ...::args | main.rs:68:13:68:29 | ...::alloc | This allocation size is derived from a $@ and could allocate arbitrary amounts of memory. | main.rs:317:13:317:26 | ...::args | user-provided value |
| main.rs:88:13:88:29 | ...::alloc | main.rs:317:13:317:26 | ...::args | main.rs:88:13:88:29 | ...::alloc | This allocation size is derived from a $@ and could allocate arbitrary amounts of memory. | main.rs:317:13:317:26 | ...::args | user-provided value |
| main.rs:96:17:96:33 | ...::alloc | main.rs:317:13:317:26 | ...::args | main.rs:96:17:96:33 | ...::alloc | This allocation size is derived from a $@ and could allocate arbitrary amounts of memory. | main.rs:317:13:317:26 | ...::args | user-provided value |
| main.rs:102:17:102:33 | ...::alloc | main.rs:317:13:317:26 | ...::args | main.rs:102:17:102:33 | ...::alloc | This allocation size is derived from a $@ and could allocate arbitrary amounts of memory. | main.rs:317:13:317:26 | ...::args | user-provided value |
| main.rs:103:17:103:33 | ...::alloc | main.rs:317:13:317:26 | ...::args | main.rs:103:17:103:33 | ...::alloc | This allocation size is derived from a $@ and could allocate arbitrary amounts of memory. | main.rs:317:13:317:26 | ...::args | user-provided value |
| main.rs:109:17:109:33 | ...::alloc | main.rs:317:13:317:26 | ...::args | main.rs:109:17:109:33 | ...::alloc | This allocation size is derived from a $@ and could allocate arbitrary amounts of memory. | main.rs:317:13:317:26 | ...::args | user-provided value |
| main.rs:111:17:111:33 | ...::alloc | main.rs:317:13:317:26 | ...::args | main.rs:111:17:111:33 | ...::alloc | This allocation size is derived from a $@ and could allocate arbitrary amounts of memory. | main.rs:317:13:317:26 | ...::args | user-provided value |
| main.rs:146:17:146:33 | ...::alloc | main.rs:317:13:317:26 | ...::args | main.rs:146:17:146:33 | ...::alloc | This allocation size is derived from a $@ and could allocate arbitrary amounts of memory. | main.rs:317:13:317:26 | ...::args | user-provided value |
| main.rs:148:17:148:33 | ...::alloc | main.rs:317:13:317:26 | ...::args | main.rs:148:17:148:33 | ...::alloc | This allocation size is derived from a $@ and could allocate arbitrary amounts of memory. | main.rs:317:13:317:26 | ...::args | user-provided value |
| main.rs:152:13:152:29 | ...::alloc | main.rs:317:13:317:26 | ...::args | main.rs:152:13:152:29 | ...::alloc | This allocation size is derived from a $@ and could allocate arbitrary amounts of memory. | main.rs:317:13:317:26 | ...::args | user-provided value |
| main.rs:155:13:155:29 | ...::alloc | main.rs:317:13:317:26 | ...::args | main.rs:155:13:155:29 | ...::alloc | This allocation size is derived from a $@ and could allocate arbitrary amounts of memory. | main.rs:317:13:317:26 | ...::args | user-provided value |
| main.rs:162:17:162:33 | ...::alloc | main.rs:317:13:317:26 | ...::args | main.rs:162:17:162:33 | ...::alloc | This allocation size is derived from a $@ and could allocate arbitrary amounts of memory. | main.rs:317:13:317:26 | ...::args | user-provided value |
| main.rs:169:17:169:33 | ...::alloc | main.rs:317:13:317:26 | ...::args | main.rs:169:17:169:33 | ...::alloc | This allocation size is derived from a $@ and could allocate arbitrary amounts of memory. | main.rs:317:13:317:26 | ...::args | user-provided value |
| main.rs:177:13:177:29 | ...::alloc | main.rs:317:13:317:26 | ...::args | main.rs:177:13:177:29 | ...::alloc | This allocation size is derived from a $@ and could allocate arbitrary amounts of memory. | main.rs:317:13:317:26 | ...::args | user-provided value |
| main.rs:193:32:193:36 | alloc | main.rs:317:13:317:26 | ...::args | main.rs:193:32:193:36 | alloc | This allocation size is derived from a $@ and could allocate arbitrary amounts of memory. | main.rs:317:13:317:26 | ...::args | user-provided value |
| main.rs:194:32:194:43 | alloc_zeroed | main.rs:317:13:317:26 | ...::args | main.rs:194:32:194:43 | alloc_zeroed | This allocation size is derived from a $@ and could allocate arbitrary amounts of memory. | main.rs:317:13:317:26 | ...::args | user-provided value |
| main.rs:195:32:195:39 | allocate | main.rs:317:13:317:26 | ...::args | main.rs:195:32:195:39 | allocate | This allocation size is derived from a $@ and could allocate arbitrary amounts of memory. | main.rs:317:13:317:26 | ...::args | user-provided value |
| main.rs:196:32:196:46 | allocate_zeroed | main.rs:317:13:317:26 | ...::args | main.rs:196:32:196:46 | allocate_zeroed | This allocation size is derived from a $@ and could allocate arbitrary amounts of memory. | main.rs:317:13:317:26 | ...::args | user-provided value |
| main.rs:197:32:197:39 | allocate | main.rs:317:13:317:26 | ...::args | main.rs:197:32:197:39 | allocate | This allocation size is derived from a $@ and could allocate arbitrary amounts of memory. | main.rs:317:13:317:26 | ...::args | user-provided value |
| main.rs:198:32:198:46 | allocate_zeroed | main.rs:317:13:317:26 | ...::args | main.rs:198:32:198:46 | allocate_zeroed | This allocation size is derived from a $@ and could allocate arbitrary amounts of memory. | main.rs:317:13:317:26 | ...::args | user-provided value |
| main.rs:208:40:208:43 | grow | main.rs:317:13:317:26 | ...::args | main.rs:208:40:208:43 | grow | This allocation size is derived from a $@ and could allocate arbitrary amounts of memory. | main.rs:317:13:317:26 | ...::args | user-provided value |
| main.rs:210:40:210:50 | grow_zeroed | main.rs:317:13:317:26 | ...::args | main.rs:210:40:210:50 | grow_zeroed | This allocation size is derived from a $@ and could allocate arbitrary amounts of memory. | main.rs:317:13:317:26 | ...::args | user-provided value |
| main.rs:219:13:219:24 | ...::malloc | main.rs:317:13:317:26 | ...::args | main.rs:219:13:219:24 | ...::malloc | This allocation size is derived from a $@ and could allocate arbitrary amounts of memory. | main.rs:317:13:317:26 | ...::args | user-provided value |
| main.rs:220:13:220:31 | ...::aligned_alloc | main.rs:317:13:317:26 | ...::args | main.rs:220:13:220:31 | ...::aligned_alloc | This allocation size is derived from a $@ and could allocate arbitrary amounts of memory. | main.rs:317:13:317:26 | ...::args | user-provided value |
| main.rs:222:13:222:24 | ...::calloc | main.rs:317:13:317:26 | ...::args | main.rs:222:13:222:24 | ...::calloc | This allocation size is derived from a $@ and could allocate arbitrary amounts of memory. | main.rs:317:13:317:26 | ...::args | user-provided value |
| main.rs:223:13:223:24 | ...::calloc | main.rs:317:13:317:26 | ...::args | main.rs:223:13:223:24 | ...::calloc | This allocation size is derived from a $@ and could allocate arbitrary amounts of memory. | main.rs:317:13:317:26 | ...::args | user-provided value |
| main.rs:224:13:224:25 | ...::realloc | main.rs:317:13:317:26 | ...::args | main.rs:224:13:224:25 | ...::realloc | This allocation size is derived from a $@ and could allocate arbitrary amounts of memory. | main.rs:317:13:317:26 | ...::args | user-provided value |
| main.rs:284:22:284:38 | ...::alloc | main.rs:308:25:308:38 | ...::args | main.rs:284:22:284:38 | ...::alloc | This allocation size is derived from a $@ and could allocate arbitrary amounts of memory. | main.rs:308:25:308:38 | ...::args | user-provided value |
edges
| main.rs:12:36:12:43 | ...: usize | main.rs:18:41:18:41 | v | provenance | |
| main.rs:18:41:18:41 | v | main.rs:18:13:18:31 | ...::realloc | provenance | MaD:5 Sink:MaD:5 |
| main.rs:18:41:18:41 | v | main.rs:20:50:20:50 | v | provenance | |
| main.rs:18:41:18:41 | v | main.rs:29:60:29:60 | v | provenance | |
| main.rs:18:41:18:41 | v | main.rs:32:60:32:89 | ... * ... | provenance | |
| main.rs:18:41:18:41 | v | main.rs:35:9:35:10 | s6 | provenance | |
| main.rs:20:9:20:10 | l2 | main.rs:21:31:21:32 | l2 | provenance | |
| main.rs:20:14:20:54 | ...::from_size_align(...) [Ok] | main.rs:20:14:20:63 | ... .unwrap() | provenance | MaD:31 |
| main.rs:20:14:20:63 | ... .unwrap() | main.rs:20:9:20:10 | l2 | provenance | |
| main.rs:20:50:20:50 | v | main.rs:20:14:20:54 | ...::from_size_align(...) [Ok] | provenance | MaD:23 |
| main.rs:21:31:21:32 | l2 | main.rs:21:13:21:29 | ...::alloc | provenance | MaD:3 Sink:MaD:3 |
| main.rs:21:31:21:32 | l2 | main.rs:22:31:22:44 | l2.align_to(...) [Ok] | provenance | MaD:17 |
| main.rs:21:31:21:32 | l2 | main.rs:23:31:23:44 | l2.align_to(...) [Ok] | provenance | MaD:17 |
| main.rs:21:31:21:32 | l2 | main.rs:24:38:24:39 | l2 | provenance | |
| main.rs:22:31:22:44 | l2.align_to(...) [Ok] | main.rs:22:31:22:53 | ... .unwrap() | provenance | MaD:31 |
| main.rs:22:31:22:53 | ... .unwrap() | main.rs:22:13:22:29 | ...::alloc | provenance | MaD:3 Sink:MaD:3 |
| main.rs:23:31:23:44 | l2.align_to(...) [Ok] | main.rs:23:31:23:53 | ... .unwrap() | provenance | MaD:31 |
| main.rs:23:31:23:53 | ... .unwrap() | main.rs:23:31:23:68 | ... .pad_to_align() | provenance | MaD:25 |
| main.rs:23:31:23:68 | ... .pad_to_align() | main.rs:23:13:23:29 | ...::alloc | provenance | MaD:3 Sink:MaD:3 |
| main.rs:24:38:24:39 | l2 | main.rs:24:13:24:36 | ...::alloc_zeroed | provenance | MaD:4 Sink:MaD:4 |
| main.rs:29:9:29:10 | l4 | main.rs:30:31:30:32 | l4 | provenance | |
| main.rs:29:14:29:64 | ...::from_size_align_unchecked(...) | main.rs:29:9:29:10 | l4 | provenance | |
| main.rs:29:60:29:60 | v | main.rs:29:14:29:64 | ...::from_size_align_unchecked(...) | provenance | MaD:24 |
| main.rs:30:31:30:32 | l4 | main.rs:30:13:30:29 | ...::alloc | provenance | MaD:3 Sink:MaD:3 |
| main.rs:32:9:32:10 | l5 | main.rs:33:31:33:32 | l5 | provenance | |
| main.rs:32:14:32:118 | ...::from_size_align_unchecked(...) | main.rs:32:9:32:10 | l5 | provenance | |
| main.rs:32:60:32:89 | ... * ... | main.rs:32:14:32:118 | ...::from_size_align_unchecked(...) | provenance | MaD:24 |
| main.rs:33:31:33:32 | l5 | main.rs:33:13:33:29 | ...::alloc | provenance | MaD:3 Sink:MaD:3 |
| main.rs:35:9:35:10 | s6 | main.rs:36:60:36:61 | s6 | provenance | |
| main.rs:36:9:36:10 | l6 | main.rs:37:31:37:32 | l6 | provenance | |
| main.rs:36:14:36:65 | ...::from_size_align_unchecked(...) | main.rs:36:9:36:10 | l6 | provenance | |
| main.rs:36:60:36:61 | s6 | main.rs:36:14:36:65 | ...::from_size_align_unchecked(...) | provenance | MaD:24 |
| main.rs:37:31:37:32 | l6 | main.rs:37:13:37:29 | ...::alloc | provenance | MaD:3 Sink:MaD:3 |
| main.rs:37:31:37:32 | l6 | main.rs:39:60:39:68 | l6.size() | provenance | MaD:28 |
| main.rs:39:9:39:10 | l7 | main.rs:40:31:40:32 | l7 | provenance | |
| main.rs:39:14:39:72 | ...::from_size_align_unchecked(...) | main.rs:39:9:39:10 | l7 | provenance | |
| main.rs:39:60:39:68 | l6.size() | main.rs:39:14:39:72 | ...::from_size_align_unchecked(...) | provenance | MaD:24 |
| main.rs:40:31:40:32 | l7 | main.rs:40:13:40:29 | ...::alloc | provenance | MaD:3 Sink:MaD:3 |
| main.rs:43:44:43:51 | ...: usize | main.rs:50:41:50:41 | v | provenance | |
| main.rs:43:44:43:51 | ...: usize | main.rs:51:41:51:45 | ... + ... | provenance | |
| main.rs:43:44:43:51 | ...: usize | main.rs:53:48:53:48 | v | provenance | |
| main.rs:43:44:43:51 | ...: usize | main.rs:54:48:54:53 | ... * ... | provenance | |
| main.rs:43:44:43:51 | ...: usize | main.rs:58:34:58:34 | v | provenance | |
| main.rs:43:44:43:51 | ...: usize | main.rs:67:46:67:46 | v | provenance | |
| main.rs:50:31:50:42 | l2.repeat(...) [Ok, tuple.0] | main.rs:50:31:50:51 | ... .unwrap() [tuple.0] | provenance | MaD:31 |
| main.rs:50:31:50:51 | ... .unwrap() [tuple.0] | main.rs:50:31:50:53 | ... .0 | provenance | |
| main.rs:50:31:50:53 | ... .0 | main.rs:50:13:50:29 | ...::alloc | provenance | MaD:3 Sink:MaD:3 |
| main.rs:50:41:50:41 | v | main.rs:50:31:50:42 | l2.repeat(...) [Ok, tuple.0] | provenance | MaD:26 |
| main.rs:51:31:51:46 | l2.repeat(...) [Ok, tuple.0] | main.rs:51:31:51:55 | ... .unwrap() [tuple.0] | provenance | MaD:31 |
| main.rs:51:31:51:55 | ... .unwrap() [tuple.0] | main.rs:51:31:51:57 | ... .0 | provenance | |
| main.rs:51:31:51:57 | ... .0 | main.rs:51:13:51:29 | ...::alloc | provenance | MaD:3 Sink:MaD:3 |
| main.rs:51:41:51:45 | ... + ... | main.rs:51:31:51:46 | l2.repeat(...) [Ok, tuple.0] | provenance | MaD:26 |
| main.rs:53:31:53:49 | l2.repeat_packed(...) [Ok] | main.rs:53:31:53:58 | ... .unwrap() | provenance | MaD:31 |
| main.rs:53:31:53:58 | ... .unwrap() | main.rs:53:13:53:29 | ...::alloc | provenance | MaD:3 Sink:MaD:3 |
| main.rs:53:48:53:48 | v | main.rs:53:31:53:49 | l2.repeat_packed(...) [Ok] | provenance | MaD:27 |
| main.rs:54:31:54:54 | l2.repeat_packed(...) [Ok] | main.rs:54:31:54:63 | ... .unwrap() | provenance | MaD:31 |
| main.rs:54:31:54:63 | ... .unwrap() | main.rs:54:13:54:29 | ...::alloc | provenance | MaD:3 Sink:MaD:3 |
| main.rs:54:48:54:53 | ... * ... | main.rs:54:31:54:54 | l2.repeat_packed(...) [Ok] | provenance | MaD:27 |
| main.rs:58:9:58:20 | TuplePat [tuple.0] | main.rs:58:10:58:11 | k1 | provenance | |
| main.rs:58:10:58:11 | k1 | main.rs:59:31:59:32 | k1 | provenance | |
| main.rs:58:24:58:35 | l3.repeat(...) [Ok, tuple.0] | main.rs:58:24:58:66 | ... .expect(...) [tuple.0] | provenance | MaD:30 |
| main.rs:58:24:58:66 | ... .expect(...) [tuple.0] | main.rs:58:9:58:20 | TuplePat [tuple.0] | provenance | |
| main.rs:58:34:58:34 | v | main.rs:58:24:58:35 | l3.repeat(...) [Ok, tuple.0] | provenance | MaD:26 |
| main.rs:59:31:59:32 | k1 | main.rs:59:13:59:29 | ...::alloc | provenance | MaD:3 Sink:MaD:3 |
| main.rs:59:31:59:32 | k1 | main.rs:60:34:60:35 | k1 | provenance | |
| main.rs:59:31:59:32 | k1 | main.rs:62:24:62:36 | k1.extend(...) [Ok, tuple.0] | provenance | MaD:20 |
| main.rs:59:31:59:32 | k1 | main.rs:64:48:64:49 | k1 | provenance | |
| main.rs:59:31:59:32 | k1 | main.rs:65:31:65:50 | k1.extend_packed(...) [Ok] | provenance | MaD:22 |
| main.rs:60:9:60:20 | TuplePat [tuple.0] | main.rs:60:10:60:11 | k2 | provenance | |
| main.rs:60:10:60:11 | k2 | main.rs:61:31:61:32 | k2 | provenance | |
| main.rs:60:24:60:36 | l3.extend(...) [Ok, tuple.0] | main.rs:60:24:60:45 | ... .unwrap() [tuple.0] | provenance | MaD:31 |
| main.rs:60:24:60:45 | ... .unwrap() [tuple.0] | main.rs:60:9:60:20 | TuplePat [tuple.0] | provenance | |
| main.rs:60:34:60:35 | k1 | main.rs:60:24:60:36 | l3.extend(...) [Ok, tuple.0] | provenance | MaD:19 |
| main.rs:61:31:61:32 | k2 | main.rs:61:13:61:29 | ...::alloc | provenance | MaD:3 Sink:MaD:3 |
| main.rs:62:9:62:20 | TuplePat [tuple.0] | main.rs:62:10:62:11 | k3 | provenance | |
| main.rs:62:10:62:11 | k3 | main.rs:63:31:63:32 | k3 | provenance | |
| main.rs:62:24:62:36 | k1.extend(...) [Ok, tuple.0] | main.rs:62:24:62:45 | ... .unwrap() [tuple.0] | provenance | MaD:31 |
| main.rs:62:24:62:45 | ... .unwrap() [tuple.0] | main.rs:62:9:62:20 | TuplePat [tuple.0] | provenance | |
| main.rs:63:31:63:32 | k3 | main.rs:63:13:63:29 | ...::alloc | provenance | MaD:3 Sink:MaD:3 |
| main.rs:64:31:64:50 | l3.extend_packed(...) [Ok] | main.rs:64:31:64:59 | ... .unwrap() | provenance | MaD:31 |
| main.rs:64:31:64:59 | ... .unwrap() | main.rs:64:13:64:29 | ...::alloc | provenance | MaD:3 Sink:MaD:3 |
| main.rs:64:48:64:49 | k1 | main.rs:64:31:64:50 | l3.extend_packed(...) [Ok] | provenance | MaD:21 |
| main.rs:65:31:65:50 | k1.extend_packed(...) [Ok] | main.rs:65:31:65:59 | ... .unwrap() | provenance | MaD:31 |
| main.rs:65:31:65:59 | ... .unwrap() | main.rs:65:13:65:29 | ...::alloc | provenance | MaD:3 Sink:MaD:3 |
| main.rs:67:9:67:10 | l4 | main.rs:68:31:68:32 | l4 | provenance | |
| main.rs:67:14:67:47 | ...::array::<...>(...) [Ok] | main.rs:67:14:67:56 | ... .unwrap() | provenance | MaD:31 |
| main.rs:67:14:67:56 | ... .unwrap() | main.rs:67:9:67:10 | l4 | provenance | |
| main.rs:67:46:67:46 | v | main.rs:67:14:67:47 | ...::array::<...>(...) [Ok] | provenance | MaD:18 |
| main.rs:68:31:68:32 | l4 | main.rs:68:13:68:29 | ...::alloc | provenance | MaD:3 Sink:MaD:3 |
| main.rs:86:35:86:42 | ...: usize | main.rs:87:54:87:54 | v | provenance | |
| main.rs:87:9:87:14 | layout | main.rs:88:31:88:36 | layout | provenance | |
| main.rs:87:18:87:58 | ...::from_size_align(...) [Ok] | main.rs:87:18:87:67 | ... .unwrap() | provenance | MaD:31 |
| main.rs:87:18:87:67 | ... .unwrap() | main.rs:87:9:87:14 | layout | provenance | |
| main.rs:87:54:87:54 | v | main.rs:87:18:87:58 | ...::from_size_align(...) [Ok] | provenance | MaD:23 |
| main.rs:88:31:88:36 | layout | main.rs:88:13:88:29 | ...::alloc | provenance | MaD:3 Sink:MaD:3 |
| main.rs:91:38:91:45 | ...: usize | main.rs:92:47:92:47 | v | provenance | |
| main.rs:91:38:91:45 | ...: usize | main.rs:101:51:101:51 | v | provenance | |
| main.rs:91:38:91:45 | ...: usize | main.rs:105:33:105:33 | v | provenance | |
| main.rs:91:38:91:45 | ...: usize | main.rs:145:51:145:51 | v | provenance | |
| main.rs:91:38:91:45 | ...: usize | main.rs:151:62:151:62 | v | provenance | |
| main.rs:91:38:91:45 | ...: usize | main.rs:154:62:154:62 | v | provenance | |
| main.rs:91:38:91:45 | ...: usize | main.rs:161:55:161:55 | v | provenance | |
| main.rs:92:9:92:10 | l1 | main.rs:96:35:96:36 | l1 | provenance | |
| main.rs:92:9:92:10 | l1 | main.rs:102:35:102:36 | l1 | provenance | |
| main.rs:92:14:92:48 | ...::array::<...>(...) [Ok] | main.rs:92:14:92:57 | ... .unwrap() | provenance | MaD:31 |
| main.rs:92:14:92:57 | ... .unwrap() | main.rs:92:9:92:10 | l1 | provenance | |
| main.rs:92:47:92:47 | v | main.rs:92:14:92:48 | ...::array::<...>(...) [Ok] | provenance | MaD:18 |
| main.rs:96:35:96:36 | l1 | main.rs:96:17:96:33 | ...::alloc | provenance | MaD:3 Sink:MaD:3 |
| main.rs:96:35:96:36 | l1 | main.rs:109:35:109:36 | l1 | provenance | |
| main.rs:96:35:96:36 | l1 | main.rs:111:35:111:36 | l1 | provenance | |
| main.rs:101:13:101:14 | l3 | main.rs:103:35:103:36 | l3 | provenance | |
| main.rs:101:18:101:52 | ...::array::<...>(...) [Ok] | main.rs:101:18:101:61 | ... .unwrap() | provenance | MaD:31 |
| main.rs:101:18:101:61 | ... .unwrap() | main.rs:101:13:101:14 | l3 | provenance | |
| main.rs:101:51:101:51 | v | main.rs:101:18:101:52 | ...::array::<...>(...) [Ok] | provenance | MaD:18 |
| main.rs:102:35:102:36 | l1 | main.rs:102:17:102:33 | ...::alloc | provenance | MaD:3 Sink:MaD:3 |
| main.rs:102:35:102:36 | l1 | main.rs:109:35:109:36 | l1 | provenance | |
| main.rs:102:35:102:36 | l1 | main.rs:111:35:111:36 | l1 | provenance | |
| main.rs:103:35:103:36 | l3 | main.rs:103:17:103:33 | ...::alloc | provenance | MaD:3 Sink:MaD:3 |
| main.rs:105:33:105:33 | v | main.rs:86:35:86:42 | ...: usize | provenance | |
| main.rs:109:35:109:36 | l1 | main.rs:109:17:109:33 | ...::alloc | provenance | MaD:3 Sink:MaD:3 |
| main.rs:109:35:109:36 | l1 | main.rs:146:35:146:36 | l1 | provenance | |
| main.rs:111:35:111:36 | l1 | main.rs:111:17:111:33 | ...::alloc | provenance | MaD:3 Sink:MaD:3 |
| main.rs:111:35:111:36 | l1 | main.rs:146:35:146:36 | l1 | provenance | |
| main.rs:145:13:145:14 | l9 | main.rs:148:35:148:36 | l9 | provenance | |
| main.rs:145:18:145:52 | ...::array::<...>(...) [Ok] | main.rs:145:18:145:61 | ... .unwrap() | provenance | MaD:31 |
| main.rs:145:18:145:61 | ... .unwrap() | main.rs:145:13:145:14 | l9 | provenance | |
| main.rs:145:51:145:51 | v | main.rs:145:18:145:52 | ...::array::<...>(...) [Ok] | provenance | MaD:18 |
| main.rs:146:35:146:36 | l1 | main.rs:146:17:146:33 | ...::alloc | provenance | MaD:3 Sink:MaD:3 |
| main.rs:146:35:146:36 | l1 | main.rs:177:31:177:32 | l1 | provenance | |
| main.rs:148:35:148:36 | l9 | main.rs:148:17:148:33 | ...::alloc | provenance | MaD:3 Sink:MaD:3 |
| main.rs:151:9:151:11 | l10 | main.rs:152:31:152:33 | l10 | provenance | |
| main.rs:151:15:151:69 | ...::array::<...>(...) [Ok] | main.rs:151:15:151:78 | ... .unwrap() | provenance | MaD:31 |
| main.rs:151:15:151:78 | ... .unwrap() | main.rs:151:9:151:11 | l10 | provenance | |
| main.rs:151:48:151:68 | ...::min(...) | main.rs:151:15:151:69 | ...::array::<...>(...) [Ok] | provenance | MaD:18 |
| main.rs:151:62:151:62 | v | main.rs:151:48:151:68 | ...::min(...) | provenance | MaD:34 |
| main.rs:152:31:152:33 | l10 | main.rs:152:13:152:29 | ...::alloc | provenance | MaD:3 Sink:MaD:3 |
| main.rs:154:9:154:11 | l11 | main.rs:155:31:155:33 | l11 | provenance | |
| main.rs:154:15:154:69 | ...::array::<...>(...) [Ok] | main.rs:154:15:154:78 | ... .unwrap() | provenance | MaD:31 |
| main.rs:154:15:154:78 | ... .unwrap() | main.rs:154:9:154:11 | l11 | provenance | |
| main.rs:154:48:154:68 | ...::max(...) | main.rs:154:15:154:69 | ...::array::<...>(...) [Ok] | provenance | MaD:18 |
| main.rs:154:62:154:62 | v | main.rs:154:48:154:68 | ...::max(...) | provenance | MaD:33 |
| main.rs:155:31:155:33 | l11 | main.rs:155:13:155:29 | ...::alloc | provenance | MaD:3 Sink:MaD:3 |
| main.rs:161:13:161:15 | l13 | main.rs:162:35:162:37 | l13 | provenance | |
| main.rs:161:19:161:59 | ...::from_size_align(...) [Ok] | main.rs:161:19:161:68 | ... .unwrap() | provenance | MaD:31 |
| main.rs:161:19:161:68 | ... .unwrap() | main.rs:161:13:161:15 | l13 | provenance | |
| main.rs:161:55:161:55 | v | main.rs:161:19:161:59 | ...::from_size_align(...) [Ok] | provenance | MaD:23 |
| main.rs:162:35:162:37 | l13 | main.rs:162:17:162:33 | ...::alloc | provenance | MaD:3 Sink:MaD:3 |
| main.rs:162:35:162:37 | l13 | main.rs:169:35:169:37 | l13 | provenance | |
| main.rs:169:35:169:37 | l13 | main.rs:169:17:169:33 | ...::alloc | provenance | MaD:3 Sink:MaD:3 |
| main.rs:177:31:177:32 | l1 | main.rs:177:13:177:29 | ...::alloc | provenance | MaD:3 Sink:MaD:3 |
| main.rs:183:29:183:36 | ...: usize | main.rs:192:46:192:46 | v | provenance | |
| main.rs:192:9:192:10 | l2 | main.rs:193:38:193:39 | l2 | provenance | |
| main.rs:192:14:192:47 | ...::array::<...>(...) [Ok] | main.rs:192:14:192:56 | ... .unwrap() | provenance | MaD:31 |
| main.rs:192:14:192:56 | ... .unwrap() | main.rs:192:9:192:10 | l2 | provenance | |
| main.rs:192:46:192:46 | v | main.rs:192:14:192:47 | ...::array::<...>(...) [Ok] | provenance | MaD:18 |
| main.rs:193:38:193:39 | l2 | main.rs:193:32:193:36 | alloc | provenance | MaD:10 Sink:MaD:10 |
| main.rs:193:38:193:39 | l2 | main.rs:194:45:194:46 | l2 | provenance | |
| main.rs:194:45:194:46 | l2 | main.rs:194:32:194:43 | alloc_zeroed | provenance | MaD:11 Sink:MaD:11 |
| main.rs:194:45:194:46 | l2 | main.rs:195:41:195:42 | l2 | provenance | |
| main.rs:195:41:195:42 | l2 | main.rs:195:32:195:39 | allocate | provenance | MaD:6 Sink:MaD:6 |
| main.rs:195:41:195:42 | l2 | main.rs:196:48:196:49 | l2 | provenance | |
| main.rs:196:48:196:49 | l2 | main.rs:196:32:196:46 | allocate_zeroed | provenance | MaD:7 Sink:MaD:7 |
| main.rs:196:48:196:49 | l2 | main.rs:197:41:197:42 | l2 | provenance | |
| main.rs:197:41:197:42 | l2 | main.rs:197:32:197:39 | allocate | provenance | MaD:1 Sink:MaD:1 |
| main.rs:197:41:197:42 | l2 | main.rs:198:48:198:49 | l2 | provenance | |
| main.rs:198:48:198:49 | l2 | main.rs:198:32:198:46 | allocate_zeroed | provenance | MaD:2 Sink:MaD:2 |
| main.rs:198:48:198:49 | l2 | main.rs:208:53:208:54 | l2 | provenance | |
| main.rs:198:48:198:49 | l2 | main.rs:210:60:210:61 | l2 | provenance | |
| main.rs:208:53:208:54 | l2 | main.rs:208:40:208:43 | grow | provenance | MaD:8 Sink:MaD:8 |
| main.rs:210:60:210:61 | l2 | main.rs:210:40:210:50 | grow_zeroed | provenance | MaD:9 Sink:MaD:9 |
| main.rs:217:27:217:34 | ...: usize | main.rs:219:26:219:26 | v | provenance | |
| main.rs:219:26:219:26 | v | main.rs:219:13:219:24 | ...::malloc | provenance | MaD:14 Sink:MaD:14 |
| main.rs:219:26:219:26 | v | main.rs:220:36:220:36 | v | provenance | |
| main.rs:220:36:220:36 | v | main.rs:220:13:220:31 | ...::aligned_alloc | provenance | MaD:12 Sink:MaD:12 |
| main.rs:220:36:220:36 | v | main.rs:222:30:222:30 | v | provenance | |
| main.rs:222:30:222:30 | v | main.rs:222:13:222:24 | ...::calloc | provenance | MaD:13 Sink:MaD:13 |
| main.rs:222:30:222:30 | v | main.rs:223:26:223:26 | v | provenance | |
| main.rs:223:26:223:26 | v | main.rs:223:13:223:24 | ...::calloc | provenance | MaD:13 Sink:MaD:13 |
| main.rs:223:26:223:26 | v | main.rs:224:31:224:31 | v | provenance | |
| main.rs:224:31:224:31 | v | main.rs:224:13:224:25 | ...::realloc | provenance | MaD:15 Sink:MaD:15 |
| main.rs:279:24:279:41 | ...: String | main.rs:280:21:280:47 | user_input.parse() [Ok] | provenance | MaD:32 |
| main.rs:280:9:280:17 | num_bytes | main.rs:282:54:282:62 | num_bytes | provenance | |
| main.rs:280:21:280:47 | user_input.parse() [Ok] | main.rs:280:21:280:48 | TryExpr | provenance | |
| main.rs:280:21:280:48 | TryExpr | main.rs:280:9:280:17 | num_bytes | provenance | |
| main.rs:282:9:282:14 | layout | main.rs:284:40:284:45 | layout | provenance | |
| main.rs:282:18:282:66 | ...::from_size_align(...) [Ok] | main.rs:282:18:282:75 | ... .unwrap() | provenance | MaD:31 |
| main.rs:282:18:282:75 | ... .unwrap() | main.rs:282:9:282:14 | layout | provenance | |
| main.rs:282:54:282:62 | num_bytes | main.rs:282:18:282:66 | ...::from_size_align(...) [Ok] | provenance | MaD:23 |
| main.rs:284:40:284:45 | layout | main.rs:284:22:284:38 | ...::alloc | provenance | MaD:3 Sink:MaD:3 |
| main.rs:308:25:308:38 | ...::args | main.rs:308:25:308:40 | ...::args(...) [element] | provenance | Src:MaD:16 |
| main.rs:308:25:308:40 | ...::args(...) [element] | main.rs:308:25:308:47 | ... .nth(...) [Some] | provenance | MaD:35 |
| main.rs:308:25:308:47 | ... .nth(...) [Some] | main.rs:308:25:308:74 | ... .unwrap_or(...) | provenance | MaD:29 |
| main.rs:308:25:308:74 | ... .unwrap_or(...) | main.rs:279:24:279:41 | ...: String | provenance | |
| main.rs:317:9:317:9 | v | main.rs:320:34:320:34 | v | provenance | |
| main.rs:317:9:317:9 | v | main.rs:321:42:321:42 | v | provenance | |
| main.rs:317:9:317:9 | v | main.rs:322:36:322:36 | v | provenance | |
| main.rs:317:9:317:9 | v | main.rs:323:27:323:27 | v | provenance | |
| main.rs:317:9:317:9 | v | main.rs:324:25:324:25 | v | provenance | |
| main.rs:317:13:317:26 | ...::args | main.rs:317:13:317:28 | ...::args(...) [element] | provenance | Src:MaD:16 |
| main.rs:317:13:317:28 | ...::args(...) [element] | main.rs:317:13:317:35 | ... .nth(...) [Some] | provenance | MaD:35 |
| main.rs:317:13:317:35 | ... .nth(...) [Some] | main.rs:317:13:317:65 | ... .unwrap_or(...) | provenance | MaD:29 |
| main.rs:317:13:317:65 | ... .unwrap_or(...) | main.rs:317:13:317:82 | ... .parse() [Ok] | provenance | MaD:32 |
| main.rs:317:13:317:82 | ... .parse() [Ok] | main.rs:317:13:317:91 | ... .unwrap() | provenance | MaD:31 |
| main.rs:317:13:317:91 | ... .unwrap() | main.rs:317:9:317:9 | v | provenance | |
| main.rs:320:34:320:34 | v | main.rs:12:36:12:43 | ...: usize | provenance | |
| main.rs:321:42:321:42 | v | main.rs:43:44:43:51 | ...: usize | provenance | |
| main.rs:322:36:322:36 | v | main.rs:91:38:91:45 | ...: usize | provenance | |
| main.rs:323:27:323:27 | v | main.rs:183:29:183:36 | ...: usize | provenance | |
| main.rs:324:25:324:25 | v | main.rs:217:27:217:34 | ...: usize | provenance | |
models
| 1 | Sink: lang:alloc; <crate::alloc::Global as crate::alloc::Allocator>::allocate; alloc-layout; Argument[0] |
| 2 | Sink: lang:alloc; <crate::alloc::Global as crate::alloc::Allocator>::allocate_zeroed; alloc-layout; Argument[0] |
| 3 | Sink: lang:alloc; crate::alloc::alloc; alloc-layout; Argument[0] |
| 4 | Sink: lang:alloc; crate::alloc::alloc_zeroed; alloc-layout; Argument[0] |
| 5 | Sink: lang:alloc; crate::alloc::realloc; alloc-size; Argument[2] |
| 6 | Sink: lang:std; <crate::alloc::System as crate::alloc::Allocator>::allocate; alloc-layout; Argument[0] |
| 7 | Sink: lang:std; <crate::alloc::System as crate::alloc::Allocator>::allocate_zeroed; alloc-layout; Argument[0] |
| 8 | Sink: lang:std; <crate::alloc::System as crate::alloc::Allocator>::grow; alloc-layout; Argument[2] |
| 9 | Sink: lang:std; <crate::alloc::System as crate::alloc::Allocator>::grow_zeroed; alloc-layout; Argument[2] |
| 10 | Sink: lang:std; <crate::alloc::System as crate::alloc::global::GlobalAlloc>::alloc; alloc-layout; Argument[0] |
| 11 | Sink: lang:std; <crate::alloc::System as crate::alloc::global::GlobalAlloc>::alloc_zeroed; alloc-layout; Argument[0] |
| 12 | Sink: repo:https://github.com/rust-lang/libc:libc; ::aligned_alloc; alloc-size; Argument[1] |
| 13 | Sink: repo:https://github.com/rust-lang/libc:libc; ::calloc; alloc-size; Argument[0,1] |
| 14 | Sink: repo:https://github.com/rust-lang/libc:libc; ::malloc; alloc-size; Argument[0] |
| 15 | Sink: repo:https://github.com/rust-lang/libc:libc; ::realloc; alloc-size; Argument[1] |
| 16 | Source: lang:std; crate::env::args; command-line-source; ReturnValue.Element |
| 17 | Summary: lang:core; <crate::alloc::layout::Layout>::align_to; Argument[self]; ReturnValue.Field[crate::result::Result::Ok(0)]; taint |
| 18 | Summary: lang:core; <crate::alloc::layout::Layout>::array; Argument[0]; ReturnValue.Field[crate::result::Result::Ok(0)]; taint |
| 19 | Summary: lang:core; <crate::alloc::layout::Layout>::extend; Argument[0]; ReturnValue.Field[crate::result::Result::Ok(0)].Field[0]; taint |
| 20 | Summary: lang:core; <crate::alloc::layout::Layout>::extend; Argument[self]; ReturnValue.Field[crate::result::Result::Ok(0)].Field[0]; taint |
| 21 | Summary: lang:core; <crate::alloc::layout::Layout>::extend_packed; Argument[0]; ReturnValue.Field[crate::result::Result::Ok(0)]; taint |
| 22 | Summary: lang:core; <crate::alloc::layout::Layout>::extend_packed; Argument[self]; ReturnValue.Field[crate::result::Result::Ok(0)]; taint |
| 23 | Summary: lang:core; <crate::alloc::layout::Layout>::from_size_align; Argument[0]; ReturnValue.Field[crate::result::Result::Ok(0)]; taint |
| 24 | Summary: lang:core; <crate::alloc::layout::Layout>::from_size_align_unchecked; Argument[0]; ReturnValue; taint |
| 25 | Summary: lang:core; <crate::alloc::layout::Layout>::pad_to_align; Argument[self]; ReturnValue; taint |
| 26 | Summary: lang:core; <crate::alloc::layout::Layout>::repeat; Argument[0]; ReturnValue.Field[crate::result::Result::Ok(0)].Field[0]; taint |
| 27 | Summary: lang:core; <crate::alloc::layout::Layout>::repeat_packed; Argument[0]; ReturnValue.Field[crate::result::Result::Ok(0)]; taint |
| 28 | Summary: lang:core; <crate::alloc::layout::Layout>::size; Argument[self]; ReturnValue; taint |
| 29 | Summary: lang:core; <crate::option::Option>::unwrap_or; Argument[self].Field[crate::option::Option::Some(0)]; ReturnValue; value |
| 30 | Summary: lang:core; <crate::result::Result>::expect; Argument[self].Field[crate::result::Result::Ok(0)]; ReturnValue; value |
| 31 | Summary: lang:core; <crate::result::Result>::unwrap; Argument[self].Field[crate::result::Result::Ok(0)]; ReturnValue; value |
| 32 | Summary: lang:core; <str>::parse; Argument[self]; ReturnValue.Field[crate::result::Result::Ok(0)]; taint |
| 33 | Summary: lang:core; crate::cmp::max; Argument[0]; ReturnValue; value |
| 34 | Summary: lang:core; crate::cmp::min; Argument[0]; ReturnValue; value |
| 35 | Summary: lang:core; crate::iter::traits::iterator::Iterator::nth; Argument[self].Element; ReturnValue.Field[crate::option::Option::Some(0)]; value |
nodes
| main.rs:12:36:12:43 | ...: usize | semmle.label | ...: usize |
| main.rs:18:13:18:31 | ...::realloc | semmle.label | ...::realloc |
| main.rs:18:41:18:41 | v | semmle.label | v |
| main.rs:20:9:20:10 | l2 | semmle.label | l2 |
| main.rs:20:14:20:54 | ...::from_size_align(...) [Ok] | semmle.label | ...::from_size_align(...) [Ok] |
| main.rs:20:14:20:63 | ... .unwrap() | semmle.label | ... .unwrap() |
| main.rs:20:50:20:50 | v | semmle.label | v |
| main.rs:21:13:21:29 | ...::alloc | semmle.label | ...::alloc |
| main.rs:21:31:21:32 | l2 | semmle.label | l2 |
| main.rs:22:13:22:29 | ...::alloc | semmle.label | ...::alloc |
| main.rs:22:31:22:44 | l2.align_to(...) [Ok] | semmle.label | l2.align_to(...) [Ok] |
| main.rs:22:31:22:53 | ... .unwrap() | semmle.label | ... .unwrap() |
| main.rs:23:13:23:29 | ...::alloc | semmle.label | ...::alloc |
| main.rs:23:31:23:44 | l2.align_to(...) [Ok] | semmle.label | l2.align_to(...) [Ok] |
| main.rs:23:31:23:53 | ... .unwrap() | semmle.label | ... .unwrap() |
| main.rs:23:31:23:68 | ... .pad_to_align() | semmle.label | ... .pad_to_align() |
| main.rs:24:13:24:36 | ...::alloc_zeroed | semmle.label | ...::alloc_zeroed |
| main.rs:24:38:24:39 | l2 | semmle.label | l2 |
| main.rs:29:9:29:10 | l4 | semmle.label | l4 |
| main.rs:29:14:29:64 | ...::from_size_align_unchecked(...) | semmle.label | ...::from_size_align_unchecked(...) |
| main.rs:29:60:29:60 | v | semmle.label | v |
| main.rs:30:13:30:29 | ...::alloc | semmle.label | ...::alloc |
| main.rs:30:31:30:32 | l4 | semmle.label | l4 |
| main.rs:32:9:32:10 | l5 | semmle.label | l5 |
| main.rs:32:14:32:118 | ...::from_size_align_unchecked(...) | semmle.label | ...::from_size_align_unchecked(...) |
| main.rs:32:60:32:89 | ... * ... | semmle.label | ... * ... |
| main.rs:33:13:33:29 | ...::alloc | semmle.label | ...::alloc |
| main.rs:33:31:33:32 | l5 | semmle.label | l5 |
| main.rs:35:9:35:10 | s6 | semmle.label | s6 |
| main.rs:36:9:36:10 | l6 | semmle.label | l6 |
| main.rs:36:14:36:65 | ...::from_size_align_unchecked(...) | semmle.label | ...::from_size_align_unchecked(...) |
| main.rs:36:60:36:61 | s6 | semmle.label | s6 |
| main.rs:37:13:37:29 | ...::alloc | semmle.label | ...::alloc |
| main.rs:37:31:37:32 | l6 | semmle.label | l6 |
| main.rs:39:9:39:10 | l7 | semmle.label | l7 |
| main.rs:39:14:39:72 | ...::from_size_align_unchecked(...) | semmle.label | ...::from_size_align_unchecked(...) |
| main.rs:39:60:39:68 | l6.size() | semmle.label | l6.size() |
| main.rs:40:13:40:29 | ...::alloc | semmle.label | ...::alloc |
| main.rs:40:31:40:32 | l7 | semmle.label | l7 |
| main.rs:43:44:43:51 | ...: usize | semmle.label | ...: usize |
| main.rs:50:13:50:29 | ...::alloc | semmle.label | ...::alloc |
| main.rs:50:31:50:42 | l2.repeat(...) [Ok, tuple.0] | semmle.label | l2.repeat(...) [Ok, tuple.0] |
| main.rs:50:31:50:51 | ... .unwrap() [tuple.0] | semmle.label | ... .unwrap() [tuple.0] |
| main.rs:50:31:50:53 | ... .0 | semmle.label | ... .0 |
| main.rs:50:41:50:41 | v | semmle.label | v |
| main.rs:51:13:51:29 | ...::alloc | semmle.label | ...::alloc |
| main.rs:51:31:51:46 | l2.repeat(...) [Ok, tuple.0] | semmle.label | l2.repeat(...) [Ok, tuple.0] |
| main.rs:51:31:51:55 | ... .unwrap() [tuple.0] | semmle.label | ... .unwrap() [tuple.0] |
| main.rs:51:31:51:57 | ... .0 | semmle.label | ... .0 |
| main.rs:51:41:51:45 | ... + ... | semmle.label | ... + ... |
| main.rs:53:13:53:29 | ...::alloc | semmle.label | ...::alloc |
| main.rs:53:31:53:49 | l2.repeat_packed(...) [Ok] | semmle.label | l2.repeat_packed(...) [Ok] |
| main.rs:53:31:53:58 | ... .unwrap() | semmle.label | ... .unwrap() |
| main.rs:53:48:53:48 | v | semmle.label | v |
| main.rs:54:13:54:29 | ...::alloc | semmle.label | ...::alloc |
| main.rs:54:31:54:54 | l2.repeat_packed(...) [Ok] | semmle.label | l2.repeat_packed(...) [Ok] |
| main.rs:54:31:54:63 | ... .unwrap() | semmle.label | ... .unwrap() |
| main.rs:54:48:54:53 | ... * ... | semmle.label | ... * ... |
| main.rs:58:9:58:20 | TuplePat [tuple.0] | semmle.label | TuplePat [tuple.0] |
| main.rs:58:10:58:11 | k1 | semmle.label | k1 |
| main.rs:58:24:58:35 | l3.repeat(...) [Ok, tuple.0] | semmle.label | l3.repeat(...) [Ok, tuple.0] |
| main.rs:58:24:58:66 | ... .expect(...) [tuple.0] | semmle.label | ... .expect(...) [tuple.0] |
| main.rs:58:34:58:34 | v | semmle.label | v |
| main.rs:59:13:59:29 | ...::alloc | semmle.label | ...::alloc |
| main.rs:59:31:59:32 | k1 | semmle.label | k1 |
| main.rs:60:9:60:20 | TuplePat [tuple.0] | semmle.label | TuplePat [tuple.0] |
| main.rs:60:10:60:11 | k2 | semmle.label | k2 |
| main.rs:60:24:60:36 | l3.extend(...) [Ok, tuple.0] | semmle.label | l3.extend(...) [Ok, tuple.0] |
| main.rs:60:24:60:45 | ... .unwrap() [tuple.0] | semmle.label | ... .unwrap() [tuple.0] |
| main.rs:60:34:60:35 | k1 | semmle.label | k1 |
| main.rs:61:13:61:29 | ...::alloc | semmle.label | ...::alloc |
| main.rs:61:31:61:32 | k2 | semmle.label | k2 |
| main.rs:62:9:62:20 | TuplePat [tuple.0] | semmle.label | TuplePat [tuple.0] |
| main.rs:62:10:62:11 | k3 | semmle.label | k3 |
| main.rs:62:24:62:36 | k1.extend(...) [Ok, tuple.0] | semmle.label | k1.extend(...) [Ok, tuple.0] |
| main.rs:62:24:62:45 | ... .unwrap() [tuple.0] | semmle.label | ... .unwrap() [tuple.0] |
| main.rs:63:13:63:29 | ...::alloc | semmle.label | ...::alloc |
| main.rs:63:31:63:32 | k3 | semmle.label | k3 |
| main.rs:64:13:64:29 | ...::alloc | semmle.label | ...::alloc |
| main.rs:64:31:64:50 | l3.extend_packed(...) [Ok] | semmle.label | l3.extend_packed(...) [Ok] |
| main.rs:64:31:64:59 | ... .unwrap() | semmle.label | ... .unwrap() |
| main.rs:64:48:64:49 | k1 | semmle.label | k1 |
| main.rs:65:13:65:29 | ...::alloc | semmle.label | ...::alloc |
| main.rs:65:31:65:50 | k1.extend_packed(...) [Ok] | semmle.label | k1.extend_packed(...) [Ok] |
| main.rs:65:31:65:59 | ... .unwrap() | semmle.label | ... .unwrap() |
| main.rs:67:9:67:10 | l4 | semmle.label | l4 |
| main.rs:67:14:67:47 | ...::array::<...>(...) [Ok] | semmle.label | ...::array::<...>(...) [Ok] |
| main.rs:67:14:67:56 | ... .unwrap() | semmle.label | ... .unwrap() |
| main.rs:67:46:67:46 | v | semmle.label | v |
| main.rs:68:13:68:29 | ...::alloc | semmle.label | ...::alloc |
| main.rs:68:31:68:32 | l4 | semmle.label | l4 |
| main.rs:86:35:86:42 | ...: usize | semmle.label | ...: usize |
| main.rs:87:9:87:14 | layout | semmle.label | layout |
| main.rs:87:18:87:58 | ...::from_size_align(...) [Ok] | semmle.label | ...::from_size_align(...) [Ok] |
| main.rs:87:18:87:67 | ... .unwrap() | semmle.label | ... .unwrap() |
| main.rs:87:54:87:54 | v | semmle.label | v |
| main.rs:88:13:88:29 | ...::alloc | semmle.label | ...::alloc |
| main.rs:88:31:88:36 | layout | semmle.label | layout |
| main.rs:91:38:91:45 | ...: usize | semmle.label | ...: usize |
| main.rs:92:9:92:10 | l1 | semmle.label | l1 |
| main.rs:92:14:92:48 | ...::array::<...>(...) [Ok] | semmle.label | ...::array::<...>(...) [Ok] |
| main.rs:92:14:92:57 | ... .unwrap() | semmle.label | ... .unwrap() |
| main.rs:92:47:92:47 | v | semmle.label | v |
| main.rs:96:17:96:33 | ...::alloc | semmle.label | ...::alloc |
| main.rs:96:35:96:36 | l1 | semmle.label | l1 |
| main.rs:101:13:101:14 | l3 | semmle.label | l3 |
| main.rs:101:18:101:52 | ...::array::<...>(...) [Ok] | semmle.label | ...::array::<...>(...) [Ok] |
| main.rs:101:18:101:61 | ... .unwrap() | semmle.label | ... .unwrap() |
| main.rs:101:51:101:51 | v | semmle.label | v |
| main.rs:102:17:102:33 | ...::alloc | semmle.label | ...::alloc |
| main.rs:102:35:102:36 | l1 | semmle.label | l1 |
| main.rs:103:17:103:33 | ...::alloc | semmle.label | ...::alloc |
| main.rs:103:35:103:36 | l3 | semmle.label | l3 |
| main.rs:105:33:105:33 | v | semmle.label | v |
| main.rs:109:17:109:33 | ...::alloc | semmle.label | ...::alloc |
| main.rs:109:35:109:36 | l1 | semmle.label | l1 |
| main.rs:111:17:111:33 | ...::alloc | semmle.label | ...::alloc |
| main.rs:111:35:111:36 | l1 | semmle.label | l1 |
| main.rs:145:13:145:14 | l9 | semmle.label | l9 |
| main.rs:145:18:145:52 | ...::array::<...>(...) [Ok] | semmle.label | ...::array::<...>(...) [Ok] |
| main.rs:145:18:145:61 | ... .unwrap() | semmle.label | ... .unwrap() |
| main.rs:145:51:145:51 | v | semmle.label | v |
| main.rs:146:17:146:33 | ...::alloc | semmle.label | ...::alloc |
| main.rs:146:35:146:36 | l1 | semmle.label | l1 |
| main.rs:148:17:148:33 | ...::alloc | semmle.label | ...::alloc |
| main.rs:148:35:148:36 | l9 | semmle.label | l9 |
| main.rs:151:9:151:11 | l10 | semmle.label | l10 |
| main.rs:151:15:151:69 | ...::array::<...>(...) [Ok] | semmle.label | ...::array::<...>(...) [Ok] |
| main.rs:151:15:151:78 | ... .unwrap() | semmle.label | ... .unwrap() |
| main.rs:151:48:151:68 | ...::min(...) | semmle.label | ...::min(...) |
| main.rs:151:62:151:62 | v | semmle.label | v |
| main.rs:152:13:152:29 | ...::alloc | semmle.label | ...::alloc |
| main.rs:152:31:152:33 | l10 | semmle.label | l10 |
| main.rs:154:9:154:11 | l11 | semmle.label | l11 |
| main.rs:154:15:154:69 | ...::array::<...>(...) [Ok] | semmle.label | ...::array::<...>(...) [Ok] |
| main.rs:154:15:154:78 | ... .unwrap() | semmle.label | ... .unwrap() |
| main.rs:154:48:154:68 | ...::max(...) | semmle.label | ...::max(...) |
| main.rs:154:62:154:62 | v | semmle.label | v |
| main.rs:155:13:155:29 | ...::alloc | semmle.label | ...::alloc |
| main.rs:155:31:155:33 | l11 | semmle.label | l11 |
| main.rs:161:13:161:15 | l13 | semmle.label | l13 |
| main.rs:161:19:161:59 | ...::from_size_align(...) [Ok] | semmle.label | ...::from_size_align(...) [Ok] |
| main.rs:161:19:161:68 | ... .unwrap() | semmle.label | ... .unwrap() |
| main.rs:161:55:161:55 | v | semmle.label | v |
| main.rs:162:17:162:33 | ...::alloc | semmle.label | ...::alloc |
| main.rs:162:35:162:37 | l13 | semmle.label | l13 |
| main.rs:169:17:169:33 | ...::alloc | semmle.label | ...::alloc |
| main.rs:169:35:169:37 | l13 | semmle.label | l13 |
| main.rs:177:13:177:29 | ...::alloc | semmle.label | ...::alloc |
| main.rs:177:31:177:32 | l1 | semmle.label | l1 |
| main.rs:183:29:183:36 | ...: usize | semmle.label | ...: usize |
| main.rs:192:9:192:10 | l2 | semmle.label | l2 |
| main.rs:192:14:192:47 | ...::array::<...>(...) [Ok] | semmle.label | ...::array::<...>(...) [Ok] |
| main.rs:192:14:192:56 | ... .unwrap() | semmle.label | ... .unwrap() |
| main.rs:192:46:192:46 | v | semmle.label | v |
| main.rs:193:32:193:36 | alloc | semmle.label | alloc |
| main.rs:193:38:193:39 | l2 | semmle.label | l2 |
| main.rs:194:32:194:43 | alloc_zeroed | semmle.label | alloc_zeroed |
| main.rs:194:45:194:46 | l2 | semmle.label | l2 |
| main.rs:195:32:195:39 | allocate | semmle.label | allocate |
| main.rs:195:41:195:42 | l2 | semmle.label | l2 |
| main.rs:196:32:196:46 | allocate_zeroed | semmle.label | allocate_zeroed |
| main.rs:196:48:196:49 | l2 | semmle.label | l2 |
| main.rs:197:32:197:39 | allocate | semmle.label | allocate |
| main.rs:197:41:197:42 | l2 | semmle.label | l2 |
| main.rs:198:32:198:46 | allocate_zeroed | semmle.label | allocate_zeroed |
| main.rs:198:48:198:49 | l2 | semmle.label | l2 |
| main.rs:208:40:208:43 | grow | semmle.label | grow |
| main.rs:208:53:208:54 | l2 | semmle.label | l2 |
| main.rs:210:40:210:50 | grow_zeroed | semmle.label | grow_zeroed |
| main.rs:210:60:210:61 | l2 | semmle.label | l2 |
| main.rs:217:27:217:34 | ...: usize | semmle.label | ...: usize |
| main.rs:219:13:219:24 | ...::malloc | semmle.label | ...::malloc |
| main.rs:219:26:219:26 | v | semmle.label | v |
| main.rs:220:13:220:31 | ...::aligned_alloc | semmle.label | ...::aligned_alloc |
| main.rs:220:36:220:36 | v | semmle.label | v |
| main.rs:222:13:222:24 | ...::calloc | semmle.label | ...::calloc |
| main.rs:222:30:222:30 | v | semmle.label | v |
| main.rs:223:13:223:24 | ...::calloc | semmle.label | ...::calloc |
| main.rs:223:26:223:26 | v | semmle.label | v |
| main.rs:224:13:224:25 | ...::realloc | semmle.label | ...::realloc |
| main.rs:224:31:224:31 | v | semmle.label | v |
| main.rs:279:24:279:41 | ...: String | semmle.label | ...: String |
| main.rs:280:9:280:17 | num_bytes | semmle.label | num_bytes |
| main.rs:280:21:280:47 | user_input.parse() [Ok] | semmle.label | user_input.parse() [Ok] |
| main.rs:280:21:280:48 | TryExpr | semmle.label | TryExpr |
| main.rs:282:9:282:14 | layout | semmle.label | layout |
| main.rs:282:18:282:66 | ...::from_size_align(...) [Ok] | semmle.label | ...::from_size_align(...) [Ok] |
| main.rs:282:18:282:75 | ... .unwrap() | semmle.label | ... .unwrap() |
| main.rs:282:54:282:62 | num_bytes | semmle.label | num_bytes |
| main.rs:284:22:284:38 | ...::alloc | semmle.label | ...::alloc |
| main.rs:284:40:284:45 | layout | semmle.label | layout |
| main.rs:308:25:308:38 | ...::args | semmle.label | ...::args |
| main.rs:308:25:308:40 | ...::args(...) [element] | semmle.label | ...::args(...) [element] |
| main.rs:308:25:308:47 | ... .nth(...) [Some] | semmle.label | ... .nth(...) [Some] |
| main.rs:308:25:308:74 | ... .unwrap_or(...) | semmle.label | ... .unwrap_or(...) |
| main.rs:317:9:317:9 | v | semmle.label | v |
| main.rs:317:13:317:26 | ...::args | semmle.label | ...::args |
| main.rs:317:13:317:28 | ...::args(...) [element] | semmle.label | ...::args(...) [element] |
| main.rs:317:13:317:35 | ... .nth(...) [Some] | semmle.label | ... .nth(...) [Some] |
| main.rs:317:13:317:65 | ... .unwrap_or(...) | semmle.label | ... .unwrap_or(...) |
| main.rs:317:13:317:82 | ... .parse() [Ok] | semmle.label | ... .parse() [Ok] |
| main.rs:317:13:317:91 | ... .unwrap() | semmle.label | ... .unwrap() |
| main.rs:320:34:320:34 | v | semmle.label | v |
| main.rs:321:42:321:42 | v | semmle.label | v |
| main.rs:322:36:322:36 | v | semmle.label | v |
| main.rs:323:27:323:27 | v | semmle.label | v |
| main.rs:324:25:324:25 | v | semmle.label | v |
subpaths

View File

@@ -0,0 +1,4 @@
query: queries/security/CWE-770/UncontrolledAllocationSize.ql
postprocess:
- utils/test/InlineExpectationsTestQuery.ql
- utils/test/PrettyPrintModels.ql

View File

@@ -0,0 +1,330 @@
#![feature(alloc_layout_extra)]
#![feature(allocator_api)]
#![feature(try_with_capacity)]
#![feature(box_vec_non_null)]
#![feature(non_null_from_ref)]
struct MyStruct {
_a: usize,
_b: i64,
}
unsafe fn test_std_alloc_from_size(v: usize) {
let l1 = std::alloc::Layout::from_size_align(16, 1).unwrap();
let m1 = std::alloc::alloc(l1);
let _ = std::alloc::alloc(l1.align_to(8).unwrap());
let _ = std::alloc::alloc(l1.align_to(8).unwrap().pad_to_align());
let _ = std::alloc::alloc_zeroed(l1);
let _ = std::alloc::realloc(m1, l1, v); // $ Alert[rust/uncontrolled-allocation-size]=arg1
let l2 = std::alloc::Layout::from_size_align(v, 1).unwrap();
let _ = std::alloc::alloc(l2); // $ Alert[rust/uncontrolled-allocation-size]=arg1
let _ = std::alloc::alloc(l2.align_to(8).unwrap()); // $ Alert[rust/uncontrolled-allocation-size]=arg1
let _ = std::alloc::alloc(l2.align_to(8).unwrap().pad_to_align()); // $ Alert[rust/uncontrolled-allocation-size]=arg1
let _ = std::alloc::alloc_zeroed(l2); // $ Alert[rust/uncontrolled-allocation-size]=arg1
let l3 = std::alloc::Layout::from_size_align(1, v).unwrap(); // not obviously dangerous?
let _ = std::alloc::alloc(l3);
let l4 = std::alloc::Layout::from_size_align_unchecked(v, 1);
let _ = std::alloc::alloc(l4); // $ Alert[rust/uncontrolled-allocation-size]=arg1
let l5 = std::alloc::Layout::from_size_align_unchecked(v * std::mem::size_of::<i64>(), std::mem::size_of::<i64>());
let _ = std::alloc::alloc(l5); // $ Alert[rust/uncontrolled-allocation-size]=arg1
let s6 = (std::mem::size_of::<MyStruct>() * v) + 1;
let l6 = std::alloc::Layout::from_size_align_unchecked(s6, 4);
let _ = std::alloc::alloc(l6); // $ Alert[rust/uncontrolled-allocation-size]=arg1
let l7 = std::alloc::Layout::from_size_align_unchecked(l6.size(), 8);
let _ = std::alloc::alloc(l7); // $ Alert[rust/uncontrolled-allocation-size]=arg1
}
unsafe fn test_std_alloc_new_repeat_extend(v: usize) {
let l1 = std::alloc::Layout::new::<[u8; 10]>();
let _ = std::alloc::alloc(l1);
let l2 = std::alloc::Layout::new::<MyStruct>();
let _ = std::alloc::alloc(l2);
let _ = std::alloc::alloc(l2.repeat(10).unwrap().0);
let _ = std::alloc::alloc(l2.repeat(v).unwrap().0); // $ Alert[rust/uncontrolled-allocation-size]=arg1
let _ = std::alloc::alloc(l2.repeat(v + 1).unwrap().0); // $ Alert[rust/uncontrolled-allocation-size]=arg1
let _ = std::alloc::alloc(l2.repeat_packed(10).unwrap());
let _ = std::alloc::alloc(l2.repeat_packed(v).unwrap()); // $ Alert[rust/uncontrolled-allocation-size]=arg1
let _ = std::alloc::alloc(l2.repeat_packed(v * 10).unwrap()); // $ Alert[rust/uncontrolled-allocation-size]=arg1
let l3 = std::alloc::Layout::array::<u8>(10).unwrap();
let _ = std::alloc::alloc(l3);
let (k1, _offs1) = l3.repeat(v).expect("arithmetic overflow?");
let _ = std::alloc::alloc(k1); // $ Alert[rust/uncontrolled-allocation-size]=arg1
let (k2, _offs2) = l3.extend(k1).unwrap();
let _ = std::alloc::alloc(k2); // $ Alert[rust/uncontrolled-allocation-size]=arg1
let (k3, _offs3) = k1.extend(l3).unwrap();
let _ = std::alloc::alloc(k3); // $ Alert[rust/uncontrolled-allocation-size]=arg1
let _ = std::alloc::alloc(l3.extend_packed(k1).unwrap()); // $ Alert[rust/uncontrolled-allocation-size]=arg1
let _ = std::alloc::alloc(k1.extend_packed(l3).unwrap()); // $ Alert[rust/uncontrolled-allocation-size]=arg1
let l4 = std::alloc::Layout::array::<u8>(v).unwrap();
let _ = std::alloc::alloc(l4); // $ Alert[rust/uncontrolled-allocation-size]=arg1
}
fn clamp<T: std::cmp::PartialOrd>(v: T, min: T, max: T) -> T {
if v < min {
return min;
} else if v > max {
return max;
} else {
return v;
}
}
unsafe fn test_fn_alloc_bounded(v: usize) {
let layout = std::alloc::Layout::from_size_align(v, 1).unwrap();
let _ = std::alloc::alloc(layout); // $ GOOD (bounded)
}
unsafe fn test_fn_alloc_unbounded(v: usize) {
let layout = std::alloc::Layout::from_size_align(v, 1).unwrap();
let _ = std::alloc::alloc(layout); // $ Alert[rust/uncontrolled-allocation-size]=arg1
}
unsafe fn test_std_alloc_with_bounds(v: usize, limit: usize) {
let l1 = std::alloc::Layout::array::<u32>(v).unwrap();
if v < 100 {
let l2 = std::alloc::Layout::array::<u32>(v).unwrap();
let _ = std::alloc::alloc(l1); // $ SPURIOUS: Alert[rust/uncontrolled-allocation-size]=arg1
let _ = std::alloc::alloc(l2); // $ GOOD (bounded)
test_fn_alloc_bounded(v);
} else {
let l3 = std::alloc::Layout::array::<u32>(v).unwrap();
let _ = std::alloc::alloc(l1); // $ Alert[rust/uncontrolled-allocation-size]=arg1
let _ = std::alloc::alloc(l3); // $ Alert[rust/uncontrolled-allocation-size]=arg1
test_fn_alloc_unbounded(v);
}
if v == 100 {
let _ = std::alloc::alloc(l1); // $ SPURIOUS: Alert[rust/uncontrolled-allocation-size]=arg1
} else {
let _ = std::alloc::alloc(l1); // $ Alert[rust/uncontrolled-allocation-size]=arg1
}
if (v < limit) {
let l4 = std::alloc::Layout::from_size_align(v, 1).unwrap();
let _ = std::alloc::alloc(l4); // $ GOOD (bounded)
}
if (v < 2 * v) { // not a good bound
let l5 = std::alloc::Layout::from_size_align(v, 1).unwrap();
let _ = std::alloc::alloc(l5); // $ MISSING: Alert[rust/uncontrolled-allocation-size]=arg1
}
if (true && v < limit && true) {
let l6 = std::alloc::Layout::from_size_align(v, 1).unwrap();
let _ = std::alloc::alloc(l6); // $ GOOD (bounded)
}
let mut l7;
if (v < 100) {
l7 = std::alloc::Layout::from_size_align(v, 1).unwrap();
} else {
l7 = std::alloc::Layout::from_size_align(100, 1).unwrap();
}
let _ = std::alloc::alloc(l7); // $ GOOD (bounded)
{
let mut v_mut = v;
if v_mut > 100 {
v_mut = 100;
}
let l8 = std::alloc::Layout::array::<u32>(v_mut).unwrap();
let l9 = std::alloc::Layout::array::<u32>(v).unwrap();
let _ = std::alloc::alloc(l1); // $ Alert[rust/uncontrolled-allocation-size]=arg1
let _ = std::alloc::alloc(l8); // $ GOOD (bounded)
let _ = std::alloc::alloc(l9); // $ Alert[rust/uncontrolled-allocation-size]=arg1
}
let l10 = std::alloc::Layout::array::<u32>(std::cmp::min(v, 100)).unwrap();
let _ = std::alloc::alloc(l10); // $ SPURIOUS: Alert[rust/uncontrolled-allocation-size]=arg1
let l11 = std::alloc::Layout::array::<u32>(std::cmp::max(v, 100)).unwrap();
let _ = std::alloc::alloc(l11); // $ Alert[rust/uncontrolled-allocation-size]=arg1
let l12 = std::alloc::Layout::array::<u32>(clamp(v, 1, 100)).unwrap();
let _ = std::alloc::alloc(l12); // $ GOOD (bounded)
for i in 0..10 {
let l13 = std::alloc::Layout::from_size_align(v, 1).unwrap();
let _ = std::alloc::alloc(l13); // $ Alert[rust/uncontrolled-allocation-size]=arg1
if (v > 1000) {
continue;
}
let l14 = std::alloc::Layout::from_size_align(v, 1).unwrap();
let _ = std::alloc::alloc(l13); // $ SPURIOUS: Alert[rust/uncontrolled-allocation-size]=arg1
let _ = std::alloc::alloc(l14); // $ GOOD (bounded)
}
if v > 100 {
return;
}
let l15 = std::alloc::Layout::from_size_align(v, 1).unwrap();
let _ = std::alloc::alloc(l1); // $ SPURIOUS: Alert[rust/uncontrolled-allocation-size]=arg1
let _ = std::alloc::alloc(l15); // $ GOOD (bounded)
}
use std::alloc::{GlobalAlloc, Allocator};
unsafe fn test_system_alloc(v: usize) {
let l1 = std::alloc::Layout::array::<u8>(10).unwrap();
let _ = std::alloc::System.alloc(l1);
let _ = std::alloc::System.alloc_zeroed(l1);
let _ = std::alloc::System.allocate(l1).unwrap();
let _ = std::alloc::System.allocate_zeroed(l1).unwrap();
let _ = std::alloc::Global.allocate(l1).unwrap();
let _ = std::alloc::Global.allocate_zeroed(l1).unwrap();
let l2 = std::alloc::Layout::array::<u8>(v).unwrap();
let _ = std::alloc::System.alloc(l2); // $ Alert[rust/uncontrolled-allocation-size]=arg1
let _ = std::alloc::System.alloc_zeroed(l2); // $ Alert[rust/uncontrolled-allocation-size]=arg1
let _ = std::alloc::System.allocate(l2).unwrap(); // $ Alert[rust/uncontrolled-allocation-size]=arg1
let _ = std::alloc::System.allocate_zeroed(l2).unwrap(); // $ Alert[rust/uncontrolled-allocation-size]=arg1
let _ = std::alloc::Global.allocate(l2).unwrap(); // $ Alert[rust/uncontrolled-allocation-size]=arg1
let _ = std::alloc::Global.allocate_zeroed(l2).unwrap(); // $ Alert[rust/uncontrolled-allocation-size]=arg1
let l3 = std::alloc::Layout::array::<u8>(10).unwrap();
let m3 = std::alloc::System.alloc(l3);
let _ = std::alloc::System.realloc(m3, l3, v); // $ MISSING: Alert[rust/uncontrolled-allocation-size]
let l4 = std::alloc::Layout::array::<u8>(10).unwrap();
let m4 = std::ptr::NonNull::<u8>::new(std::alloc::alloc(l4)).unwrap();
if v > 10 {
if v % 2 == 0 {
let _ = std::alloc::System.grow(m4, l4, l2).unwrap(); // $ Alert[rust/uncontrolled-allocation-size]=arg1
} else {
let _ = std::alloc::System.grow_zeroed(m4, l4, l2).unwrap(); // $ Alert[rust/uncontrolled-allocation-size]=arg1
}
} else {
let _ = std::alloc::System.shrink(m4, l4, l2).unwrap();
}
}
unsafe fn test_libc_alloc(v: usize) {
let m1 = libc::malloc(256);
let _ = libc::malloc(v); // $ Alert[rust/uncontrolled-allocation-size]=arg1
let _ = libc::aligned_alloc(8, v); // $ Alert[rust/uncontrolled-allocation-size]=arg1
let _ = libc::aligned_alloc(v, 8);
let _ = libc::calloc(64, v); // $ Alert[rust/uncontrolled-allocation-size]=arg1
let _ = libc::calloc(v, std::mem::size_of::<i64>()); // $ Alert[rust/uncontrolled-allocation-size]=arg1
let _ = libc::realloc(m1, v); // $ Alert[rust/uncontrolled-allocation-size]=arg1
}
unsafe fn test_vectors(v: usize) {
let _ = Vec::<u64>::try_with_capacity(v).unwrap(); // $ MISSING: Alert[rust/uncontrolled-allocation-size]
let _ = Vec::<u64>::with_capacity(v); // $ MISSING: Alert[rust/uncontrolled-allocation-size]
let _ = Vec::<u64>::try_with_capacity_in(v, std::alloc::Global).unwrap(); // $ MISSING: Alert[rust/uncontrolled-allocation-size]
let _ = Vec::<u64>::with_capacity_in(v, std::alloc::Global); // $ MISSING: Alert[rust/uncontrolled-allocation-size]
let mut v1 = Vec::<u64>::with_capacity(100);
v1.reserve(v); // $ MISSING: Alert[rust/uncontrolled-allocation-size]
v1.reserve_exact(v); // $ MISSING: Alert[rust/uncontrolled-allocation-size]
let _ = v1.try_reserve(v).unwrap(); // $ MISSING: Alert[rust/uncontrolled-allocation-size]
let _ = v1.try_reserve_exact(v).unwrap(); // $ MISSING: Alert[rust/uncontrolled-allocation-size]
v1.resize(v, 1); // $ MISSING: Alert[rust/uncontrolled-allocation-size]
v1.set_len(v); // $ MISSING: Alert[rust/uncontrolled-allocation-size]
let l2 = std::alloc::Layout::new::<[u64; 200]>();
let m2 = std::ptr::NonNull::<u64>::new(std::alloc::alloc(l2).cast::<u64>()).unwrap();
let _ = Vec::<u64>::from_parts(m2, v, 200); // $ MISSING: Alert[rust/uncontrolled-allocation-size]
let m3 = std::ptr::NonNull::<u64>::new(std::alloc::alloc(l2).cast::<u64>()).unwrap();
let _ = Vec::<u64>::from_parts(m3, 100, v); // $ MISSING: Alert[rust/uncontrolled-allocation-size]
let m4 = std::ptr::NonNull::<u64>::new(std::alloc::alloc(l2).cast::<u64>()).unwrap();
let _ = Vec::<u64>::from_parts_in(m4, 100, v, std::alloc::Global); // $ MISSING: Alert[rust/uncontrolled-allocation-size]
let m5 = std::alloc::alloc(l2).cast::<u64>();
let _ = Vec::<u64>::from_raw_parts(m5, v, 200); // $ MISSING: Alert[rust/uncontrolled-allocation-size]
let m6 = std::alloc::alloc(l2).cast::<u64>();
let _ = Vec::<u64>::from_raw_parts(m6, 100, v); // $ MISSING: Alert[rust/uncontrolled-allocation-size]
let m7 = std::alloc::alloc(l2).cast::<u64>();
let _ = Vec::<u64>::from_raw_parts_in(m7, 100, v, std::alloc::Global); // $ MISSING: Alert[rust/uncontrolled-allocation-size]
}
// --- examples from the qhelp ---
struct Error {
msg: String,
}
impl From<std::num::ParseIntError> for Error {
fn from(err: std::num::ParseIntError) -> Self {
Error { msg: "ParseIntError".to_string() }
}
}
impl From<&str> for Error {
fn from(msg: &str) -> Self {
Error { msg: msg.to_string() }
}
}
fn allocate_buffer_bad(user_input: String) -> Result<*mut u8, Error> {
let num_bytes = user_input.parse::<usize>()? * std::mem::size_of::<u64>();
let layout = std::alloc::Layout::from_size_align(num_bytes, 1).unwrap();
unsafe {
let buffer = std::alloc::alloc(layout); // $ Alert[rust/uncontrolled-allocation-size]=example1
Ok(buffer)
}
}
const BUFFER_LIMIT: usize = 10 * 1024;
fn allocate_buffer_good(user_input: String) -> Result<*mut u8, Error> {
let size = user_input.parse::<usize>()?;
if size > BUFFER_LIMIT {
return Err("Size exceeds limit".into());
}
let num_bytes = size * std::mem::size_of::<u64>();
let layout = std::alloc::Layout::from_size_align(num_bytes, 1).unwrap();
unsafe {
let buffer = std::alloc::alloc(layout); // $ GOOD (bounded)
Ok(buffer)
}
}
fn test_examples() {
allocate_buffer_bad(std::env::args().nth(1).unwrap_or("0".to_string())); // $ Source=example1
allocate_buffer_good(std::env::args().nth(1).unwrap_or("0".to_string()));
}
// --- main ---
fn main() {
println!("--- begin ---");
let v = std::env::args().nth(1).unwrap_or("1024".to_string()).parse::<usize>().unwrap(); // $ Source=arg1
unsafe {
test_std_alloc_from_size(v);
test_std_alloc_new_repeat_extend(v);
test_std_alloc_with_bounds(v, 1000);
test_system_alloc(v);
test_libc_alloc(v);
test_vectors(v);
test_examples();
}
println!("--- end ---");
}

View File

@@ -0,0 +1,3 @@
qltest_cargo_check: true
qltest_dependencies:
- libc = { version = "0.2.11" }

View File

@@ -0,0 +1,2 @@
[toolchain]
channel = "nightly"

1
rust/schema/ast.py generated
View File

@@ -539,6 +539,7 @@ class StructExprFieldList(AstNode, ):
class StructField(AstNode, ):
attrs: list["Attr"] | child
default: optional["Expr"] | child
is_unsafe: predicate
name: optional["Name"] | child
type_repr: optional["TypeRepr"] | child
visibility: optional["Visibility"] | child