From 949969b47e9eef07a42a3342cd31d8f906ac34ba Mon Sep 17 00:00:00 2001 From: jaensen <4954577+jaensen@users.noreply.github.com> Date: Thu, 30 Mar 2023 04:11:39 +0200 Subject: [PATCH 1/2] Added new InputValidationError and validate the U256 input string for 'compute_transfer' with a BigUint. --- src/server.rs | 45 ++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 40 insertions(+), 5 deletions(-) diff --git a/src/server.rs b/src/server.rs index ca01750..304f8bc 100644 --- a/src/server.rs +++ b/src/server.rs @@ -4,13 +4,16 @@ 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, @@ -131,12 +134,48 @@ fn load_safes_binary(edges: &RwLock>, file: &str) -> Result) -> 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) + } +} + +impl Error for InputValidationError {} + fn compute_transfer( request: JsonRpcRequest, edges: &EdgeDB, mut socket: TcpStream, ) -> Result<(), Box> { 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 { @@ -148,11 +187,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, ); From ec0df1959ec2e7c3ec185a88009dd0b37e63f62b Mon Sep 17 00:00:00 2001 From: jaensen <4954577+jaensen@users.noreply.github.com> Date: Thu, 30 Mar 2023 04:30:34 +0200 Subject: [PATCH 2/2] moved the InputValidationError to the top of server.rs --- src/server.rs | 29 ++++++++++++++--------------- 1 file changed, 14 insertions(+), 15 deletions(-) diff --git a/src/server.rs b/src/server.rs index 304f8bc..1cc68ec 100644 --- a/src/server.rs +++ b/src/server.rs @@ -21,6 +21,20 @@ struct JsonRpcRequest { 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>> = Arc::new(RwLock::new(Arc::new(EdgeDB::default()))); @@ -134,21 +148,6 @@ fn load_safes_binary(edges: &RwLock>, file: &str) -> Result) -> 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) - } -} - -impl Error for InputValidationError {} - fn compute_transfer( request: JsonRpcRequest, edges: &EdgeDB,