diff options
author | Tyler Murphy <tylerm@tylerm.dev> | 2023-06-08 02:10:57 -0400 |
---|---|---|
committer | Tyler Murphy <tylerm@tylerm.dev> | 2023-06-08 02:10:57 -0400 |
commit | 346bac811d32ddeb4fa129f548f617aa40a3dd61 (patch) | |
tree | ab8d5c813353067ec09dcabe0286c27cf6b4a618 /src | |
parent | clippy my beloved (diff) | |
download | leak_memory-346bac811d32ddeb4fa129f548f617aa40a3dd61.tar.gz leak_memory-346bac811d32ddeb4fa129f548f617aa40a3dd61.tar.bz2 leak_memory-346bac811d32ddeb4fa129f548f617aa40a3dd61.zip |
lleeaakk
Diffstat (limited to 'src')
-rw-r--r-- | src/lib.rs | 49 | ||||
-rw-r--r-- | src/parse.rs | 76 |
2 files changed, 82 insertions, 43 deletions
@@ -1,33 +1,35 @@ use std::cell::RefCell; use libc::malloc; -use std::fmt::{Result, Display, Formatter}; +use std::fmt::{self, Display, Formatter}; -pub mod parse; +mod parse; #[derive(Clone, Debug)] -pub enum PissError { +pub enum LeakError { + Unexpected(char), InvalidSuffix(String), InvalidNumber(String), NumberNotPositive } -impl Display for PissError { - fn fmt(&self, f: &mut Formatter<'_>) -> Result { +impl Display for LeakError { + fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { match self { - Self::InvalidSuffix(s) => write!(f, "I cannot piss the suffix {s:?}"), - Self::InvalidNumber(s) => write!(f, "I cannot piss the invalid number {s:?}"), - Self::NumberNotPositive => write!(f, "I cannot piss nonexistent memory") + Self::Unexpected(c) => write!(f, "Unexpected character: '{c}'"), + Self::InvalidSuffix(s) => write!(f, "Invalid file size suffix: '{s}'"), + Self::InvalidNumber(s) => write!(f, "Invalid number: '{s}'"), + Self::NumberNotPositive => write!(f, "Cannot leak negative memory") } } } #[derive(Copy, Clone, Debug, Eq, PartialEq, Ord, PartialOrd)] -pub struct PissAmount { - to_piss: u128 +pub struct LeakAmount { + to_leak: u128 } #[derive(Copy, Clone, Debug)] -pub enum Toliet { +pub enum LeakMethod { Rust, Lazy, Unsafe @@ -42,7 +44,7 @@ thread_local!(static TOLIET: RefCell<Vec<Vec<u8>>> = RefCell::new(Vec::new())); fn leak_lazy(amount: usize) { TOLIET.with(|t| { t.borrow_mut().push(Vec::<u8>::with_capacity(amount)); - }) + }); } fn leak_unsafe(amount: usize) { @@ -51,16 +53,21 @@ fn leak_unsafe(amount: usize) { } } -fn leak_match(amount: usize, method: Toliet) { +fn leak_match(amount: usize, method: LeakMethod) { match method { - Toliet::Rust => leak_rust(amount), - Toliet::Lazy => leak_lazy(amount), - Toliet::Unsafe => leak_unsafe(amount), + LeakMethod::Rust => leak_rust(amount), + LeakMethod::Lazy => leak_lazy(amount), + LeakMethod::Unsafe => leak_unsafe(amount), } } -pub fn leak<T: Into<PissAmount>>(amount: T, method: Toliet) { - let num: u128 = amount.into().to_piss; +pub fn leak<T: Into<LeakAmount>>(amount: T, method: LeakMethod) -> Result<(), LeakError> { + let num: u128 = amount.into().to_leak; + + if num <= 0 { + return Err(LeakError::NumberNotPositive) + } + let count = num / usize::MAX as u128; for _ in 0..count { @@ -68,8 +75,10 @@ pub fn leak<T: Into<PissAmount>>(amount: T, method: Toliet) { } leak_match((num % usize::MAX as u128) as usize, method); + + Ok(()) } -pub async fn leak_async<T: Into<PissAmount>>(amount: T, method: Toliet) { - leak(amount, method); +pub async fn leak_async<T: Into<LeakAmount> + Send>(amount: T, method: LeakMethod) -> Result<(), LeakError> { + leak(amount, method) } diff --git a/src/parse.rs b/src/parse.rs index c5521d6..d6e5dfa 100644 --- a/src/parse.rs +++ b/src/parse.rs @@ -1,16 +1,45 @@ use std::str::FromStr; -use crate::{PissError, PissAmount}; +use crate::{LeakError, LeakAmount}; -impl<T> From<T> for PissAmount -where T: Into<u128> { - fn from(num: T) -> Self { - Self { - to_piss: num.into() - } - } +macro_rules! from_num { + ($t:ty) => { + impl From<$t> for LeakAmount { + fn from(num: $t) -> Self { + Self { + to_leak: num as u128 + } + } + } + + impl From<Vec<$t>> for LeakAmount { + fn from(vec: Vec<$t>) -> Self { + let mut amount = 0; + for i in vec { + amount += i as u128; + } + Self { + to_leak: amount + } + } + } + }; } -fn parse_suffix(s: &str) -> Result<u128, PissError> { +from_num!(u128); +from_num!(u64); +from_num!(u32); +from_num!(u16); +from_num!(u8); +from_num!(i128); +from_num!(i64); +from_num!(i32); +from_num!(i16); +from_num!(i8); +from_num!(f32); +from_num!(f64); +from_num!(bool); + +fn parse_suffix(s: &str) -> Result<u128, LeakError> { Ok(match s { // nepal "k" | "kb" => 1_000, "m" | "mb" => 1_000_000, @@ -33,39 +62,40 @@ fn parse_suffix(s: &str) -> Result<u128, PissError> { "ri" | "rib" => 0x0400_0000_0000_0000_0000_0000, "qi" | "qib" => 0x0010_0000_0000_0000_0000_0000_0000, "" | "b" => 1, // uwu - _ => return Err(PissError::InvalidSuffix(s.into())) // such nepal + _ => return Err(LeakError::InvalidSuffix(s.into())) // such nepal }) } -fn parse_file_size(s: &str) -> Result<PissAmount, PissError> { +fn parse_file_size(s: &str) -> Result<LeakAmount, LeakError> { let mut end = 0; for (i, c) in s.char_indices() { - if c.is_ascii_digit() || c == '.' { continue; } end = i; - break; + if !c.is_ascii_digit() && c != '.' { break; } + } + + if end == 0 { + if let Some(c) = s.chars().nth(0) { + return Err(LeakError::Unexpected(c)) + } } let num_text = &s[..end]; let suffix_text = &s[end..]; let Ok(num) = num_text.parse::<f64>() else { - return Err(PissError::InvalidNumber(num_text.into())) + return Err(LeakError::InvalidNumber(num_text.into())) }; - if num <= 0f64 { - return Err(PissError::NumberNotPositive) - } - let multiplier = parse_suffix(suffix_text)?; - Ok(PissAmount { - to_piss: (num * multiplier as f64) as u128 + Ok(LeakAmount { + to_leak: (num * multiplier as f64) as u128 }) } -impl FromStr for PissAmount { - type Err = PissError; +impl FromStr for LeakAmount { + type Err = LeakError; fn from_str(s: &str) -> Result<Self, Self::Err> { - parse_file_size(s) + parse_file_size(s.to_lowercase().as_str()) } } |