From e8b4f54ef9910f733f5d4785a906fc6ca185167b Mon Sep 17 00:00:00 2001 From: Jokler Date: Fri, 20 Oct 2017 01:07:48 +0200 Subject: Move the Factoids plugin into a subfolder --- src/plugins/factoids/sandbox.lua | 1 + 1 file changed, 1 insertion(+) create mode 100644 src/plugins/factoids/sandbox.lua (limited to 'src/plugins/factoids/sandbox.lua') diff --git a/src/plugins/factoids/sandbox.lua b/src/plugins/factoids/sandbox.lua new file mode 100644 index 0000000..9b4f52e --- /dev/null +++ b/src/plugins/factoids/sandbox.lua @@ -0,0 +1 @@ +factoid() -- cgit v1.2.3-70-g09d2 From 048f5f048456b4537b1067273b89d5192c65fb21 Mon Sep 17 00:00:00 2001 From: Jokler Date: Tue, 13 Feb 2018 15:35:03 +0100 Subject: Add some sandboxing --- src/plugins/factoids/mod.rs | 6 +++--- src/plugins/factoids/sandbox.lua | 28 +++++++++++++++++++++++++++- 2 files changed, 30 insertions(+), 4 deletions(-) (limited to 'src/plugins/factoids/sandbox.lua') diff --git a/src/plugins/factoids/mod.rs b/src/plugins/factoids/mod.rs index aeb83b0..d67416f 100644 --- a/src/plugins/factoids/mod.rs +++ b/src/plugins/factoids/mod.rs @@ -201,7 +201,7 @@ impl Factoids { factoid }; - server.send_privmsg(&command.target, &value) + server.send_privmsg(&command.target, &value.replace("\n", "|").replace("\r", "")) } } @@ -221,7 +221,7 @@ impl Factoids { let lua = Lua::new(); let globals = lua.globals(); - globals.set("factoid", lua.load(code, Some(name))?)?; + globals.set("factoid", code)?; globals.set("args", args)?; globals.set("input", command.tokens.join(" "))?; globals.set("user", command.source.clone())?; @@ -231,7 +231,7 @@ impl Factoids { lua.exec::<()>(LUA_SANDBOX, Some(name))?; let output: Vec = globals.get::<_, Vec>("output")?; - Ok(output.join("|").replace("\n", "|")) + Ok(output.join("|")) } fn invalid_command(&self, server: &IrcServer, command: &PluginCommand) -> Result<(), IrcError> { diff --git a/src/plugins/factoids/sandbox.lua b/src/plugins/factoids/sandbox.lua index 9b4f52e..4e6b53e 100644 --- a/src/plugins/factoids/sandbox.lua +++ b/src/plugins/factoids/sandbox.lua @@ -1 +1,27 @@ -factoid() +function send(text) + len = #output + if len < 1 then + output = { text } + else + output[len] = output[len] .. text + end +end + +function sendln(text) + sendtoirc(text) + table.insert(output, "") +end + +local env = { print = send, + println = sendln, + args = args, + input = input, + user = user, + channel = channel, + pairs = pairs, + table = table, + string = string, + tostring = tostring, + math = math } + +load(factoid, nil, nil, env)() -- cgit v1.2.3-70-g09d2 From 2c6351d2c8dea5b782b2e6b52b8847426722a60a Mon Sep 17 00:00:00 2001 From: Jokler Date: Tue, 13 Feb 2018 15:39:05 +0100 Subject: Fix function call in lua --- src/plugins/factoids/sandbox.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/plugins/factoids/sandbox.lua') diff --git a/src/plugins/factoids/sandbox.lua b/src/plugins/factoids/sandbox.lua index 4e6b53e..2fff150 100644 --- a/src/plugins/factoids/sandbox.lua +++ b/src/plugins/factoids/sandbox.lua @@ -8,7 +8,7 @@ function send(text) end function sendln(text) - sendtoirc(text) + send(text) table.insert(output, "") end -- cgit v1.2.3-70-g09d2 From 32e59aa3cc6567b909ab995a4e69beb12bdf0322 Mon Sep 17 00:00:00 2001 From: Jokler Date: Tue, 13 Feb 2018 21:37:58 +0100 Subject: Add download function & fromurl command --- bin/main.rs | 2 +- src/lib.rs | 1 + src/plugins/factoids/database.rs | 4 +-- src/plugins/factoids/mod.rs | 63 +++++++++++++++++++++++++++++----------- src/plugins/factoids/sandbox.lua | 1 + src/plugins/factoids/utils.rs | 13 +++++++++ src/plugins/url.rs | 61 ++------------------------------------ src/utils.rs | 59 +++++++++++++++++++++++++++++++++++++ 8 files changed, 125 insertions(+), 79 deletions(-) create mode 100644 src/plugins/factoids/utils.rs create mode 100644 src/utils.rs (limited to 'src/plugins/factoids/sandbox.lua') diff --git a/bin/main.rs b/bin/main.rs index 9373afd..fd0b4ab 100644 --- a/bin/main.rs +++ b/bin/main.rs @@ -144,7 +144,7 @@ fn main() { if let Some(disabled_plugins) = disabled_plugins { for name in disabled_plugins { if let None = bot.remove_plugin(name) { - error!("{:?} was not found - could not disable", name); + error!("\"{}\" was not found - could not disable", name); } } } diff --git a/src/lib.rs b/src/lib.rs index 8b55dab..186d35c 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -51,6 +51,7 @@ extern crate time; pub mod plugin; pub mod plugins; +pub mod utils; use std::collections::HashMap; use std::fmt; diff --git a/src/plugins/factoids/database.rs b/src/plugins/factoids/database.rs index cb6f422..b612d6f 100644 --- a/src/plugins/factoids/database.rs +++ b/src/plugins/factoids/database.rs @@ -106,7 +106,7 @@ impl Database for MysqlConnection { .execute(self) { Ok(_) => DbResponse::Success, Err(e) => { - error!("DB Insertion Error: {:?}", e); + error!("DB Insertion Error: \"{}\"", e); DbResponse::Failed("Failed to add factoid") } } @@ -131,7 +131,7 @@ impl Database for MysqlConnection { } } Err(e) => { - error!("DB Deletion Error: {:?}", e); + error!("DB Deletion Error: \"{}\"", e); DbResponse::Failed("Failed to delete factoid") } } diff --git a/src/plugins/factoids/mod.rs b/src/plugins/factoids/mod.rs index d67416f..f857f85 100644 --- a/src/plugins/factoids/mod.rs +++ b/src/plugins/factoids/mod.rs @@ -14,6 +14,9 @@ use plugin::*; pub mod database; use self::database::{Database, DbResponse}; +mod utils; +use self::utils::download; + static LUA_SANDBOX: &'static str = include_str!("sandbox.lua"); #[derive(PluginName)] @@ -35,6 +38,24 @@ impl Factoids { Factoids { factoids: Mutex::new(db) } } + fn create_factoid(&self, name: &str, content: &str, author: &str) -> Result<&str, &str> { + let count = try_lock!(self.factoids).count(&name)?; + let tm = time::now().to_timespec(); + + let factoid = database::NewFactoid { + name: name, + idx: count, + content: content, + author: author, + created: NaiveDateTime::from_timestamp(tm.sec, tm.nsec as u32), + }; + + match try_lock!(self.factoids).insert(&factoid) { + DbResponse::Success => Ok("Successfully added"), + DbResponse::Failed(e) => Err(e), + } + } + fn add(&self, server: &IrcServer, command: &mut PluginCommand) -> Result<(), IrcError> { if command.tokens.len() < 2 { return self.invalid_command(server, command); @@ -42,24 +63,27 @@ impl Factoids { let name = command.tokens.remove(0); let content = command.tokens.join(" "); - let count = match try_lock!(self.factoids).count(&name) { - Ok(c) => c, - Err(e) => return server.send_notice(&command.source, e), - }; - let tm = time::now().to_timespec(); + match self.create_factoid(&name, &content, &command.source) { + Ok(v) => server.send_notice(&command.source, v), + Err(e) => server.send_notice(&command.source, e), + } + } - let factoid = database::NewFactoid { - name: &name, - idx: count, - content: &content, - author: &command.source, - created: NaiveDateTime::from_timestamp(tm.sec, tm.nsec as u32), - }; + fn from_url(&self, server: &IrcServer, command: &mut PluginCommand) -> Result<(), IrcError> { + if command.tokens.len() < 2 { + return self.invalid_command(server, command); + } - match try_lock!(self.factoids).insert(&factoid) { - DbResponse::Success => server.send_notice(&command.source, "Successfully added"), - DbResponse::Failed(e) => server.send_notice(&command.source, &e), + let name = command.tokens.remove(0); + let url = &command.tokens[0]; + if let Some(content) = ::utils::download(1024, url) { + match self.create_factoid(&name, &content, &command.source) { + Ok(v) => server.send_notice(&command.source, v), + Err(e) => server.send_notice(&command.source, e), + } + } else { + server.send_notice(&command.source, "Failed to download.") } } @@ -110,7 +134,10 @@ impl Factoids { let factoid = match try_lock!(self.factoids).get(name, idx) { Some(v) => v, - None => return server.send_notice(&command.source, &format!("{}~{} does not exist", name, idx)), + None => { + return server.send_notice(&command.source, + &format!("{}~{} does not exist", name, idx)) + } }; server.send_privmsg(&command.target, @@ -194,7 +221,7 @@ impl Factoids { } else { match self.run_lua(&name, &factoid, &command) { Ok(v) => v, - Err(e) => format!("{}", e), + Err(e) => format!("\"{}\"", e), } } } else { @@ -222,6 +249,7 @@ impl Factoids { let globals = lua.globals(); globals.set("factoid", code)?; + globals.set("download", lua.create_function(download))?; globals.set("args", args)?; globals.set("input", command.tokens.join(" "))?; globals.set("user", command.source.clone())?; @@ -274,6 +302,7 @@ impl Plugin for Factoids { let sub_command = command.tokens.remove(0); match sub_command.as_ref() { "add" => self.add(server, &mut command), + "fromurl" => self.from_url(server, &mut command), "remove" => self.remove(server, &mut command), "get" => self.get(server, &command), "info" => self.info(server, &command), diff --git a/src/plugins/factoids/sandbox.lua b/src/plugins/factoids/sandbox.lua index 2fff150..282a903 100644 --- a/src/plugins/factoids/sandbox.lua +++ b/src/plugins/factoids/sandbox.lua @@ -18,6 +18,7 @@ local env = { print = send, input = input, user = user, channel = channel, + request = download, pairs = pairs, table = table, string = string, diff --git a/src/plugins/factoids/utils.rs b/src/plugins/factoids/utils.rs new file mode 100644 index 0000000..ad25eef --- /dev/null +++ b/src/plugins/factoids/utils.rs @@ -0,0 +1,13 @@ +extern crate reqwest; + +use utils; +use super::rlua::prelude::*; + +use self::LuaError::RuntimeError; + +pub fn download(_: &Lua, url: String) -> Result { + match utils::download(1024, &url) { + Some(v) => Ok(v), + None => Err(RuntimeError(format!("Failed to download {}", url))), + } +} diff --git a/src/plugins/url.rs b/src/plugins/url.rs index f6e06f3..6f4a68f 100644 --- a/src/plugins/url.rs +++ b/src/plugins/url.rs @@ -1,5 +1,4 @@ extern crate regex; -extern crate reqwest; extern crate select; use irc::client::prelude::*; @@ -7,15 +6,11 @@ use irc::error::Error as IrcError; use self::regex::Regex; -use std::str; -use std::io::{self, Read}; -use self::reqwest::Client; -use self::reqwest::header::Connection; - use self::select::document::Document; use self::select::predicate::Name; use plugin::*; +use utils; lazy_static! { static ref RE: Regex = Regex::new(r"(^|\s)(https?://\S+)").unwrap(); @@ -43,58 +38,6 @@ impl Url { } } - fn download(&self, url: &str) -> Option { - let response = Client::new() - .get(url) - .header(Connection::close()) - .send(); - - match response { - Ok(mut response) => { - let mut body = String::new(); - - // 500 kilobyte buffer - let mut buf = [0; 500 * 1000]; - let mut written = 0; - // Read until we reach EOF or max_kib KiB - loop { - let len = match response.read(&mut buf) { - Ok(0) => break, - Ok(len) => len, - Err(ref e) if e.kind() == io::ErrorKind::Interrupted => continue, - Err(e) => { - debug!("Download from {:?} failed: {}", url, e); - return None; - } - }; - - let slice = match str::from_utf8(&buf[..len]) { - Ok(slice) => slice, - Err(e) => { - debug!("Failed to read bytes from {:?} as UTF8: {}", url, e); - return None; - } - }; - - body.push_str(slice); - written += len; - - // Check if the file is too large to download - if written > self.max_kib * 1024 { - debug!("Stopping download - File from {:?} is larger than {} KiB", url, self.max_kib); - return None; - } - - } - Some(body) // once told me - } - Err(e) => { - debug!("Bad response from {:?}: ({})", url, e); - return None; - } - } - } - fn url(&self, server: &IrcServer, message: &str, target: &str) -> Result<(), IrcError> { let url = match self.grep_url(message) { Some(url) => url, @@ -104,7 +47,7 @@ impl Url { }; - match self.download(&url) { + match utils::download(self.max_kib, &url) { Some(body) => { let doc = Document::from(body.as_ref()); diff --git a/src/utils.rs b/src/utils.rs new file mode 100644 index 0000000..59a5a54 --- /dev/null +++ b/src/utils.rs @@ -0,0 +1,59 @@ +extern crate reqwest; + +use std::str; +use std::io::{self, Read}; + +use self::reqwest::Client; +use self::reqwest::header::Connection; + +pub fn download(max_kib: usize, url: &str) -> Option { + let response = Client::new() + .get(url) + .header(Connection::close()) + .send(); + + match response { + Ok(mut response) => { + let mut body = String::new(); + + // 500 kilobyte buffer + let mut buf = [0; 500 * 1000]; + let mut written = 0; + // Read until we reach EOF or max_kib KiB + loop { + let len = match response.read(&mut buf) { + Ok(0) => break, + Ok(len) => len, + Err(ref e) if e.kind() == io::ErrorKind::Interrupted => continue, + Err(e) => { + debug!("Download from {:?} failed: {}", url, e); + return None; + } + }; + + let slice = match str::from_utf8(&buf[..len]) { + Ok(slice) => slice, + Err(e) => { + debug!("Failed to read bytes from {:?} as UTF8: {}", url, e); + return None; + } + }; + + body.push_str(slice); + written += len; + + // Check if the file is too large to download + if written > max_kib * 1024 { + debug!("Stopping download - File from {:?} is larger than {} KiB", url, max_kib); + return None; + } + + } + Some(body) + } + Err(e) => { + debug!("Bad response from {:?}: ({})", url, e); + return None; + } + } +} -- cgit v1.2.3-70-g09d2 From 806614b5bf00581c9a564fcda4ecb760b6d27c6a Mon Sep 17 00:00:00 2001 From: Jokler Date: Sat, 17 Feb 2018 23:25:38 +0100 Subject: Improve factoid error handling --- src/plugins/factoids/mod.rs | 6 ++++-- src/plugins/factoids/sandbox.lua | 10 ++++++++-- 2 files changed, 12 insertions(+), 4 deletions(-) (limited to 'src/plugins/factoids/sandbox.lua') diff --git a/src/plugins/factoids/mod.rs b/src/plugins/factoids/mod.rs index f857f85..252ba83 100644 --- a/src/plugins/factoids/mod.rs +++ b/src/plugins/factoids/mod.rs @@ -140,8 +140,10 @@ impl Factoids { } }; + let message = factoid.content.replace("\n", "|").replace("\r", ""); + server.send_privmsg(&command.target, - &format!("{}: {}", factoid.name, factoid.content)) + &format!("{}: {}", factoid.name, message)) } fn info(&self, server: &IrcServer, command: &PluginCommand) -> Result<(), IrcError> { @@ -156,7 +158,7 @@ impl Factoids { }; match count { - 0 => server.send_privmsg(&command.target, &format!("{} does not exist", name)), + 0 => server.send_notice(&command.source, &format!("{} does not exist", name)), 1 => { server.send_privmsg(&command.target, &format!("There is 1 version of {}", name)) diff --git a/src/plugins/factoids/sandbox.lua b/src/plugins/factoids/sandbox.lua index 282a903..8ebf518 100644 --- a/src/plugins/factoids/sandbox.lua +++ b/src/plugins/factoids/sandbox.lua @@ -1,5 +1,6 @@ function send(text) - len = #output + local text = tostring(text) + local len = #output if len < 1 then output = { text } else @@ -25,4 +26,9 @@ local env = { print = send, tostring = tostring, math = math } -load(factoid, nil, nil, env)() +local f, e = load(factoid, nil, nil, env) +if f then + f() +else + error(e) +end -- cgit v1.2.3-70-g09d2 From 297ceaa0899a6228f47f1f14e4bd261ec4cc6619 Mon Sep 17 00:00:00 2001 From: Jokler Date: Fri, 23 Feb 2018 18:29:20 +0100 Subject: Add possibly unsafe timeout hook to factoids --- Cargo.lock | 38 +++++++++++++++++++++++++++++++++++--- Cargo.toml | 2 +- src/plugins/factoids/mod.rs | 9 +++++---- src/plugins/factoids/sandbox.lua | 17 +++++++++++++++++ src/plugins/factoids/utils.rs | 8 ++++++++ 5 files changed, 66 insertions(+), 8 deletions(-) (limited to 'src/plugins/factoids/sandbox.lua') diff --git a/Cargo.lock b/Cargo.lock index 6b471e8..118e68f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -341,6 +341,25 @@ dependencies = [ "backtrace 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "failure" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "backtrace 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", + "failure_derive 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "failure_derive" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)", + "synstructure 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "foreign-types" version = "0.3.2" @@ -372,7 +391,7 @@ dependencies = [ "log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", "regex 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "reqwest 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)", - "rlua 0.9.7 (registry+https://github.com/rust-lang/crates.io-index)", + "rlua 0.12.2 (registry+https://github.com/rust-lang/crates.io-index)", "select 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)", @@ -952,9 +971,10 @@ dependencies = [ [[package]] name = "rlua" -version = "0.9.7" +version = "0.12.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ + "failure 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "gcc 0.3.54 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.34 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1158,6 +1178,15 @@ dependencies = [ "unicode-xid 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "synstructure" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "take" version = "0.1.0" @@ -1451,6 +1480,8 @@ dependencies = [ "checksum encoding-index-tradchinese 1.20141219.5 (registry+https://github.com/rust-lang/crates.io-index)" = "fd0e20d5688ce3cab59eb3ef3a2083a5c77bf496cb798dc6fcdb75f323890c18" "checksum encoding_index_tests 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "a246d82be1c9d791c5dfde9a2bd045fc3cbba3fa2b11ad558f27d01712f00569" "checksum error-chain 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d9435d864e017c3c6afeac1654189b06cdb491cf2ff73dbf0d73b0f292f42ff8" +"checksum failure 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "934799b6c1de475a012a02dab0ace1ace43789ee4b99bcfbf1a2e3e8ced5de82" +"checksum failure_derive 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c7cdda555bb90c9bb67a3b670a0f42de8e73f5981524123ad8578aafec8ddb8b" "checksum foreign-types 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" "checksum foreign-types-shared 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" "checksum fuchsia-zircon 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f6c0581a4e363262e52b87f59ee2afe3415361c6ec35e665924eb08afe8ff159" @@ -1517,7 +1548,7 @@ dependencies = [ "checksum regex-syntax 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ad890a5eef7953f55427c50575c680c42841653abd2b028b68cd223d157f62db" "checksum relay 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f301bafeb60867c85170031bdb2fcf24c8041f33aee09e7b116a58d4e9f781c5" "checksum reqwest 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)" = "3161ca63fd11ce36c7718af239e6492a25a3dbfcec54240f959b9d816cf42413" -"checksum rlua 0.9.7 (registry+https://github.com/rust-lang/crates.io-index)" = "fb7eec2f28b4812553f10b2e69888a5a674b2e761f5a39731c14541c32bdb6d8" +"checksum rlua 0.12.2 (registry+https://github.com/rust-lang/crates.io-index)" = "4d6a9d2d1da31dd5cb4878789b924e46a600bdca4895b30f2efd6370d0dfc80e" "checksum rustc-demangle 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "aee45432acc62f7b9a108cc054142dac51f979e69e71ddce7d6fc7adf29e817e" "checksum rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)" = "dcf128d1287d2ea9d80910b5f1120d0b8eede3fbf1abe91c40d39ea7d51e6fda" "checksum safemem 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e27a8b19b835f7aea908818e871f5cc3a5a186550c30773be987e155e8163d8f" @@ -1543,6 +1574,7 @@ dependencies = [ "checksum string_cache_shared 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b1884d1bc09741d466d9b14e6d37ac89d6909cbcac41dd9ae982d4d063bbedfc" "checksum syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)" = "d3b891b9015c88c576343b9b3e41c2c11a51c219ef067b264bd9c8aa9b441dad" "checksum synom 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a393066ed9010ebaed60b9eafa373d4b1baac186dd7e008555b0f702b51945b6" +"checksum synstructure 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3a761d12e6d8dcb4dcf952a7a89b475e3a9d69e4a69307e01a470977642914bd" "checksum take 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b157868d8ac1f56b64604539990685fa7611d8fa9e5476cf0c02cf34d32917c5" "checksum tempdir 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "87974a6f5c1dfb344d733055601650059a3363de2a6104819293baff662132d6" "checksum tendril 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1b72f8e2f5b73b65c315b1a70c730f24b9d7a25f39e98de8acbe2bb795caea" diff --git a/Cargo.toml b/Cargo.toml index 1775455..aadd44c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -27,7 +27,7 @@ tokio-core = "0.1.10" futures = "0.1.16" log = "0.3.8" time = "0.1" -rlua = "0.9.3" +rlua = "0.12.2" reqwest = "0.8.0" select = "0.4.2" regex = "0.2.2" diff --git a/src/plugins/factoids/mod.rs b/src/plugins/factoids/mod.rs index 252ba83..08e8f12 100644 --- a/src/plugins/factoids/mod.rs +++ b/src/plugins/factoids/mod.rs @@ -15,7 +15,7 @@ pub mod database; use self::database::{Database, DbResponse}; mod utils; -use self::utils::download; +use self::utils::*; static LUA_SANDBOX: &'static str = include_str!("sandbox.lua"); @@ -247,16 +247,17 @@ impl Factoids { .map(ToOwned::to_owned) .collect::>(); - let lua = Lua::new(); + let lua = unsafe { Lua::new_with_debug() }; let globals = lua.globals(); globals.set("factoid", code)?; - globals.set("download", lua.create_function(download))?; + globals.set("download", lua.create_function(download)?)?; + globals.set("sleep", lua.create_function(sleep)?)?; globals.set("args", args)?; globals.set("input", command.tokens.join(" "))?; globals.set("user", command.source.clone())?; globals.set("channel", command.target.clone())?; - globals.set("output", lua.create_table())?; + globals.set("output", lua.create_table()?)?; lua.exec::<()>(LUA_SANDBOX, Some(name))?; let output: Vec = globals.get::<_, Vec>("output")?; diff --git a/src/plugins/factoids/sandbox.lua b/src/plugins/factoids/sandbox.lua index 8ebf518..3fde65e 100644 --- a/src/plugins/factoids/sandbox.lua +++ b/src/plugins/factoids/sandbox.lua @@ -24,9 +24,26 @@ local env = { print = send, table = table, string = string, tostring = tostring, + tonumber = tonumber, math = math } local f, e = load(factoid, nil, nil, env) + +-- Check if the factoid timed out +function checktime(event, line) + if os.time() - time >= timeout then + error("Timed out after " .. timeout .. " seconds", 0) + else + -- Limit the cpu usage of factoids + sleep(1) + end +end + +-- Add timeout hook +time = os.time() +timeout = 30 +debug.sethook(checktime, "l") + if f then f() else diff --git a/src/plugins/factoids/utils.rs b/src/plugins/factoids/utils.rs index ad25eef..fc86fb3 100644 --- a/src/plugins/factoids/utils.rs +++ b/src/plugins/factoids/utils.rs @@ -1,5 +1,8 @@ extern crate reqwest; +use std::thread; +use std::time::Duration; + use utils; use super::rlua::prelude::*; @@ -11,3 +14,8 @@ pub fn download(_: &Lua, url: String) -> Result { None => Err(RuntimeError(format!("Failed to download {}", url))), } } + +pub fn sleep(_: &Lua, dur: u64) -> Result<(), LuaError> { + thread::sleep(Duration::from_millis(dur)); + Ok(()) +} -- cgit v1.2.3-70-g09d2 From 886bd6d4d77a941946bec0d7f8b5c422d206feea Mon Sep 17 00:00:00 2001 From: Jokler Date: Sat, 24 Feb 2018 18:49:57 +0100 Subject: Extend Lua sandbox --- src/plugins/factoids/sandbox.lua | 52 ++++++++++++++++++++++++++++------------ 1 file changed, 37 insertions(+), 15 deletions(-) (limited to 'src/plugins/factoids/sandbox.lua') diff --git a/src/plugins/factoids/sandbox.lua b/src/plugins/factoids/sandbox.lua index 3fde65e..31ef5cb 100644 --- a/src/plugins/factoids/sandbox.lua +++ b/src/plugins/factoids/sandbox.lua @@ -13,21 +13,43 @@ function sendln(text) table.insert(output, "") end -local env = { print = send, - println = sendln, - args = args, - input = input, - user = user, - channel = channel, - request = download, - pairs = pairs, - table = table, - string = string, - tostring = tostring, - tonumber = tonumber, - math = math } - -local f, e = load(factoid, nil, nil, env) +local sandbox_env = { + print = send, + println = sendln, + args = args, + input = input, + user = user, + channel = channel, + request = download, + string = string, + math = math, + table = table, + pairs = pairs, + ipairs = ipairs, + next = next, + select = select, + unpack = unpack, + tostring = tostring, + tonumber = tonumber, + type = type, + assert = assert, + error = error, + pcall = pcall, + xpcall = xpcall, + _VERSION = _VERSION +} + +sandbox_env.os = { + clock = os.clock, + time = os.time, + difftime = os.difftime +} + +sandbox_env.string.rep = nil +sandbox_env.string.dump = nil +sandbox_env.math.randomseed = nil + +local f, e = load(factoid, nil, nil, sandbox_env) -- Check if the factoid timed out function checktime(event, line) -- cgit v1.2.3-70-g09d2 From f24da1f5090d71a4963e05c5a76dad2eccac15bd Mon Sep 17 00:00:00 2001 From: Jokler Date: Sat, 24 Feb 2018 19:26:26 +0100 Subject: Add temporary eval function to factoids --- src/plugins/factoids/sandbox.lua | 27 ++++++++++++++++++++------- 1 file changed, 20 insertions(+), 7 deletions(-) (limited to 'src/plugins/factoids/sandbox.lua') diff --git a/src/plugins/factoids/sandbox.lua b/src/plugins/factoids/sandbox.lua index 31ef5cb..3fc74cd 100644 --- a/src/plugins/factoids/sandbox.lua +++ b/src/plugins/factoids/sandbox.lua @@ -16,6 +16,7 @@ end local sandbox_env = { print = send, println = sendln, + eval = nil, args = args, input = input, user = user, @@ -49,18 +50,30 @@ sandbox_env.string.rep = nil sandbox_env.string.dump = nil sandbox_env.math.randomseed = nil -local f, e = load(factoid, nil, nil, sandbox_env) +-- Temporary evaluation function +function eval(code) + local c, e = load(code, nil, nil, sandbox_env) + if c then + return c() + else + error(e) + end +end + +sandbox_env.eval = eval -- Check if the factoid timed out function checktime(event, line) - if os.time() - time >= timeout then - error("Timed out after " .. timeout .. " seconds", 0) - else - -- Limit the cpu usage of factoids - sleep(1) - end + if os.time() - time >= timeout then + error("Timed out after " .. timeout .. " seconds", 0) + else + -- Limit the cpu usage of factoids + sleep(1) + end end +local f, e = load(factoid, nil, nil, sandbox_env) + -- Add timeout hook time = os.time() timeout = 30 -- cgit v1.2.3-70-g09d2