Skip to content

Commit

Permalink
Merge pull request #29 from CirclesUBI/feature/app-200-input-validati…
Browse files Browse the repository at this point in the history
…on-for-pathfinders

Validate the U256 input string for 'compute_transfer'
  • Loading branch information
jaensen authored Mar 30, 2023
2 parents 3d89989 + ec0df19 commit 6014339
Showing 1 changed file with 39 additions and 5 deletions.
44 changes: 39 additions & 5 deletions src/server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,37 @@ use crate::types::edge::EdgeDB;
use crate::types::{Address, Edge, U256};
use json::JsonValue;
use std::error::Error;
use std::fmt::{Debug, Display, Formatter};
use std::io::Read;
use std::io::{BufRead, BufReader, Write};
use std::net::{TcpListener, TcpStream};
use std::ops::Deref;
use std::str::FromStr;
use std::sync::mpsc::TrySendError;
use std::sync::{mpsc, Arc, Mutex, RwLock};
use std::thread;
use num_bigint::BigUint;

struct JsonRpcRequest {
id: JsonValue,
method: String,
params: JsonValue,
}

struct InputValidationError(String);
impl Error for InputValidationError {}

impl Debug for InputValidationError {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
write!(f, "Error: {}", self.0)
}
}
impl Display for InputValidationError {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
write!(f, "Error: {}", self.0)
}
}

pub fn start_server(listen_at: &str, queue_size: usize, threads: u64) {
let edges: Arc<RwLock<Arc<EdgeDB>>> = Arc::new(RwLock::new(Arc::new(EdgeDB::default())));

Expand Down Expand Up @@ -137,6 +154,27 @@ fn compute_transfer(
mut socket: TcpStream,
) -> Result<(), Box<dyn Error>> {
socket.write_all(chunked_header().as_bytes())?;

let parsed_value_param = match request.params["value"].as_str() {
Some(value_str) => match BigUint::from_str(value_str) {
Ok(parsed_value) => parsed_value,
Err(e) => {
return Err(Box::new(InputValidationError(format!(
"Invalid value: {}. Couldn't parse value: {}",
value_str, e
))));
}
},
None => U256::MAX.into(),
};

if parsed_value_param > U256::MAX.into() {
return Err(Box::new(InputValidationError(format!(
"Value {} is too large. Maximum value is {}.",
parsed_value_param, U256::MAX
))));
}

let max_distances = if request.params["iterative"].as_bool().unwrap_or_default() {
vec![Some(1), Some(2), None]
} else {
Expand All @@ -148,11 +186,7 @@ fn compute_transfer(
&Address::from(request.params["from"].to_string().as_str()),
&Address::from(request.params["to"].to_string().as_str()),
edges,
if request.params.has_key("value") {
U256::from(request.params["value"].to_string().as_str())
} else {
U256::MAX
},
U256::from_bigint_truncating(parsed_value_param.clone()),
max_distance,
max_transfers,
);
Expand Down

0 comments on commit 6014339

Please sign in to comment.