summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorTyler Murphy <tylerm@tylerm.dev>2023-06-08 02:10:57 -0400
committerTyler Murphy <tylerm@tylerm.dev>2023-06-08 02:10:57 -0400
commit346bac811d32ddeb4fa129f548f617aa40a3dd61 (patch)
treeab8d5c813353067ec09dcabe0286c27cf6b4a618 /src
parentclippy my beloved (diff)
downloadleak_memory-346bac811d32ddeb4fa129f548f617aa40a3dd61.tar.gz
leak_memory-346bac811d32ddeb4fa129f548f617aa40a3dd61.tar.bz2
leak_memory-346bac811d32ddeb4fa129f548f617aa40a3dd61.zip
lleeaakk
Diffstat (limited to 'src')
-rw-r--r--src/lib.rs49
-rw-r--r--src/parse.rs76
2 files changed, 82 insertions, 43 deletions
diff --git a/src/lib.rs b/src/lib.rs
index 2b5e3ac..b9a7b07 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -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())
}
}