mirror of
https://github.com/github/codeql.git
synced 2025-12-16 16:53:25 +01:00
178 lines
4.2 KiB
Rust
178 lines
4.2 KiB
Rust
fn source(i: i64) -> i64 {
|
|
1000 + i
|
|
}
|
|
|
|
fn sink(s: i64) {
|
|
println!("{}", s);
|
|
}
|
|
|
|
// Flow through `clone` methods
|
|
|
|
fn option_clone() {
|
|
let a = Some(source(88));
|
|
sink(a.unwrap()); // $ hasValueFlow=88
|
|
let b = a.clone();
|
|
sink(b.unwrap()); // $ hasValueFlow=88
|
|
}
|
|
|
|
fn result_clone() {
|
|
let a: Result<i64, i64> = Ok(source(37));
|
|
sink(a.unwrap()); // $ hasValueFlow=37
|
|
let b = a.clone();
|
|
sink(b.unwrap()); // $ hasValueFlow=37
|
|
}
|
|
|
|
fn i64_clone() {
|
|
let a = source(12);
|
|
sink(a); // $ hasValueFlow=12
|
|
let b = a.clone();
|
|
sink(b); // $ hasValueFlow=12
|
|
}
|
|
|
|
mod my_clone {
|
|
use super::{sink, source};
|
|
|
|
// TODO: Replace manual implementation below with `#[derive(Clone)]`,
|
|
// once the extractor expands the `#[derive]` attributes.
|
|
// #[derive(Clone)]
|
|
struct Wrapper {
|
|
n: i64,
|
|
}
|
|
|
|
impl Clone for Wrapper {
|
|
fn clone(&self) -> Self {
|
|
Wrapper { n: self.n }
|
|
}
|
|
}
|
|
|
|
pub fn wrapper_clone() {
|
|
let w = Wrapper { n: source(73) };
|
|
match w {
|
|
Wrapper { n: n } => sink(n), // $ hasValueFlow=73
|
|
}
|
|
let u = w.clone();
|
|
match u {
|
|
Wrapper { n: n } => sink(n), // $ hasValueFlow=73
|
|
}
|
|
}
|
|
}
|
|
|
|
mod flow_through_option {
|
|
use super::{sink, source};
|
|
// Test the auto generated flow summaries for `Option`
|
|
|
|
fn zip_flow() {
|
|
let a = Some(2);
|
|
let b = Some(source(38));
|
|
let z = a.zip(b);
|
|
match z {
|
|
Some((n, m)) => {
|
|
sink(n);
|
|
sink(m); // $ hasValueFlow=38
|
|
}
|
|
None => (),
|
|
}
|
|
}
|
|
|
|
fn higher_order_flow() {
|
|
let a = Some(0);
|
|
let b = a.map_or(3, |n| n + source(63));
|
|
sink(b); // $ hasTaintFlow=63
|
|
}
|
|
}
|
|
|
|
mod ptr {
|
|
use super::{sink, source};
|
|
|
|
fn read_write() {
|
|
let mut x: i64 = 0;
|
|
let y = &mut x as *mut i64;
|
|
unsafe {
|
|
sink(std::ptr::read(y));
|
|
std::ptr::write(y, source(30));
|
|
sink(std::ptr::read(y)); // $ hasValueFlow=30
|
|
}
|
|
}
|
|
}
|
|
|
|
use std::pin::pin;
|
|
use std::pin::Pin;
|
|
|
|
#[derive(Clone)]
|
|
struct MyStruct {
|
|
val: i64,
|
|
}
|
|
|
|
fn test_pin() {
|
|
{
|
|
let mut i = source(40);
|
|
let mut pin1 = Pin::new(&i);
|
|
let mut pin2 = Box::pin(i);
|
|
let mut pin3 = Box::into_pin(Box::new(i));
|
|
let mut pin4 = pin!(i);
|
|
sink(i); // $ hasValueFlow=40
|
|
sink(*pin1); // $ hasValueFlow=40
|
|
sink(*Pin::into_inner(pin1)); // $ hasValueFlow=40
|
|
sink(*pin2); // $ hasValueFlow=40
|
|
sink(*pin3); // $ hasValueFlow=40
|
|
sink(*pin4); // $ hasValueFlow=40
|
|
}
|
|
|
|
{
|
|
let mut ms = MyStruct { val: source(41) };
|
|
let mut pin1 = Pin::new(&ms);
|
|
let mut pin2 = Box::pin(ms.clone());
|
|
let mut pin3 = Box::into_pin(Box::new(ms.clone()));
|
|
let mut pin4 = pin!(&ms);
|
|
sink(ms.val); // $ hasValueFlow=41
|
|
sink(pin1.val); // $ MISSING: hasValueFlow=41
|
|
sink(Pin::into_inner(pin1).val); // $ hasValueFlow=41
|
|
sink(pin2.val); // $ MISSING: hasValueFlow=41
|
|
sink(pin3.val); // $ MISSING: hasValueFlow=41
|
|
sink(pin4.val); // $ MISSING: hasValueFlow=41
|
|
}
|
|
|
|
unsafe {
|
|
let mut ms = MyStruct { val: source(42) };
|
|
let mut pin5 = Pin::new_unchecked(&ms);
|
|
sink(pin5.val); // $ MISSING: hasValueFlow=42
|
|
sink(Pin::into_inner_unchecked(pin5).val); // $ hasValueFlow=42
|
|
}
|
|
|
|
{
|
|
let mut ms = MyStruct { val: source(43) };
|
|
let mut ms2 = MyStruct { val: source(44) };
|
|
let mut pin = Pin::new(&mut ms);
|
|
sink(pin.val); // $ MISSING: hasValueFlow=43
|
|
pin.set(ms2);
|
|
sink(pin.val); // $ MISSING: hasValueFlow=44
|
|
}
|
|
}
|
|
|
|
fn test_ord() {
|
|
let a = source(50);
|
|
let b = source(51);
|
|
let c = a.min(b);
|
|
sink(c); // $ hasValueFlow=50 hasValueFlow=51
|
|
|
|
let d = source(52);
|
|
let e = source(53);
|
|
let f = d.max(e);
|
|
sink(f); // $ hasValueFlow=52 hasValueFlow=53
|
|
|
|
let g = source(54);
|
|
let h = source(55);
|
|
let i = source(56);
|
|
let j = g.clamp(h, i);
|
|
sink(j); // $ hasValueFlow=54 hasValueFlow=55 hasValueFlow=56
|
|
}
|
|
|
|
fn main() {
|
|
option_clone();
|
|
result_clone();
|
|
i64_clone();
|
|
my_clone::wrapper_clone();
|
|
test_pin();
|
|
test_ord();
|
|
}
|