From d50dd127ba5b30f1cc62caa6d7f68adb01ec53e8 Mon Sep 17 00:00:00 2001 From: Hardcore Sushi Date: Tue, 4 May 2021 20:56:34 +0200 Subject: [PATCH] Safe messages parsing --- src/frontend/commons/script.js | 2 +- src/frontend/index.css | 13 ++++---- src/frontend/index.js | 5 +++ src/session_manager/mod.rs | 55 ++++++++++++++++----------------- src/session_manager/protocol.rs | 28 +++++++++++++++++ 5 files changed, 67 insertions(+), 36 deletions(-) diff --git a/src/frontend/commons/script.js b/src/frontend/commons/script.js index 5c3bce6..b0951a8 100644 --- a/src/frontend/commons/script.js +++ b/src/frontend/commons/script.js @@ -2,7 +2,7 @@ function generateAvatar(name){ let span = document.createElement("span"); if (typeof name == "undefined"){ span.appendChild(document.createTextNode("?")); - } else { + } else if (name.length > 0) { span.appendChild(document.createTextNode(name[0].toUpperCase())); } let div = document.createElement("div"); diff --git a/src/frontend/index.css b/src/frontend/index.css index f4ddcd7..43a44d5 100644 --- a/src/frontend/index.css +++ b/src/frontend/index.css @@ -219,10 +219,10 @@ input[type="file"] { content: url("/static/imgs/icons/verified/FF3C00"); } #left_panel ul li .not_seen_marker { - width: 5px; - height: 5px; + width: 12px; + height: 12px; background-color: var(--accent); - border-radius: 5px; + border-radius: 12px; } #refresher { position: relative; @@ -242,7 +242,7 @@ input[type="file"] { #chat_header { flex-direction: row; align-items: center; - padding: 5px 20px; + padding: 20px 20px; font-size: 1.5em; } #chat_header>div { @@ -254,8 +254,9 @@ input[type="file"] { #chat_header>div:hover p { color: var(--accent); } -#chat_header>div>p { +#chat_header>div>p { /*name*/ font-weight: bold; + margin: 0; } #chat_header p::after { content: url("/static/imgs/icons/warning/FF3C00"); @@ -401,4 +402,4 @@ input[type="file"] { } #message_box, #chat_header, #msg_log { display: none; -} \ No newline at end of file +} diff --git a/src/frontend/index.js b/src/frontend/index.js index c76a3cc..9763a40 100644 --- a/src/frontend/index.js +++ b/src/frontend/index.js @@ -732,6 +732,11 @@ function displayHeader() { function showPopup(content, closeButton = true) { let popup_background = document.createElement("div"); popup_background.classList.add("popup_background"); + popup_background.onclick = function(e) { + if (e.target == popup_background) { + removePopup(); + } + }; let popup = document.createElement("div"); popup.classList.add("popup"); if (closeButton) { diff --git a/src/session_manager/mod.rs b/src/session_manager/mod.rs index 4eae0cc..1fd07f5 100644 --- a/src/session_manager/mod.rs +++ b/src/session_manager/mod.rs @@ -1,7 +1,7 @@ mod session; pub mod protocol; -use std::{collections::HashMap, net::{IpAddr, SocketAddr}, io::{self, Write}, convert::TryInto, str::from_utf8, fs::OpenOptions, sync::{Mutex, RwLock, Arc}}; +use std::{collections::HashMap, net::{IpAddr, SocketAddr}, io::{self, Write}, str::from_utf8, fs::OpenOptions, sync::{Mutex, RwLock, Arc}}; use tokio::{net::{TcpListener, TcpStream}, sync::mpsc::{self, Sender, Receiver}}; use libmdns::Service; use strum_macros::Display; @@ -239,25 +239,20 @@ impl SessionManager { } protocol::Headers::ASK_LARGE_FILE => { if self.sessions.read().unwrap().get(&session_id).unwrap().file_download.is_none() { //don't accept 2 downloads at the same time - let file_size = u64::from_be_bytes(buffer[1..9].try_into().unwrap()); - match from_utf8(&buffer[9..]) { - Ok(file_name) => { - let file_name = sanitize_filename::sanitize(file_name); - let download_dir = UserDirs::new().unwrap().download_dir; - self.sessions.write().unwrap().get_mut(&session_id).unwrap().file_download = Some(LargeFileDownload{ - file_name: file_name.clone(), - download_location: download_dir.to_str().unwrap().to_string(), - file_size, - state: FileState::ASKING, - transferred: 0, - last_chunk: get_unix_timestamp(), - }); - local_file_path = Some(get_not_used_path(&file_name, &download_dir)); - self.with_ui_connection(|ui_connection| { - ui_connection.on_ask_large_file(&session_id, file_size, &file_name, download_dir.to_str().unwrap()); - }) - } - Err(e) => print_error!(e), + if let Some((file_size, file_name)) = protocol::parse_ask_file(&buffer) { + let download_dir = UserDirs::new().unwrap().download_dir; + self.sessions.write().unwrap().get_mut(&session_id).unwrap().file_download = Some(LargeFileDownload{ + file_name: file_name.clone(), + download_location: download_dir.to_str().unwrap().to_string(), + file_size, + state: FileState::ASKING, + transferred: 0, + last_chunk: get_unix_timestamp(), + }); + local_file_path = Some(get_not_used_path(&file_name, &download_dir)); + self.with_ui_connection(|ui_connection| { + ui_connection.on_ask_large_file(&session_id, file_size, &file_name, download_dir.to_str().unwrap()); + }) } } else if let Err(e) = session.encrypt_and_send(&[protocol::Headers::ABORT_FILE_TRANSFER]).await { print_error!(e); @@ -361,16 +356,18 @@ impl SessionManager { let header = buffer[0]; let buffer = match header { protocol::Headers::FILE => { - let file_name_len = u16::from_be_bytes([buffer[1], buffer[2]]) as usize; - let file_name = &buffer[3..3+file_name_len]; - match self.store_file(&session_id, &buffer[3+file_name_len..]) { - Ok(file_uuid) => { - Some([&[protocol::Headers::FILE][..], file_uuid.as_bytes(), file_name].concat()) - } - Err(e) => { - print_error!(e); - None + if let Some((file_name, content)) = protocol::parse_file(&buffer) { + match self.store_file(&session_id, content) { + Ok(file_uuid) => { + Some([&[protocol::Headers::FILE][..], file_uuid.as_bytes(), file_name].concat()) + } + Err(e) => { + print_error!(e); + None + } } + } else { + None } } _ => { diff --git a/src/session_manager/protocol.rs b/src/session_manager/protocol.rs index 0f26d9d..260f578 100644 --- a/src/session_manager/protocol.rs +++ b/src/session_manager/protocol.rs @@ -1,3 +1,6 @@ +use std::{convert::TryInto, str::from_utf8}; +use crate::print_error; + pub struct Headers; impl Headers { @@ -28,6 +31,31 @@ pub fn file(file_name: &str, buffer: &[u8]) -> Vec { [&[Headers::FILE], &(file_name.len() as u16).to_be_bytes()[..], file_name.as_bytes(), buffer].concat() } +pub fn parse_file<'a>(buffer: &'a [u8]) -> Option<(&'a [u8], &'a [u8])> { + if buffer.len() > 3 { + let file_name_len = u16::from_be_bytes([buffer[1], buffer[2]]) as usize; + if buffer.len() > 3+file_name_len { + let file_name = &buffer[3..3+file_name_len]; + return Some((file_name, &buffer[3+file_name_len..])); + } + } + None +} + pub fn ask_large_file(file_size: u64, file_name: &str) -> Vec { [&[Headers::ASK_LARGE_FILE], &file_size.to_be_bytes()[..], file_name.as_bytes()].concat() +} + +pub fn parse_ask_file(buffer: &[u8]) -> Option<(u64, String)> { + if buffer.len() > 9 { + let file_size = u64::from_be_bytes(buffer[1..9].try_into().unwrap()); + match from_utf8(&buffer[9..]) { + Ok(file_name) => { + let file_name = sanitize_filename::sanitize(file_name); + return Some((file_size, file_name)); + } + Err(e) => print_error!(e), + } + } + None } \ No newline at end of file