added modbase64

master
Avril 3 years ago
parent 5e24e96ffe
commit c26dab4150
Signed by: flanchan
GPG Key ID: 284488987C31F630

48
Cargo.lock generated

@ -67,6 +67,12 @@ version = "0.12.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3441f0f7b02788e948e47f457ca01f1d7e6d92c693bc132c22b087d3141c03ff"
[[package]]
name = "base64"
version = "0.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd"
[[package]]
name = "bitflags"
version = "1.2.1"
@ -225,6 +231,7 @@ dependencies = [
name = "datse"
version = "0.1.0"
dependencies = [
"base64 0.13.0",
"color-eyre",
"cryptohelpers",
"futures",
@ -233,7 +240,9 @@ dependencies = [
"log",
"pretty_env_logger",
"rand 0.7.3",
"regex",
"serde",
"smallmap",
"tokio",
"uuid",
"warp",
@ -519,7 +528,7 @@ version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ed18eb2459bf1a09ad2d6b1547840c3e5e62882fa09b9a6a20b1de8e3228848f"
dependencies = [
"base64",
"base64 0.12.3",
"bitflags",
"bytes",
"headers-core",
@ -915,7 +924,7 @@ version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7170d73bf11f39b4ce1809aabc95bf5c33564cdc16fc3200ddda17a5f6e5e48b"
dependencies = [
"base64",
"base64 0.12.3",
"crypto-mac",
"hmac",
"rand 0.7.3",
@ -1235,6 +1244,15 @@ version = "0.1.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6e3bad0ee36814ca07d7968269dd4b7ec89ec2da10c4bb613928d3077083c232"
[[package]]
name = "rustc_version"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a"
dependencies = [
"semver",
]
[[package]]
name = "ryu"
version = "1.0.5"
@ -1253,6 +1271,21 @@ version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ea6a9290e3c9cf0f18145ef7ffa62d68ee0bf5fcd651017e586dc7fd5da448c2"
[[package]]
name = "semver"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403"
dependencies = [
"semver-parser",
]
[[package]]
name = "semver-parser"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"
[[package]]
name = "serde"
version = "1.0.117"
@ -1349,6 +1382,15 @@ version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8"
[[package]]
name = "smallmap"
version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "735b09f6ab554c4165d045a7d67b3b7b5248acb39463dffba38ebced1b9110e2"
dependencies = [
"rustc_version",
]
[[package]]
name = "socket2"
version = "0.3.16"
@ -1547,7 +1589,7 @@ version = "0.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f0308d80d86700c5878b9ef6321f020f29b1bb9d5ff3cab25e75e23f3a492a23"
dependencies = [
"base64",
"base64 0.12.3",
"byteorder",
"bytes",
"http",

@ -20,6 +20,7 @@ server = []
client = []
[dependencies]
base64 = "0.13.0"
color-eyre = {version = "0.5", default-features=false}
cryptohelpers = {version = "1.5.1", features= ["sha256", "rsa", "serde"]}
futures = "0.3.8"
@ -28,7 +29,9 @@ lazy_static = "1.4.0"
log = "0.4.11"
pretty_env_logger = "0.4.0"
rand = "0.7.3"
regex = "1.4.2"
serde = {version = "1.0", features = ["derive"]}
smallmap = "1.2"
tokio = {version = "0.2", features = ["full"]}
uuid = {version = "0.8.1", features = ["v4","serde"]}
warp = "0.2.5"

@ -0,0 +1,133 @@
//! Conversion formats
use super::*;
use std::{
ops::Deref,
borrow::Borrow,
fmt,
error,
};
use regex::{
Regex,
};
const BASE64_VALIDATE_RE_STR: &'static str = r#"^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$"#;
lazy_static!{
static ref BASE64_CONV_TABLE: smallmap::Map<char, char> = smallmap![
{'/' => 'ł'},
{'+' => 'þ'},
{'=' => 'ø'},
];
static ref BASE64_CONV_TABLE_REV: smallmap::Map<char, char> = BASE64_CONV_TABLE.clone().reverse();
static ref BASE64_VALIDATE_REGEX: Regex = Regex::new(BASE64_VALIDATE_RE_STR).expect("Failed to compile base64 validation regex");
}
#[derive(Debug)]
pub struct Base64Error<T>(T);
impl<T> error::Error for Base64Error<T>
where T: AsRef<str> + fmt::Debug{}
impl<T> fmt::Display for Base64Error<T>
where T: AsRef<str>
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result
{
write!(f, "invalid base64: {:?}", self.0.as_ref())
}
}
/// A string of modified base64, appropriate for URL paths etc.
#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Serialize, Deserialize)]
pub struct ModifiedBase64String(String);
impl fmt::Display for ModifiedBase64String
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result
{
write!(f, "{}", self.0)
}
}
impl ModifiedBase64String
{
fn from_base64_unchecked(string: &str) -> Self
{
Self(conv_str(&BASE64_CONV_TABLE, string).collect())
}
/// Consume into a normal base64 string
pub fn into_base64(self) -> String
{
conv_char_iter(&BASE64_CONV_TABLE_REV, self.0.chars()).collect()
}
/// Try to convert a base64 string into a modified base64 string
pub fn try_from_base64<T: AsRef<str>>(base64: T) -> Result<Self, Base64Error<T>>
{
let string = base64.as_ref();
if BASE64_VALIDATE_REGEX.is_match(string) {
Ok(Self::from_base64_unchecked(string))
} else {
Err(Base64Error(base64))
}
}
/// As a string slice
#[inline(always)] pub fn as_str(&self) -> &str
{
self.0.as_str()
}
/// Encode from a slice
pub fn encode(slice: impl AsRef<[u8]>) -> Self
{
Self::from_base64_unchecked(base64::encode(slice.as_ref()).as_str())
}
/// Consume into decoded bytes, write those bytes into the provided buffer
pub fn decode(self, output: &mut Vec<u8>)
{
base64::decode_config_buf(self.into_base64(), base64::STANDARD, output).expect("modified base64 string contained invalid formatted data")
}
/// Consume into decoded bytes, return those bytes as a new `Vec<u8>`
pub fn decode_new(self) -> Vec<u8>
{
base64::decode(self.into_base64()).expect("modified base64 string contained invalid formatted data")
}
}
impl Deref for ModifiedBase64String
{
type Target = str;
#[inline] fn deref(&self) -> &Self::Target {
self.as_str()
}
}
impl AsRef<str> for ModifiedBase64String
{
#[inline] fn as_ref(&self) -> &str
{
self.as_str()
}
}
/// Convert this string with a specified char map. Returns a `char` yielding iterator.
#[inline] pub fn conv_str<'a, 'b>(table: &'b smallmap::Map<char, char>, string: &'a (impl AsRef<str> + ?Sized)) -> CharSubstituteIter<'b, std::str::Chars<'a>>
where 'b: 'a
{
conv_char_iter(table, string.as_ref().chars())
}
/// Convert this iterator of chars with this char swapping map
#[inline] pub fn conv_char_iter<T, I>(table: &smallmap::Map<char, char>, iter: I) -> CharSubstituteIter<I::IntoIter, T>
where I: IntoIterator<Item=T>,
T: From<char> + smallmap::Collapse,
char: Borrow<T>
{
iter.replace_chars(table)
}

@ -1,5 +1,12 @@
//! Extensions
use super::*;
use std::{
borrow::{
Borrow, ToOwned,
},
iter,
};
pub trait Tuple2MapExt<T>
{
@ -30,3 +37,92 @@ where T: rand::distributions::uniform::SampleUniform
util::jitter(self.0, self.1)
}
}
pub trait Unreference<T>
{
fn cloned(self) -> Option<T>;
}
impl<'a, T> Unreference<T> for Option<&'a T>
where T: Clone
{
fn cloned(self) -> Option<T> {
self.map(Clone::clone)
}
}
/// An iterator over `char` that maps certain characters to others
pub struct CharSubstituteIter<'map, I, T= char>
where I: Iterator<Item = T>,
{
iter: I,
map: &'map smallmap::Map<char, char>,
}
impl<'a, I, T> Iterator for CharSubstituteIter<'a, I, T>
where I: Iterator<Item = T>,
T: From<char> + smallmap::Collapse,
char: Borrow<T>
{
type Item = T;
fn next(&mut self) -> Option<Self::Item>
{
self.iter.next()
.map(|item| self.map.get(&item)
.cloned()
.map(T::from)
.unwrap_or(item))
}
#[inline] fn size_hint(&self) -> (usize, Option<usize>) {
self.iter.size_hint()
}
}
impl<'a, I, T> DoubleEndedIterator for CharSubstituteIter<'a, I, T>
where I: Iterator<Item = T> + DoubleEndedIterator,
T: From<char> + smallmap::Collapse,
char: Borrow<T>
{
fn next_back(&mut self) -> Option<Self::Item>
{
self.iter.next_back()
.map(|item| self.map.get(&item)
.cloned()
.map(T::from)
.unwrap_or(item))
}
}
impl<'a, I, T> iter::FusedIterator for CharSubstituteIter<'a, I, T>
where I: Iterator<Item = T> + iter::FusedIterator,
T: From<char> + smallmap::Collapse,
char: Borrow<T>{}
impl<'a, I, T> iter::ExactSizeIterator for CharSubstituteIter<'a, I, T>
where I: Iterator<Item = T> + ExactSizeIterator,
T: From<char> + smallmap::Collapse,
char: Borrow<T>{}
pub trait CharMapExt<T>: Sized + IntoIterator<Item=T>
{
/// Creates an iterator that maps chars over this one
fn replace_chars(self, map: &smallmap::Map<char, char>) -> CharSubstituteIter<'_, Self::IntoIter, T>;
}
impl<S, T> CharMapExt<T> for S
where S: IntoIterator<Item=T>,
T: From<char> + smallmap::Collapse,
char: Borrow<T>
{
#[inline] fn replace_chars(self, map: &smallmap::Map<char, char>) -> CharSubstituteIter<'_, Self::IntoIter, T> {
CharSubstituteIter {
iter: self.into_iter(),
map,
}
}
}

@ -17,6 +17,7 @@ use futures::{
};
use lazy_static::lazy_static;
use getrandom::getrandom;
use smallmap::smallmap;
use serde::{
Serialize,
Deserialize,
@ -35,6 +36,8 @@ mod ext;
use ext::*;
mod util;
mod conv;
mod args;
#[cfg(feature="server")] mod server;

@ -1,120 +0,0 @@
//! Conversion formats
use super::*;
use std::{
ops::Deref,
};
/// A string of modified base64, appropriate for URL paths etc.
#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Serialize, Deserialize)]
pub struct ModifiedBase64String(String);
impl ModifiedBase64String
{
/// Get as a reference
#[inline(always)] pub fn as_str(&self) -> &ModifiedBase64
{
ModifiedBase64::new_unchecked(&self.0[..])
}
/// Get as a mutable reference
#[inline(always)] fn as_mut_str(&mut self) -> &mut ModifiedBase64
{
ModifiedBase64::new_unchecked_mut(&mut self.0[..])
}
/// Consume into regular base64 string
pub fn into_base64(mut self) -> String
{
self.as_mut_str().unmodify();
self.0
}
/// Create from a refular base64 string
pub fn from_base64(mut string: String) -> Self
{
ModifiedBase64::modify(&mut string[..]);
Self(string)
}
}
impl AsRef<ModifiedBase64> for ModifiedBase64String
{
#[inline] fn as_ref(&self) -> &ModifiedBase64
{
self.as_str()
}
}
impl Deref for ModifiedBase64String
{
type Target = ModifiedBase64;
#[inline] fn deref(&self) -> &Self::Target {
self.as_str()
}
}
/// A string slice of modified base64, appropriate for URL paths etc.
#[derive(Debug, PartialEq, Eq, Hash, PartialOrd, Ord, Serialize)]
#[repr(transparent)]
pub struct ModifiedBase64(str);
impl ModifiedBase64
{
#[inline(always)] fn new_unchecked<'a>(from: &'a str) -> &'a ModifiedBase64
{
unsafe {
std::mem::transmute(from)
}
}
#[inline(always)] fn new_unchecked_mut<'a>(from: &'a mut str) -> &'a mut ModifiedBase64
{
unsafe {
std::mem::transmute(from)
}
}
/// Get the underlying string slice
#[inline] pub fn as_str(&self) -> &str
{
unsafe {
std::mem::transmute::<&'_ Self, &'_ str>(self)
}
}
/// Get the underlying string slice as a mutable reference.
///
/// # This is not safe to expose in the API.
#[inline] fn as_mut_str(&mut self) -> &mut str
{
unsafe {
std::mem::transmute::<&'_ mut Self, &'_ mut str>(self)
}
}
fn unmodify(&mut self) -> &mut str
{
todo!();
self.as_mut_str()
}
/// Modify this base64 string into a mutable reference to self
pub fn modify(base64: &mut str) -> &mut Self
{
todo!();
Self::new_unchecked_mut(base64)
}
}
impl AsRef<ModifiedBase64> for ModifiedBase64
{
#[inline(always)] fn as_ref(&self) -> &ModifiedBase64
{
self
}
}

@ -7,7 +7,6 @@ pub struct Config
}
mod state;
mod conv;
#[cfg(feature="server-http")] pub mod web;
#[cfg(feature="server-tcp")] pub mod tcp;

Loading…
Cancel
Save