diff --git a/rust/Cargo.lock b/rust/Cargo.lock index aa04b20e0..3fe8911d6 100644 --- a/rust/Cargo.lock +++ b/rust/Cargo.lock @@ -1938,6 +1938,7 @@ dependencies = [ "nasl-syntax", "regex", "storage", + "tracing", ] [[package]] @@ -3311,18 +3312,18 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.59" +version = "1.0.60" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0126ad08bff79f29fc3ae6a55cc72352056dfff61e3ff8bb7129476d44b23aa" +checksum = "579e9083ca58dd9dcf91a9923bb9054071b9ebbd800b342194c9feb0ee89fc18" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.59" +version = "1.0.60" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d1cd413b5d558b4c5bf3680e324a6fa5014e7b7c067a51e69dbdf47eb7148b66" +checksum = "e2470041c06ec3ac1ab38d0356a6119054dedaea53e12fbefc0de730a1c08524" dependencies = [ "proc-macro2", "quote", diff --git a/rust/examples/get_kb_item.nasl b/rust/examples/get_kb_item.nasl new file mode 100644 index 000000000..808e65376 --- /dev/null +++ b/rust/examples/get_kb_item.nasl @@ -0,0 +1,6 @@ +set_kb_item(name: "test", value: 1); +set_kb_item(name: "test", value: 2); +set_kb_item(name: "test", value: 3); +set_kb_item(name: "test", value: 4); +set_kb_item(name: "test", value: 5); +display(get_kb_item("test")); diff --git a/rust/feed/src/update/mod.rs b/rust/feed/src/update/mod.rs index 7228ea859..ac1908b64 100644 --- a/rust/feed/src/update/mod.rs +++ b/rust/feed/src/update/mod.rs @@ -9,8 +9,8 @@ pub use error::Error; use std::{fmt::Display, fs::File, io::Read, marker::PhantomData}; use nasl_interpreter::{ - logger::DefaultLogger, AsBufReader, Context, ContextType, Interpreter, Loader, NaslValue, - Register, + logger::DefaultLogger, AsBufReader, CodeInterpreter, Context, ContextType, Interpreter, Loader, + NaslValue, Register, }; use storage::{item::NVTField, Dispatcher, NoOpRetriever}; @@ -46,7 +46,7 @@ pub fn feed_version + 'static>( ) -> Result { let feed_info_key = "plugin_feed_info.inc"; let code = loader.load(feed_info_key)?; - let mut register = Register::default(); + let register = Register::default(); let logger = DefaultLogger::default(); let k: K = Default::default(); let fr = NoOpRetriever::default(); @@ -54,15 +54,16 @@ pub fn feed_version + 'static>( // TODO add parameter to struct let functions = nasl_interpreter::nasl_std_functions(); let context = Context::new(&k, &target, dispatcher, &fr, loader, &logger, &functions); - let mut interpreter = Interpreter::new(&mut register, &context); + let mut interpreter = Interpreter::new(register, &context); for stmt in nasl_syntax::parse(&code) { match stmt { - Ok(stmt) => interpreter.retry_resolve(&stmt, 3)?, + Ok(stmt) => interpreter.retry_resolve_next(&stmt, 3)?, Err(e) => return Err(e.into()), }; } - let feed_version = register + let feed_version = interpreter + .register() .named("PLUGIN_SET") .map(|x| x.to_string()) .unwrap_or_else(|| "0".to_owned()); @@ -142,7 +143,7 @@ where fn single(&self, key: &K) -> Result { let code = self.loader.load(key.as_ref())?; - let mut register = Register::root_initial(&self.initial); + let register = Register::root_initial(&self.initial); let logger = DefaultLogger::default(); let fr = NoOpRetriever::default(); let target = String::default(); @@ -158,9 +159,9 @@ where &logger, &functions, ); - let mut interpreter = Interpreter::new(&mut register, &context); - for stmt in nasl_syntax::parse(&code) { - match interpreter.retry_resolve(&stmt?, self.max_retry) { + let interpreter = CodeInterpreter::new(&code, register, &context); + for stmt in interpreter { + match stmt { Ok(NaslValue::Exit(i)) => { self.dispatcher.on_exit()?; return Ok(i); diff --git a/rust/nasl-builtin-cryptographic/tests/aes_cbc.rs b/rust/nasl-builtin-cryptographic/tests/aes_cbc.rs index d7a6812cc..3b98c109c 100644 --- a/rust/nasl-builtin-cryptographic/tests/aes_cbc.rs +++ b/rust/nasl-builtin-cryptographic/tests/aes_cbc.rs @@ -18,12 +18,10 @@ mod tests { crypt = aes128_cbc_encrypt(key: key, data: data, iv: iv); aes128_cbc_decrypt(key: key, data: crypt, iv: iv); "#; - let mut register = Register::default(); + let register = Register::default(); let binding = ContextBuilder::default(); let context = binding.build(); - let mut interpreter = Interpreter::new(&mut register, &context); - let mut parser = - parse(code).map(|x| interpreter.resolve(&x.expect("no parse error expected"))); + let mut parser = CodeInterpreter::new(code, register, &context); parser.next(); parser.next(); parser.next(); @@ -50,12 +48,10 @@ mod tests { crypt = aes192_cbc_encrypt(key: key, data: data, iv: iv); aes192_cbc_decrypt(key: key, data: crypt, iv: iv); "#; - let mut register = Register::default(); + let register = Register::default(); let binding = ContextBuilder::default(); let context = binding.build(); - let mut interpreter = Interpreter::new(&mut register, &context); - let mut parser = - parse(code).map(|x| interpreter.resolve(&x.expect("no parse error expected"))); + let mut parser = CodeInterpreter::new(code, register, &context); parser.next(); parser.next(); parser.next(); @@ -82,12 +78,10 @@ mod tests { crypt = aes256_cbc_encrypt(key: key, data: data, iv: iv); aes256_cbc_decrypt(key: key, data: crypt, iv: iv); "#; - let mut register = Register::default(); + let register = Register::default(); let binding = ContextBuilder::default(); let context = binding.build(); - let mut interpreter = Interpreter::new(&mut register, &context); - let mut parser = - parse(code).map(|x| interpreter.resolve(&x.expect("no parse error expected"))); + let mut parser = CodeInterpreter::new(code, register, &context); parser.next(); parser.next(); parser.next(); @@ -115,12 +109,10 @@ mod tests { aes128_cbc_encrypt(key: key, data: data1, iv: iv); aes128_cbc_encrypt(key: key, data: data2, iv: iv); "#; - let mut register = Register::default(); + let register = Register::default(); let binding = ContextBuilder::default(); let context = binding.build(); - let mut interpreter = Interpreter::new(&mut register, &context); - let mut parser = - parse(code).map(|x| interpreter.resolve(&x.expect("no parse error expected"))); + let mut parser = CodeInterpreter::new(code, register, &context); parser.next(); parser.next(); parser.next(); diff --git a/rust/nasl-builtin-cryptographic/tests/aes_ccm.rs b/rust/nasl-builtin-cryptographic/tests/aes_ccm.rs index 1d7b0ad90..cbea560dd 100644 --- a/rust/nasl-builtin-cryptographic/tests/aes_ccm.rs +++ b/rust/nasl-builtin-cryptographic/tests/aes_ccm.rs @@ -18,12 +18,10 @@ mod tests { crypt = aes128_ccm_encrypt(key: key, data: data, iv: iv); aes128_ccm_decrypt(key: key, data: crypt, iv: iv); "#; - let mut register = Register::default(); + let register = Register::default(); let binding = ContextBuilder::default(); let context = binding.build(); - let mut interpreter = Interpreter::new(&mut register, &context); - let mut parser = - parse(code).map(|x| interpreter.resolve(&x.expect("no parse error expected"))); + let mut parser = CodeInterpreter::new(code, register, &context); parser.next(); parser.next(); parser.next(); @@ -51,12 +49,10 @@ mod tests { crypt = aes128_ccm_encrypt_auth(key: key, data: data, iv: iv, aad: aad); aes128_ccm_decrypt_auth(key: key, data: crypt, iv: iv, aad: aad); "#; - let mut register = Register::default(); + let register = Register::default(); let binding = ContextBuilder::default(); let context = binding.build(); - let mut interpreter = Interpreter::new(&mut register, &context); - let mut parser = - parse(code).map(|x| interpreter.resolve(&x.expect("no parse error expected"))); + let mut parser = CodeInterpreter::new(code, register, &context); parser.next(); parser.next(); parser.next(); @@ -84,12 +80,10 @@ mod tests { crypt = aes192_ccm_encrypt(key: key, data: data, iv: iv); aes192_ccm_decrypt(key: key, data: crypt, iv: iv); "#; - let mut register = Register::default(); + let register = Register::default(); let binding = ContextBuilder::default(); let context = binding.build(); - let mut interpreter = Interpreter::new(&mut register, &context); - let mut parser = - parse(code).map(|x| interpreter.resolve(&x.expect("no parse error expected"))); + let mut parser = CodeInterpreter::new(code, register, &context); parser.next(); parser.next(); parser.next(); @@ -117,12 +111,10 @@ mod tests { crypt = aes192_ccm_encrypt_auth(key: key, data: data, iv: iv, aad: aad); aes192_ccm_decrypt_auth(key: key, data: crypt, iv: iv, aad: aad); "#; - let mut register = Register::default(); + let register = Register::default(); let binding = ContextBuilder::default(); let context = binding.build(); - let mut interpreter = Interpreter::new(&mut register, &context); - let mut parser = - parse(code).map(|x| interpreter.resolve(&x.expect("no parse error expected"))); + let mut parser = CodeInterpreter::new(code, register, &context); parser.next(); parser.next(); parser.next(); @@ -150,12 +142,10 @@ mod tests { crypt = aes256_ccm_encrypt(key: key, data: data, iv: iv); aes256_ccm_decrypt(key: key, data: crypt, iv: iv); "#; - let mut register = Register::default(); + let register = Register::default(); let binding = ContextBuilder::default(); let context = binding.build(); - let mut interpreter = Interpreter::new(&mut register, &context); - let mut parser = - parse(code).map(|x| interpreter.resolve(&x.expect("no parse error expected"))); + let mut parser = CodeInterpreter::new(code, register, &context); parser.next(); parser.next(); parser.next(); @@ -183,12 +173,10 @@ mod tests { crypt = aes256_ccm_encrypt_auth(key: key, data: data, iv: iv, aad: aad); aes256_ccm_decrypt_auth(key: key, data: crypt, iv: iv, aad: aad); "#; - let mut register = Register::default(); + let register = Register::default(); let binding = ContextBuilder::default(); let context = binding.build(); - let mut interpreter = Interpreter::new(&mut register, &context); - let mut parser = - parse(code).map(|x| interpreter.resolve(&x.expect("no parse error expected"))); + let mut parser = CodeInterpreter::new(code, register, &context); parser.next(); parser.next(); parser.next(); diff --git a/rust/nasl-builtin-cryptographic/tests/aes_cmac.rs b/rust/nasl-builtin-cryptographic/tests/aes_cmac.rs index a6ae5a58b..31d423707 100644 --- a/rust/nasl-builtin-cryptographic/tests/aes_cmac.rs +++ b/rust/nasl-builtin-cryptographic/tests/aes_cmac.rs @@ -15,12 +15,10 @@ mod tests { data = hexstr_to_data("d2e8a3e86ae0b9edc7cc3116d929a16f13ee3643"); crypt = aes_mac_cbc(key: key, data: data); "#; - let mut register = Register::default(); + let register = Register::default(); let binding = ContextBuilder::default(); let context = binding.build(); - let mut interpreter = Interpreter::new(&mut register, &context); - let mut parser = - parse(code).map(|x| interpreter.resolve(&x.expect("no parse error expected"))); + let mut parser = CodeInterpreter::new(code, register, &context); parser.next(); parser.next(); assert_eq!( diff --git a/rust/nasl-builtin-cryptographic/tests/aes_ctr.rs b/rust/nasl-builtin-cryptographic/tests/aes_ctr.rs index 84c962ccb..49012ff24 100644 --- a/rust/nasl-builtin-cryptographic/tests/aes_ctr.rs +++ b/rust/nasl-builtin-cryptographic/tests/aes_ctr.rs @@ -19,12 +19,10 @@ mod tests { crypt = aes128_ctr_encrypt(key: key, data: data, iv: iv); aes128_ctr_decrypt(key: key, data: crypt, iv: iv); "#; - let mut register = Register::default(); + let register = Register::default(); let binding = ContextBuilder::default(); let context = binding.build(); - let mut interpreter = Interpreter::new(&mut register, &context); - let mut parser = - parse(code).map(|x| interpreter.resolve(&x.expect("no parse error expected"))); + let mut parser = CodeInterpreter::new(code, register, &context); parser.next(); parser.next(); parser.next(); @@ -51,12 +49,10 @@ mod tests { crypt = aes192_ctr_encrypt(key: key, data: data, iv: iv); aes192_ctr_decrypt(key: key, data: crypt, iv: iv); "#; - let mut register = Register::default(); + let register = Register::default(); let binding = ContextBuilder::default(); let context = binding.build(); - let mut interpreter = Interpreter::new(&mut register, &context); - let mut parser = - parse(code).map(|x| interpreter.resolve(&x.expect("no parse error expected"))); + let mut parser = CodeInterpreter::new(code, register, &context); parser.next(); parser.next(); parser.next(); @@ -83,12 +79,10 @@ mod tests { crypt = aes256_ctr_encrypt(key: key, data: data, iv: iv); aes256_ctr_decrypt(key: key, data: crypt, iv: iv); "#; - let mut register = Register::default(); + let register = Register::default(); let binding = ContextBuilder::default(); let context = binding.build(); - let mut interpreter = Interpreter::new(&mut register, &context); - let mut parser = - parse(code).map(|x| interpreter.resolve(&x.expect("no parse error expected"))); + let mut parser = CodeInterpreter::new(code, register, &context); parser.next(); parser.next(); parser.next(); diff --git a/rust/nasl-builtin-cryptographic/tests/aes_gcm.rs b/rust/nasl-builtin-cryptographic/tests/aes_gcm.rs index 50489bfec..bade3ca2b 100644 --- a/rust/nasl-builtin-cryptographic/tests/aes_gcm.rs +++ b/rust/nasl-builtin-cryptographic/tests/aes_gcm.rs @@ -18,12 +18,10 @@ mod tests { crypt = aes128_gcm_encrypt(key: key, data: data, iv: iv); aes128_gcm_decrypt(key: key, data: crypt, iv: iv); "#; - let mut register = Register::default(); + let register = Register::default(); let binding = ContextBuilder::default(); let context = binding.build(); - let mut interpreter = Interpreter::new(&mut register, &context); - let mut parser = - parse(code).map(|x| interpreter.resolve(&x.expect("no parse error expected"))); + let mut parser = CodeInterpreter::new(code, register, &context); parser.next(); parser.next(); parser.next(); @@ -52,12 +50,10 @@ mod tests { crypt = aes128_gcm_encrypt_auth(key: key, data: data, iv: iv, aad: aad); aes128_gcm_decrypt_auth(key: key, data: crypt, iv: iv, aad: aad); "#; - let mut register = Register::default(); + let register = Register::default(); let binding = ContextBuilder::default(); let context = binding.build(); - let mut interpreter = Interpreter::new(&mut register, &context); - let mut parser = - parse(code).map(|x| interpreter.resolve(&x.expect("no parse error expected"))); + let mut parser = CodeInterpreter::new(code, register, &context); parser.next(); parser.next(); parser.next(); @@ -86,12 +82,10 @@ mod tests { crypt = aes192_gcm_encrypt(key: key, data: data, iv: iv); aes192_gcm_decrypt(key: key, data: crypt, iv: iv); "#; - let mut register = Register::default(); + let register = Register::default(); let binding = ContextBuilder::default(); let context = binding.build(); - let mut interpreter = Interpreter::new(&mut register, &context); - let mut parser = - parse(code).map(|x| interpreter.resolve(&x.expect("no parse error expected"))); + let mut parser = CodeInterpreter::new(code, register, &context); parser.next(); parser.next(); parser.next(); @@ -120,12 +114,10 @@ mod tests { crypt = aes192_gcm_encrypt_auth(key: key, data: data, iv: iv, aad: aad); aes192_gcm_decrypt_auth(key: key, data: crypt, iv: iv, aad: aad); "#; - let mut register = Register::default(); + let register = Register::default(); let binding = ContextBuilder::default(); let context = binding.build(); - let mut interpreter = Interpreter::new(&mut register, &context); - let mut parser = - parse(code).map(|x| interpreter.resolve(&x.expect("no parse error expected"))); + let mut parser = CodeInterpreter::new(code, register, &context); parser.next(); parser.next(); parser.next(); @@ -154,12 +146,10 @@ mod tests { crypt = aes256_gcm_encrypt(key: key, data: data, iv: iv); aes256_gcm_decrypt(key: key, data: crypt, iv: iv); "#; - let mut register = Register::default(); + let register = Register::default(); let binding = ContextBuilder::default(); let context = binding.build(); - let mut interpreter = Interpreter::new(&mut register, &context); - let mut parser = - parse(code).map(|x| interpreter.resolve(&x.expect("no parse error expected"))); + let mut parser = CodeInterpreter::new(code, register, &context); parser.next(); parser.next(); parser.next(); @@ -188,12 +178,10 @@ mod tests { crypt = aes256_gcm_encrypt_auth(key: key, data: data, iv: iv, aad: aad); aes256_gcm_decrypt_auth(key: key, data: crypt, iv: iv, aad: aad); "#; - let mut register = Register::default(); + let register = Register::default(); let binding = ContextBuilder::default(); let context = binding.build(); - let mut interpreter = Interpreter::new(&mut register, &context); - let mut parser = - parse(code).map(|x| interpreter.resolve(&x.expect("no parse error expected"))); + let mut parser = CodeInterpreter::new(code, register, &context); parser.next(); parser.next(); parser.next(); @@ -223,12 +211,10 @@ mod tests { aes128_gcm_encrypt(key: key, data: data1, iv: iv); aes128_gcm_encrypt(key: key, data: data2, iv: iv); "#; - let mut register = Register::default(); + let register = Register::default(); let binding = ContextBuilder::default(); let context = binding.build(); - let mut interpreter = Interpreter::new(&mut register, &context); - let mut parser = - parse(code).map(|x| interpreter.resolve(&x.expect("no parse error expected"))); + let mut parser = CodeInterpreter::new(code, register, &context); parser.next(); parser.next(); parser.next(); diff --git a/rust/nasl-builtin-cryptographic/tests/hash.rs b/rust/nasl-builtin-cryptographic/tests/hash.rs index a8d5d89c9..427098c2a 100644 --- a/rust/nasl-builtin-cryptographic/tests/hash.rs +++ b/rust/nasl-builtin-cryptographic/tests/hash.rs @@ -15,12 +15,10 @@ mod tests { a = MD5('hola mundo'); a = MD5(); "#; - let mut register = Register::default(); + let register = Register::default(); let binding = ContextBuilder::default(); let context = binding.build(); - let mut interpreter = Interpreter::new(&mut register, &context); - let mut parser = - parse(code).map(|x| interpreter.resolve(&x.expect("no parse error expected"))); + let mut parser = CodeInterpreter::new(code, register, &context); assert_eq!( parser.next(), Some(Ok(NaslValue::Data( @@ -41,12 +39,10 @@ mod tests { let code = r#" MD4("hola mundo"); "#; - let mut register = Register::default(); + let register = Register::default(); let binding = ContextBuilder::default(); let context = binding.build(); - let mut interpreter = Interpreter::new(&mut register, &context); - let mut parser = - parse(code).map(|x| interpreter.resolve(&x.expect("no parse error expected"))); + let mut parser = CodeInterpreter::new(code, register, &context); assert_eq!( parser.next(), Some(Ok(NaslValue::Data( @@ -61,12 +57,10 @@ mod tests { let code = r#" MD2("hola mundo"); "#; - let mut register = Register::default(); + let register = Register::default(); let binding = ContextBuilder::default(); let context = binding.build(); - let mut interpreter = Interpreter::new(&mut register, &context); - let mut parser = - parse(code).map(|x| interpreter.resolve(&x.expect("no parse error expected"))); + let mut parser = CodeInterpreter::new(code, register, &context); assert_eq!( parser.next(), Some(Ok(NaslValue::Data( @@ -80,12 +74,10 @@ mod tests { let code = r#" SHA1("hola mundo"); "#; - let mut register = Register::default(); + let register = Register::default(); let binding = ContextBuilder::default(); let context = binding.build(); - let mut interpreter = Interpreter::new(&mut register, &context); - let mut parser = - parse(code).map(|x| interpreter.resolve(&x.expect("no parse error expected"))); + let mut parser = CodeInterpreter::new(code, register, &context); assert_eq!( parser.next(), Some(Ok(NaslValue::Data( @@ -103,12 +95,10 @@ mod tests { let code = r#" SHA256("hola mundo"); "#; - let mut register = Register::default(); + let register = Register::default(); let binding = ContextBuilder::default(); let context = binding.build(); - let mut interpreter = Interpreter::new(&mut register, &context); - let mut parser = - parse(code).map(|x| interpreter.resolve(&x.expect("no parse error expected"))); + let mut parser = CodeInterpreter::new(code, register, &context); assert_eq!( parser.next(), Some(Ok(NaslValue::Data( @@ -126,12 +116,10 @@ mod tests { let code = r#" SHA512("hola mundo"); "#; - let mut register = Register::default(); + let register = Register::default(); let binding = ContextBuilder::default(); let context = binding.build(); - let mut interpreter = Interpreter::new(&mut register, &context); - let mut parser = - parse(code).map(|x| interpreter.resolve(&x.expect("no parse error expected"))); + let mut parser = CodeInterpreter::new(code, register, &context); assert_eq!( parser.next(), Some(Ok(NaslValue::Data( @@ -151,12 +139,10 @@ mod tests { let code = r#" RIPEMD160("hola mundo"); "#; - let mut register = Register::default(); + let register = Register::default(); let binding = ContextBuilder::default(); let context = binding.build(); - let mut interpreter = Interpreter::new(&mut register, &context); - let mut parser = - parse(code).map(|x| interpreter.resolve(&x.expect("no parse error expected"))); + let mut parser = CodeInterpreter::new(code, register, &context); assert_eq!( parser.next(), Some(Ok(NaslValue::Data( diff --git a/rust/nasl-builtin-cryptographic/tests/hmac.rs b/rust/nasl-builtin-cryptographic/tests/hmac.rs index 89e6f2ae2..c1513f4ef 100644 --- a/rust/nasl-builtin-cryptographic/tests/hmac.rs +++ b/rust/nasl-builtin-cryptographic/tests/hmac.rs @@ -12,12 +12,10 @@ mod tests { let code = r#" HMAC_MD2(key: "my_shared?key", data: "so much wow"); "#; - let mut register = Register::default(); + let register = Register::default(); let binding = ContextBuilder::default(); let context = binding.build(); - let mut interpreter = Interpreter::new(&mut register, &context); - let mut parser = - parse(code).map(|x| interpreter.resolve(&x.expect("no parse error expected"))); + let mut parser = CodeInterpreter::new(code, register, &context); assert_eq!( parser.next(), Some(Ok("9558b32badac84072d54422d05bd601a".into())) @@ -29,12 +27,10 @@ mod tests { let code = r#" HMAC_MD5(key: "my_shared?key", data: "so much wow"); "#; - let mut register = Register::default(); + let register = Register::default(); let binding = ContextBuilder::default(); let context = binding.build(); - let mut interpreter = Interpreter::new(&mut register, &context); - let mut parser = - parse(code).map(|x| interpreter.resolve(&x.expect("no parse error expected"))); + let mut parser = CodeInterpreter::new(code, register, &context); assert_eq!( parser.next(), Some(Ok("815292959633f0e63666d90d6f47cb79".into())) @@ -46,12 +42,10 @@ mod tests { let code = r#" HMAC_RIPEMD160(key: "my_shared?key", data: "so much wow"); "#; - let mut register = Register::default(); + let register = Register::default(); let binding = ContextBuilder::default(); let context = binding.build(); - let mut interpreter = Interpreter::new(&mut register, &context); - let mut parser = - parse(code).map(|x| interpreter.resolve(&x.expect("no parse error expected"))); + let mut parser = CodeInterpreter::new(code, register, &context); assert_eq!( parser.next(), Some(Ok("e337eca2ca86bd2d4678462b491d72f03dbc70c8".into())) @@ -63,12 +57,10 @@ mod tests { let code = r#" HMAC_SHA1(key: "my_shared?key", data: "so much wow"); "#; - let mut register = Register::default(); + let register = Register::default(); let binding = ContextBuilder::default(); let context = binding.build(); - let mut interpreter = Interpreter::new(&mut register, &context); - let mut parser = - parse(code).map(|x| interpreter.resolve(&x.expect("no parse error expected"))); + let mut parser = CodeInterpreter::new(code, register, &context); assert_eq!( parser.next(), Some(Ok("3815da2d914cdddd3fe2ca620dd1f1a2ba5f17bc".into())) @@ -80,12 +72,10 @@ mod tests { let code = r#" HMAC_SHA256(key: "my_shared?key", data: "so much wow"); "#; - let mut register = Register::default(); + let register = Register::default(); let binding = ContextBuilder::default(); let context = binding.build(); - let mut interpreter = Interpreter::new(&mut register, &context); - let mut parser = - parse(code).map(|x| interpreter.resolve(&x.expect("no parse error expected"))); + let mut parser = CodeInterpreter::new(code, register, &context); assert_eq!( parser.next(), Some(Ok( @@ -99,12 +89,10 @@ mod tests { let code = r#" HMAC_SHA384(key: "my_shared?key", data: "so much wow"); "#; - let mut register = Register::default(); + let register = Register::default(); let binding = ContextBuilder::default(); let context = binding.build(); - let mut interpreter = Interpreter::new(&mut register, &context); - let mut parser = - parse(code).map(|x| interpreter.resolve(&x.expect("no parse error expected"))); + let mut parser = CodeInterpreter::new(code, register, &context); assert_eq!( parser.next(), Some(Ok("fce1f12094a52a4654c4a0f7086a470e74096fa200187a79f770384e33dd9f1a224b7bd86f6ced2dd1be6d922f8418b2".into())) @@ -116,12 +104,10 @@ mod tests { let code = r#" HMAC_SHA512(key: "my_shared?key", data: "so much wow"); "#; - let mut register = Register::default(); + let register = Register::default(); let binding = ContextBuilder::default(); let context = binding.build(); - let mut interpreter = Interpreter::new(&mut register, &context); - let mut parser = - parse(code).map(|x| interpreter.resolve(&x.expect("no parse error expected"))); + let mut parser = CodeInterpreter::new(code, register, &context); assert_eq!( parser.next(), Some(Ok("7e251167d67f7f29fc978048d338f6ebe0d8bb5213f5ccacca50359b3435df19e60fa709241b98b0ed9e1aeb994df6f900c5fa87201c3fc971b0120968c96cb3".into())) diff --git a/rust/nasl-builtin-host/tests/hostname.rs b/rust/nasl-builtin-host/tests/hostname.rs index 1daf0488e..35cf11cad 100644 --- a/rust/nasl-builtin-host/tests/hostname.rs +++ b/rust/nasl-builtin-host/tests/hostname.rs @@ -11,12 +11,10 @@ mod tests { get_host_name(); get_host_names(); "###; - let mut register = Register::default(); + let register = Register::default(); let binding = ContextBuilder::default(); let context = binding.build(); - let mut interpreter = Interpreter::new(&mut register, &context); - let mut parser = - parse(code).map(|x| interpreter.resolve(&x.expect("no parse error expected"))); + let mut parser = CodeInterpreter::new(code, register, &context); assert!(matches!(parser.next(), Some(Ok(NaslValue::String(_))))); assert!(matches!(parser.next(), Some(Ok(NaslValue::Array(_))))); } diff --git a/rust/nasl-builtin-knowledge-base/src/lib.rs b/rust/nasl-builtin-knowledge-base/src/lib.rs index 4b36f6721..0fb46fb7f 100644 --- a/rust/nasl-builtin-knowledge-base/src/lib.rs +++ b/rust/nasl-builtin-knowledge-base/src/lib.rs @@ -2,7 +2,10 @@ // // SPDX-License-Identifier: GPL-2.0-or-later WITH x11vnc-openssl-exception +use std::time::{SystemTime, UNIX_EPOCH}; + use nasl_builtin_utils::{error::FunctionErrorKind, get_named_parameter, NaslFunction}; +use storage::{Field, Kb, Retrieve}; use nasl_builtin_utils::{Context, Register}; use nasl_syntax::NaslValue; @@ -12,8 +15,8 @@ fn set_kb_item(register: &Register, c: &Context) -> Result Some(*x as u64), - Ok(NaslValue::Exit(_)) => None, + Ok(NaslValue::Number(x)) => Some(*x), + Ok(NaslValue::Exit(0)) => None, Ok(x) => { return Err(FunctionErrorKind::Diagnostic( format!("expected expires to be a number but is {x}."), @@ -21,14 +24,43 @@ fn set_kb_item(register: &Register, c: &Context) -> Result return Err(e), - }; - c.set_kb_item(name.to_string(), value.clone().as_primitive(), expires) + } + .map(|seconds| { + let start = SystemTime::now(); + match start.duration_since(UNIX_EPOCH) { + Ok(x) => x.as_secs() + seconds as u64, + Err(_) => 0, + } + }); + c.dispatcher() + .dispatch( + c.key(), + Field::KB(Kb { + key: name.to_string(), + value: value.clone().as_primitive(), + expire: expires, + }), + ) + .map(|_| NaslValue::Null) + .map_err(|e| e.into()) } /// NASL function to get a knowledge base fn get_kb_item(register: &Register, c: &Context) -> Result { match register.positional() { - [x] => c.get_kb_item(&x.to_string()), + [x] => c + .retriever() + .retrieve(c.key(), Retrieve::KB(x.to_string())) + .map(|r| { + r.into_iter() + .filter_map(|x| match x { + Field::NVT(_) | Field::NotusAdvisory(_) => None, + Field::KB(kb) => Some(kb.value.into()), + }) + .collect::>() + }) + .map(NaslValue::Fork) + .map_err(|e| e.into()), x => Err(FunctionErrorKind::Diagnostic( format!("expected one positional argument but got: {}", x.len()), None, diff --git a/rust/nasl-builtin-knowledge-base/tests/kb.rs b/rust/nasl-builtin-knowledge-base/tests/kb.rs index 5256cdae9..8b8380f49 100644 --- a/rust/nasl-builtin-knowledge-base/tests/kb.rs +++ b/rust/nasl-builtin-knowledge-base/tests/kb.rs @@ -13,12 +13,10 @@ mod tests { set_kb_item(name: "test"); set_kb_item(value: 1); "#; - let mut register = Register::default(); + let register = Register::default(); let binding = ContextBuilder::default(); let context = binding.build(); - let mut interpreter = Interpreter::new(&mut register, &context); - let mut parser = - parse(code).map(|x| interpreter.resolve(&x.expect("no parse error expected"))); + let mut parser = CodeInterpreter::new(code, register, &context); assert_eq!(parser.next(), Some(Ok(NaslValue::Null))); assert!(matches!(parser.next(), Some(Err(_)))); assert!(matches!(parser.next(), Some(Err(_)))); @@ -30,12 +28,10 @@ mod tests { get_kb_item("test"); get_kb_item("test", 1); "#; - let mut register = Register::default(); + let register = Register::default(); let binding = ContextBuilder::default(); let context = binding.build(); - let mut interpreter = Interpreter::new(&mut register, &context); - let mut parser = - parse(code).map(|x| interpreter.resolve(&x.expect("no parse error expected"))); + let mut parser = CodeInterpreter::new(code, register, &context); assert_eq!(parser.next(), Some(Ok(NaslValue::Null))); assert_eq!(parser.next(), Some(Ok(NaslValue::Number(1)))); assert!(matches!(parser.next(), Some(Err(_)))); diff --git a/rust/nasl-builtin-misc/tests/misc.rs b/rust/nasl-builtin-misc/tests/misc.rs index bd9e9476e..611b41a40 100644 --- a/rust/nasl-builtin-misc/tests/misc.rs +++ b/rust/nasl-builtin-misc/tests/misc.rs @@ -7,8 +7,8 @@ mod tests { use chrono::Offset; use nasl_builtin_utils::Register; - use nasl_interpreter::{ContextBuilder, Interpreter}; - use nasl_syntax::{parse, NaslValue}; + use nasl_interpreter::{CodeInterpreter, ContextBuilder}; + use nasl_syntax::NaslValue; use std::time::Instant; #[test] @@ -17,12 +17,10 @@ mod tests { rand(); rand(); "###; - let mut register = Register::default(); + let register = Register::default(); let binding = ContextBuilder::default(); let context = binding.build(); - let mut interpreter = Interpreter::new(&mut register, &context); - let mut parser = - parse(code).map(|x| interpreter.resolve(&x.expect("no parse error expected"))); + let mut parser = CodeInterpreter::new(code, register, &context); let first = parser.next(); let second = parser.next(); assert!(matches!(first, Some(Ok(NaslValue::Number(_))))); @@ -35,12 +33,10 @@ mod tests { let code = r###" get_byte_order(); "###; - let mut register = Register::default(); + let register = Register::default(); let binding = ContextBuilder::default(); let context = binding.build(); - let mut interpreter = Interpreter::new(&mut register, &context); - let mut parser = - parse(code).map(|x| interpreter.resolve(&x.expect("no parse error expected"))); + let mut parser = CodeInterpreter::new(code, register, &context); assert!(matches!(parser.next(), Some(Ok(NaslValue::Boolean(_))))); } @@ -49,12 +45,10 @@ mod tests { let code = r###" dec2str(num: 23); "###; - let mut register = Register::default(); + let register = Register::default(); let binding = ContextBuilder::default(); let context = binding.build(); - let mut interpreter = Interpreter::new(&mut register, &context); - let mut parser = - parse(code).map(|x| interpreter.resolve(&x.expect("no parse error expected"))); + let mut parser = CodeInterpreter::new(code, register, &context); assert_eq!(parser.next(), Some(Ok("23".into()))); } @@ -71,12 +65,10 @@ mod tests { typeof(a); typeof(23,76); "#; - let mut register = Register::default(); + let register = Register::default(); let binding = ContextBuilder::default(); let context = binding.build(); - let mut interpreter = Interpreter::new(&mut register, &context); - let mut parser = - parse(code).map(|x| interpreter.resolve(&x.expect("no parse error expected"))); + let mut parser = CodeInterpreter::new(code, register, &context); assert_eq!(parser.next(), Some(Ok(NaslValue::String("string".into())))); assert_eq!(parser.next(), Some(Ok(NaslValue::String("int".into())))); assert_eq!(parser.next(), Some(Ok(NaslValue::String("data".into())))); @@ -94,12 +86,10 @@ mod tests { isnull(42); isnull(Null); "###; - let mut register = Register::default(); + let register = Register::default(); let binding = ContextBuilder::default(); let context = binding.build(); - let mut interpreter = Interpreter::new(&mut register, &context); - let mut parser = - parse(code).map(|x| interpreter.resolve(&x.expect("no parse error expected"))); + let mut parser = CodeInterpreter::new(code, register, &context); assert_eq!(parser.next(), Some(Ok(NaslValue::Boolean(false)))); assert_eq!(parser.next(), Some(Ok(NaslValue::Boolean(true)))); } @@ -109,12 +99,10 @@ mod tests { let code = r###" unixtime(); "###; - let mut register = Register::default(); + let register = Register::default(); let binding = ContextBuilder::default(); let context = binding.build(); - let mut interpreter = Interpreter::new(&mut register, &context); - let mut parser = - parse(code).map(|x| interpreter.resolve(&x.expect("no parse error expected"))); + let mut parser = CodeInterpreter::new(code, register, &context); assert!(matches!(parser.next(), Some(Ok(NaslValue::Number(_))))); } @@ -124,12 +112,10 @@ mod tests { gzip(data: 'z', headformat: "gzip"); gzip(data: 'z'); "#; - let mut register = Register::default(); + let register = Register::default(); let binding = ContextBuilder::default(); let context = binding.build(); - let mut interpreter = Interpreter::new(&mut register, &context); - let mut parser = - parse(code).map(|x| interpreter.resolve(&x.expect("no parse error expected"))); + let mut parser = CodeInterpreter::new(code, register, &context); assert_eq!( parser.next(), Some(Ok(NaslValue::Data( @@ -157,12 +143,10 @@ mod tests { ngz = gzip(data: "ngz"); gunzip(data: ngz); "#; - let mut register = Register::default(); + let register = Register::default(); let binding = ContextBuilder::default(); let context = binding.build(); - let mut interpreter = Interpreter::new(&mut register, &context); - let mut parser = - parse(code).map(|x| interpreter.resolve(&x.expect("no parse error expected"))); + let mut parser = CodeInterpreter::new(code, register, &context); parser.next(); assert_eq!(parser.next(), Some(Ok(NaslValue::String("z".into())))); parser.next(); @@ -179,12 +163,10 @@ mod tests { c = localtime(utc: TRUE); d = localtime(utc: FALSE); "###; - let mut register = Register::default(); + let register = Register::default(); let binding = ContextBuilder::default(); let context = binding.build(); - let mut interpreter = Interpreter::new(&mut register, &context); - let mut parser = - parse(code).map(|x| interpreter.resolve(&x.expect("no parse error expected"))); + let mut parser = CodeInterpreter::new(code, register, &context); let offset = chrono::Local::now().offset().fix().local_minus_utc(); let date_a = parser.next(); @@ -252,12 +234,10 @@ mod tests { let code = r###" mktime(sec: 01, min: 02, hour: 03, mday: 01, mon: 01, year: 1970); "###; - let mut register = Register::default(); + let register = Register::default(); let binding = ContextBuilder::default(); let context = binding.build(); - let mut interpreter = Interpreter::new(&mut register, &context); - let mut parser = - parse(code).map(|x| interpreter.resolve(&x.expect("no parse error expected"))); + let mut parser = CodeInterpreter::new(code, register, &context); let offset = chrono::Local::now().offset().fix().local_minus_utc(); assert_eq!( parser.next(), @@ -270,12 +250,10 @@ mod tests { let code = r###" sleep(1); "###; - let mut register = Register::default(); + let register = Register::default(); let binding = ContextBuilder::default(); let context = binding.build(); - let mut interpreter = Interpreter::new(&mut register, &context); - let mut parser = - parse(code).map(|x| interpreter.resolve(&x.expect("no parse error expected"))); + let mut parser = CodeInterpreter::new(code, register, &context); let now = Instant::now(); parser.next(); assert!(now.elapsed().as_secs() >= 1); @@ -286,12 +264,10 @@ mod tests { let code = r###" usleep(1000); "###; - let mut register = Register::default(); + let register = Register::default(); let binding = ContextBuilder::default(); let context = binding.build(); - let mut interpreter = Interpreter::new(&mut register, &context); - let mut parser = - parse(code).map(|x| interpreter.resolve(&x.expect("no parse error expected"))); + let mut parser = CodeInterpreter::new(code, register, &context); let now = Instant::now(); parser.next(); assert!(now.elapsed().as_micros() >= 1000); @@ -307,12 +283,10 @@ mod tests { defined_func("a"); defined_func(a); "#; - let mut register = Register::default(); + let register = Register::default(); let binding = ContextBuilder::default(); let context = binding.build(); - let mut interpreter = Interpreter::new(&mut register, &context); - let mut parser = - parse(code).map(|x| interpreter.resolve(&x.expect("no parse error expected"))); + let mut parser = CodeInterpreter::new(code, register, &context); assert_eq!(parser.next(), Some(Ok(NaslValue::Null))); // defining function b assert_eq!(parser.next(), Some(Ok(true.into()))); // is b defined assert_eq!(parser.next(), Some(Ok(true.into()))); // is defined_func defined diff --git a/rust/nasl-builtin-raw-ip/tests/frame_forgery.rs b/rust/nasl-builtin-raw-ip/tests/frame_forgery.rs index 484b7e8e8..58a6f6ba2 100644 --- a/rust/nasl-builtin-raw-ip/tests/frame_forgery.rs +++ b/rust/nasl-builtin-raw-ip/tests/frame_forgery.rs @@ -10,8 +10,8 @@ mod tests { use nasl_builtin_std::ContextBuilder; use nasl_builtin_utils::Register; - use nasl_interpreter::Interpreter; - use nasl_syntax::{parse, NaslValue}; + use nasl_interpreter::CodeInterpreter; + use nasl_syntax::NaslValue; #[test] fn get_local_mac_address_from_ip() { @@ -20,13 +20,11 @@ mod tests { get_local_mac_address_from_ip("127.0.0.1"); get_local_mac_address_from_ip("::1"); "#; - let mut register = Register::default(); + let register = Register::default(); let mut binding = ContextBuilder::default(); binding.functions.push_executer(nasl_builtin_raw_ip::RawIp); let context = binding.build(); - let mut interpreter = Interpreter::new(&mut register, &context); - let mut parser = - parse(code).map(|x| interpreter.resolve(&x.expect("no parse error expected"))); + let mut parser = CodeInterpreter::new(code, register, &context); assert_eq!( parser.next(), Some(Ok(NaslValue::String("00:00:00:00:00:00".to_string()))) @@ -50,14 +48,12 @@ mod tests { ether_proto: 0x0806, payload: "abcd" ); dump_frame(frame:a); "#; - let mut register = Register::default(); + let register = Register::default(); let mut binding = ContextBuilder::default(); binding.functions.push_executer(nasl_builtin_raw_ip::RawIp); let context = binding.build(); - let mut interpreter = Interpreter::new(&mut register, &context); - let mut parser = - parse(code).map(|x| interpreter.resolve(&x.expect("no parse error expected"))); + let mut parser = CodeInterpreter::new(code, register, &context); parser.next(); parser.next(); assert_eq!( @@ -85,10 +81,8 @@ mod tests { let mut binding = ContextBuilder::default(); binding.functions.push_executer(nasl_builtin_raw_ip::RawIp); let context = binding.build(); - let mut register = Register::default(); - let mut interpreter = Interpreter::new(&mut register, &context); - let mut parser = - parse(code).map(|x| interpreter.resolve(&x.expect("no parse error expected"))); + let register = Register::default(); + let mut parser = CodeInterpreter::new(code, register, &context); parser.next(); parser.next(); assert_eq!( diff --git a/rust/nasl-builtin-raw-ip/tests/packet_forgery.rs b/rust/nasl-builtin-raw-ip/tests/packet_forgery.rs index 8e26630b1..70e8e0366 100644 --- a/rust/nasl-builtin-raw-ip/tests/packet_forgery.rs +++ b/rust/nasl-builtin-raw-ip/tests/packet_forgery.rs @@ -8,8 +8,8 @@ mod tests { use nasl_builtin_std::ContextBuilder; use nasl_builtin_utils::{error::FunctionErrorKind, Register}; - use nasl_interpreter::Interpreter; - use nasl_syntax::{parse, NaslValue}; + use nasl_interpreter::CodeInterpreter; + use nasl_syntax::NaslValue; /// Copy from a slice in safe way, performing the necessary test to avoid panicking fn safe_copy_from_slice( @@ -63,14 +63,12 @@ mod tests { th_sum: 0, th_urp: 0); "###; - let mut register = Register::default(); + let register = Register::default(); let mut binding = ContextBuilder::default(); binding.functions.push_executer(nasl_builtin_raw_ip::RawIp); let context = binding.build(); - let mut interpreter = Interpreter::new(&mut register, &context); - let mut parser = - parse(code).map(|x| interpreter.resolve(&x.expect("no parse error expected"))); + let mut parser = CodeInterpreter::new(code, register, &context); assert_eq!( parser.next(), Some(Ok(NaslValue::Data(vec![ @@ -105,14 +103,12 @@ mod tests { ip_packet = set_ip_elements(ip: ip_packet, ip_ttl: 127, ip_src: 192.168.0.10); elem = get_ip_element(ip: ip_packet, element: "ip_ttl"); "#; - let mut register = Register::default(); + let register = Register::default(); let mut binding = ContextBuilder::default(); binding.functions.push_executer(nasl_builtin_raw_ip::RawIp); let context = binding.build(); - let mut interpreter = Interpreter::new(&mut register, &context); - let mut parser = - parse(code).map(|x| interpreter.resolve(&x.expect("no parse error expected"))); + let mut parser = CodeInterpreter::new(code, register, &context); parser.next(); assert_eq!(parser.next(), Some(Ok(NaslValue::Number(255)))); parser.next(); @@ -136,14 +132,12 @@ mod tests { ip_packet = insert_ip_options(ip: ip_packet, code: 131, length:5, value: "12"); opt = get_ip_element(ip: ip_packet, element: "ip_hl"); "#; - let mut register = Register::default(); + let register = Register::default(); let mut binding = ContextBuilder::default(); binding.functions.push_executer(nasl_builtin_raw_ip::RawIp); let context = binding.build(); - let mut interpreter = Interpreter::new(&mut register, &context); - let mut parser = - parse(code).map(|x| interpreter.resolve(&x.expect("no parse error expected"))); + let mut parser = CodeInterpreter::new(code, register, &context); parser.next(); parser.next(); assert_eq!(parser.next(), Some(Ok(NaslValue::Number(8)))); @@ -178,14 +172,12 @@ mod tests { tcp_packet = insert_tcp_options(tcp: tcp_packet, 3, 2); opt = get_tcp_option(tcp: tcp_packet, option: 3); "###; - let mut register = Register::default(); + let register = Register::default(); let mut binding = ContextBuilder::default(); binding.functions.push_executer(nasl_builtin_raw_ip::RawIp); let context = binding.build(); - let mut interpreter = Interpreter::new(&mut register, &context); - let mut parser = - parse(code).map(|x| interpreter.resolve(&x.expect("no parse error expected"))); + let mut parser = CodeInterpreter::new(code, register, &context); parser.next(); parser.next(); parser.next(); @@ -213,14 +205,12 @@ mod tests { th_sum: 0, data: "1234"); "#; - let mut register = Register::default(); + let register = Register::default(); let mut binding = ContextBuilder::default(); binding.functions.push_executer(nasl_builtin_raw_ip::RawIp); let context = binding.build(); - let mut interpreter = Interpreter::new(&mut register, &context); - let mut parser = - parse(code).map(|x| interpreter.resolve(&x.expect("no parse error expected"))); + let mut parser = CodeInterpreter::new(code, register, &context); assert_eq!( parser.next(), Some(Ok(NaslValue::Data(vec![ @@ -257,14 +247,12 @@ mod tests { icmp_id: 1, data: "1234"); "#; - let mut register = Register::default(); + let register = Register::default(); let mut binding = ContextBuilder::default(); binding.functions.push_executer(nasl_builtin_raw_ip::RawIp); let context = binding.build(); - let mut interpreter = Interpreter::new(&mut register, &context); - let mut parser = - parse(code).map(|x| interpreter.resolve(&x.expect("no parse error expected"))); + let mut parser = CodeInterpreter::new(code, register, &context); parser.next(); assert_eq!( parser.next(), @@ -295,14 +283,12 @@ mod tests { group: 224.0.0.1, ); "###; - let mut register = Register::default(); + let register = Register::default(); let mut binding = ContextBuilder::default(); binding.functions.push_executer(nasl_builtin_raw_ip::RawIp); let context = binding.build(); - let mut interpreter = Interpreter::new(&mut register, &context); - let mut parser = - parse(code).map(|x| interpreter.resolve(&x.expect("no parse error expected"))); + let mut parser = CodeInterpreter::new(code, register, &context); parser.next(); assert_eq!( parser.next(), diff --git a/rust/nasl-builtin-std/src/lib.rs b/rust/nasl-builtin-std/src/lib.rs index 9f54f00bc..28909ca48 100644 --- a/rust/nasl-builtin-std/src/lib.rs +++ b/rust/nasl-builtin-std/src/lib.rs @@ -234,6 +234,7 @@ impl, S> ContextBuilder { impl> ContextBuilder> { /// Creates a new context builder with the given key and storage. + // TODO remove key and move it to build as they change per script call pub fn new(key: K, storage: Box>) -> Self { Self { key: KeyDispatcherSet { key, storage }, diff --git a/rust/nasl-builtin-std/tests/array.rs b/rust/nasl-builtin-std/tests/array.rs index 45e421d03..6b8d30362 100644 --- a/rust/nasl-builtin-std/tests/array.rs +++ b/rust/nasl-builtin-std/tests/array.rs @@ -8,8 +8,8 @@ mod tests { use nasl_builtin_std::ContextBuilder; use nasl_builtin_utils::Register; - use nasl_interpreter::Interpreter; - use nasl_syntax::{parse, NaslValue}; + use nasl_interpreter::CodeInterpreter; + use nasl_syntax::NaslValue; macro_rules! make_dict { ($($key:expr => $val:expr),*) => { { @@ -34,12 +34,10 @@ mod tests { make_array(1); make_array(); "###; - let mut register = Register::default(); + let register = Register::default(); let binding = ContextBuilder::default(); let context = binding.build(); - let mut interpreter = Interpreter::new(&mut register, &context); - let mut parser = - parse(code).map(|x| interpreter.resolve(&x.expect("no parse error expected"))); + let mut parser = CodeInterpreter::new(code, register, &context); assert_eq!(parser.next(), Some(Ok(make_dict!(1 => 0i64, 2 => 1i64)))); assert_eq!(parser.next(), Some(Ok(make_dict!(1 => 0i64, 2 => 1i64)))); assert_eq!(parser.next(), Some(Ok(make_dict!()))); @@ -57,12 +55,10 @@ mod tests { make_list(1, 0, b); make_list(1, 0, a); "#; - let mut register = Register::default(); + let register = Register::default(); let binding = ContextBuilder::default(); let context = binding.build(); - let mut interpreter = Interpreter::new(&mut register, &context); - let mut parser = - parse(code).map(|x| interpreter.resolve(&x.expect("no parse error expected"))); + let mut parser = CodeInterpreter::new(code, register, &context); assert_eq!( parser.next(), Some(Ok(NaslValue::Array(vec![ @@ -112,12 +108,10 @@ mod tests { l = make_list("abbb", 1, "aaaa", 0, a); s = sort(l); "#; - let mut register = Register::default(); + let register = Register::default(); let binding = ContextBuilder::default(); let context = binding.build(); - let mut interpreter = Interpreter::new(&mut register, &context); - let mut parser = - parse(code).map(|x| interpreter.resolve(&x.expect("no parse error expected"))); + let mut parser = CodeInterpreter::new(code, register, &context); parser.next(); parser.next(); let a = parser.next(); @@ -139,12 +133,10 @@ mod tests { l = make_list("foo", "bar"); keys(a,l); "#; - let mut register = Register::default(); + let register = Register::default(); let binding = ContextBuilder::default(); let context = binding.build(); - let mut interpreter = Interpreter::new(&mut register, &context); - let mut parser = - parse(code).map(|x| interpreter.resolve(&x.expect("no parse error expected"))); + let mut parser = CodeInterpreter::new(code, register, &context); parser.next(); parser.next(); let a = parser.next(); @@ -166,12 +158,10 @@ mod tests { max_index(make_list(1, 0)); max_index(make_list()); "###; - let mut register = Register::default(); + let register = Register::default(); let binding = ContextBuilder::default(); let context = binding.build(); - let mut interpreter = Interpreter::new(&mut register, &context); - let mut parser = - parse(code).map(|x| interpreter.resolve(&x.expect("no parse error expected"))); + let mut parser = CodeInterpreter::new(code, register, &context); parser.next(); assert_eq!(parser.next(), Some(Ok(NaslValue::Number(5)))); assert_eq!(parser.next(), Some(Ok(NaslValue::Number(3)))); diff --git a/rust/nasl-builtin-string/tests/string.rs b/rust/nasl-builtin-string/tests/string.rs index d36c3b572..43f0861c4 100644 --- a/rust/nasl-builtin-string/tests/string.rs +++ b/rust/nasl-builtin-string/tests/string.rs @@ -15,12 +15,10 @@ mod tests { hexstr(); hexstr(raw_string(10, 208, 102, 165, 210, 159, 63, 42, 42, 28, 124, 23, 221, 8, 42, 121)); "#; - let mut register = Register::default(); + let register = Register::default(); let binding = ContextBuilder::default(); let context = binding.build(); - let mut interpreter = Interpreter::new(&mut register, &context); - let mut parser = - parse(code).map(|x| interpreter.resolve(&x.expect("no parse error expected"))); + let mut parser = CodeInterpreter::new(code, register, &context); parser.next(); assert_eq!(parser.next(), Some(Ok("666f6f".into()))); assert_eq!(parser.next(), Some(Ok("666f6f".into()))); @@ -40,12 +38,10 @@ mod tests { raw_string(0x7B, 1); raw_string(0x7B, 1, "Hallo"); "#; - let mut register = Register::default(); + let register = Register::default(); let binding = ContextBuilder::default(); let context = binding.build(); - let mut interpreter = Interpreter::new(&mut register, &context); - let mut parser = - parse(code).map(|x| interpreter.resolve(&x.expect("no parse error expected"))); + let mut parser = CodeInterpreter::new(code, register, &context); assert_eq!(parser.next(), Some(Ok(vec![123].into()))); assert_eq!(parser.next(), Some(Ok(vec![123, 1].into()))); assert_eq!( @@ -59,12 +55,10 @@ mod tests { tolower(0x7B); tolower('HALLO'); "###; - let mut register = Register::default(); + let register = Register::default(); let binding = ContextBuilder::default(); let context = binding.build(); - let mut interpreter = Interpreter::new(&mut register, &context); - let mut parser = - parse(code).map(|x| interpreter.resolve(&x.expect("no parse error expected"))); + let mut parser = CodeInterpreter::new(code, register, &context); assert_eq!(parser.next(), Some(Ok(NaslValue::Null))); assert_eq!(parser.next(), Some(Ok("hallo".into()))); } @@ -74,12 +68,10 @@ mod tests { toupper(0x7B); toupper('hallo'); "###; - let mut register = Register::default(); + let register = Register::default(); let binding = ContextBuilder::default(); let context = binding.build(); - let mut interpreter = Interpreter::new(&mut register, &context); - let mut parser = - parse(code).map(|x| interpreter.resolve(&x.expect("no parse error expected"))); + let mut parser = CodeInterpreter::new(code, register, &context); assert_eq!(parser.next(), Some(Ok(NaslValue::Null))); assert_eq!(parser.next(), Some(Ok("HALLO".into()))); } @@ -89,12 +81,10 @@ mod tests { strlen(0x7B); strlen('hallo'); "###; - let mut register = Register::default(); + let register = Register::default(); let binding = ContextBuilder::default(); let context = binding.build(); - let mut interpreter = Interpreter::new(&mut register, &context); - let mut parser = - parse(code).map(|x| interpreter.resolve(&x.expect("no parse error expected"))); + let mut parser = CodeInterpreter::new(code, register, &context); assert_eq!(parser.next(), Some(Ok(0i64.into()))); assert_eq!(parser.next(), Some(Ok(5i64.into()))); } @@ -106,12 +96,10 @@ mod tests { string(0x7B, 1, "Hallo"); string(0x7B, 1, NULL, "Hallo"); "#; - let mut register = Register::default(); + let register = Register::default(); let binding = ContextBuilder::default(); let context = binding.build(); - let mut interpreter = Interpreter::new(&mut register, &context); - let mut parser = - parse(code).map(|x| interpreter.resolve(&x.expect("no parse error expected"))); + let mut parser = CodeInterpreter::new(code, register, &context); assert_eq!(parser.next(), Some(Ok("123".into()))); assert_eq!(parser.next(), Some(Ok("1231".into()))); assert_eq!(parser.next(), Some(Ok("1231Hallo".into()))); @@ -125,12 +113,10 @@ mod tests { substr("hello", 0, 4); substr("hello", 6); "#; - let mut register = Register::default(); + let register = Register::default(); let binding = ContextBuilder::default(); let context = binding.build(); - let mut interpreter = Interpreter::new(&mut register, &context); - let mut parser = - parse(code).map(|x| interpreter.resolve(&x.expect("no parse error expected"))); + let mut parser = CodeInterpreter::new(code, register, &context); assert_eq!(parser.next(), Some(Ok("ello".into()))); assert_eq!(parser.next(), Some(Ok("hell".into()))); assert_eq!(parser.next(), Some(Ok(NaslValue::Null))); @@ -143,12 +129,10 @@ mod tests { crap(length: 5); crap(data: "ab", length: 5); "#; - let mut register = Register::default(); + let register = Register::default(); let binding = ContextBuilder::default(); let context = binding.build(); - let mut interpreter = Interpreter::new(&mut register, &context); - let mut parser = - parse(code).map(|x| interpreter.resolve(&x.expect("no parse error expected"))); + let mut parser = CodeInterpreter::new(code, register, &context); assert_eq!(parser.next(), Some(Ok("XXXXX".into()))); assert_eq!(parser.next(), Some(Ok("XXXXX".into()))); assert_eq!(parser.next(), Some(Ok("ababababab".into()))); @@ -162,12 +146,10 @@ mod tests { chomp("abc "); chomp("abc\n\t\r "); "#; - let mut register = Register::default(); + let register = Register::default(); let binding = ContextBuilder::default(); let context = binding.build(); - let mut interpreter = Interpreter::new(&mut register, &context); - let mut parser = - parse(code).map(|x| interpreter.resolve(&x.expect("no parse error expected"))); + let mut parser = CodeInterpreter::new(code, register, &context); assert_eq!(parser.next(), Some(Ok("abc".into()))); assert_eq!(parser.next(), Some(Ok("abc".into()))); assert_eq!(parser.next(), Some(Ok("abc".into()))); @@ -184,12 +166,10 @@ mod tests { stridx("blahabc", "abc", 3); stridx("blahbc", "abc", 2); "#; - let mut register = Register::default(); + let register = Register::default(); let binding = ContextBuilder::default(); let context = binding.build(); - let mut interpreter = Interpreter::new(&mut register, &context); - let mut parser = - parse(code).map(|x| interpreter.resolve(&x.expect("no parse error expected"))); + let mut parser = CodeInterpreter::new(code, register, &context); assert_eq!(parser.next(), Some(Ok((-1_i64).into()))); assert_eq!(parser.next(), Some(Ok(1_i64.into()))); assert_eq!(parser.next(), Some(Ok(0_i64.into()))); @@ -203,12 +183,10 @@ mod tests { let code = r#" display("abc"); "#; - let mut register = Register::default(); + let register = Register::default(); let binding = ContextBuilder::default(); let context = binding.build(); - let mut interpreter = Interpreter::new(&mut register, &context); - let mut parser = - parse(code).map(|x| interpreter.resolve(&x.expect("no parse error expected"))); + let mut parser = CodeInterpreter::new(code, register, &context); assert_eq!(parser.next(), Some(Ok(NaslValue::Null))); } @@ -218,12 +196,10 @@ mod tests { a = hexstr_to_data("4bb3c4a4f893ad8c9bdc833c325d62b3"); data_to_hexstr(a); "#; - let mut register = Register::default(); + let register = Register::default(); let binding = ContextBuilder::default(); let context = binding.build(); - let mut interpreter = Interpreter::new(&mut register, &context); - let mut parser = - parse(code).map(|x| interpreter.resolve(&x.expect("no parse error expected"))); + let mut parser = CodeInterpreter::new(code, register, &context); assert_eq!( parser.next(), Some(Ok(NaslValue::Data(vec![ diff --git a/rust/nasl-builtin-utils/src/context.rs b/rust/nasl-builtin-utils/src/context.rs index 3c6853eb6..a4b09f85f 100644 --- a/rust/nasl-builtin-utils/src/context.rs +++ b/rust/nasl-builtin-utils/src/context.rs @@ -5,7 +5,7 @@ //! Defines the context used within the interpreter and utilized by the builtin functions use nasl_syntax::{logger::NaslLogger, Loader, NaslValue, Statement}; -use storage::{types::Primitive, Dispatcher, Field, Kb, Retriever}; +use storage::{Dispatcher, Retriever}; use crate::lookup_keys::FC_ANON_ARGS; @@ -114,6 +114,7 @@ impl From> for ContextType { /// When creating a new context call a corresponding create method. /// Warning since those will be stored within a vector each context must be manually /// deleted by calling drop_last when the context runs out of scope. +#[derive(Clone)] pub struct Register { blocks: Vec, } @@ -280,17 +281,14 @@ impl Default for Register { Self::new() } } -use std::{ - collections::HashMap, - time::{SystemTime, UNIX_EPOCH}, -}; +use std::collections::HashMap; type Named = HashMap; /// NaslContext is a struct to contain variables and if root declared functions /// /// A context should never be created directly but via a Register. /// The reason for that is that a Registrat contains all blocks and a block must be registered to ensure that each Block must be created via an Registrat. -#[derive(Default)] +#[derive(Default, Clone)] pub struct NaslContext { /// Parent id within the register parent: Option, @@ -409,47 +407,6 @@ impl<'a, K> Context<'a, K> { pub fn loader(&self) -> &dyn Loader { self.loader } - /// Get a KB item - pub fn get_kb_item(&self, name: &str) -> super::NaslResult { - self.retriever() - .retrieve(self.key, storage::Retrieve::KB(name.to_string())) - .map(|r| { - r.into_iter().find_map(|x| match x { - Field::NVT(_) | Field::NotusAdvisory(_) => None, - Field::KB(kb) => kb.value.into(), - }) - }) - .map(|x| match x { - Some(x) => x.into(), - None => NaslValue::Null, - }) - .map_err(|e| e.into()) - } - /// Set a KB item - pub fn set_kb_item( - &self, - key: String, - value: Primitive, - expires_in: Option, - ) -> super::NaslResult { - self.dispatcher() - .dispatch( - self.key(), - Field::KB(Kb { - key, - value, - expire: expires_in.map(|seconds| { - let start = SystemTime::now(); - match start.duration_since(UNIX_EPOCH) { - Ok(x) => x.as_secs() + seconds, - Err(_) => 0, - } - }), - }), - ) - .map(|_| NaslValue::Null) - .map_err(|e| e.into()) - } } impl From<&ContextType> for NaslValue { diff --git a/rust/nasl-interpreter/Cargo.toml b/rust/nasl-interpreter/Cargo.toml index 7befd4426..f750dc803 100644 --- a/rust/nasl-interpreter/Cargo.toml +++ b/rust/nasl-interpreter/Cargo.toml @@ -11,6 +11,7 @@ nasl-builtin-utils = {path = "../nasl-builtin-utils"} nasl-builtin-std = {path = "../nasl-builtin-std", default-features = false} # used for !~ =~ string regex operations regex = "1" +tracing = "0.1.40" [features] nasl-builtin-raw-ip = ["nasl-builtin-std/nasl-builtin-raw-ip"] diff --git a/rust/nasl-interpreter/README.md b/rust/nasl-interpreter/README.md index 0ee4627b5..4da667406 100644 --- a/rust/nasl-interpreter/README.md +++ b/rust/nasl-interpreter/README.md @@ -20,14 +20,12 @@ An interpreter requires: ## Example ``` -use nasl_interpreter::{Interpreter, Register, ContextBuilder}; +use nasl_interpreter::{CodeInterpreter, Register, ContextBuilder}; let mut register = Register::default(); let context_builder = ContextBuilder::default(); let context = context_builder.build(); let code = "display('hi');"; -let mut interpreter = Interpreter::new(&mut register, &context); -let mut parser = - nasl_syntax::parse(code).map(|x| interpreter.resolve(&x.expect("no parse error expected"))); +let mut parser = CodeInterpreter::new(code, register, &context); ``` diff --git a/rust/nasl-interpreter/src/assign.rs b/rust/nasl-interpreter/src/assign.rs index ad40f829f..316933fbf 100644 --- a/rust/nasl-interpreter/src/assign.rs +++ b/rust/nasl-interpreter/src/assign.rs @@ -56,13 +56,13 @@ where K: AsRef, { fn save(&mut self, idx: usize, key: &str, value: NaslValue) { - self.registrat + self.register_mut() .add_to_index(idx, key, ContextType::Value(value)); } fn named_value(&self, key: &str) -> Result<(usize, NaslValue), InterpretError> { match self - .registrat() + .register() .index_named(key) .unwrap_or((0, &ContextType::Value(NaslValue::Null))) { @@ -276,12 +276,10 @@ mod tests { a--; --a; "###; - let mut register = Register::default(); + let register = Register::default(); let binding = ContextBuilder::default(); let context = binding.build(); - let mut interpreter = Interpreter::new(&mut register, &context); - let mut parser = - parse(code).map(|x| interpreter.resolve(&x.expect("no parse error expected"))); + let mut parser = CodeInterpreter::new(code, register, &context); assert_eq!(parser.next(), Some(Ok(12.into()))); assert_eq!(parser.next(), Some(Ok(25.into()))); assert_eq!(parser.next(), Some(Ok(23.into()))); @@ -311,12 +309,10 @@ mod tests { a[0]++; ++a[0]; "###; - let mut register = Register::default(); + let register = Register::default(); let binding = ContextBuilder::default(); let context = binding.build(); - let mut interpreter = Interpreter::new(&mut register, &context); - let mut parser = - parse(code).map(|x| interpreter.resolve(&x.expect("no parse error expected"))); + let mut parser = CodeInterpreter::new(code, register, &context); assert_eq!(parser.next(), Some(Ok(12.into()))); assert_eq!(parser.next(), Some(Ok(25.into()))); assert_eq!(parser.next(), Some(Ok(23.into()))); @@ -335,12 +331,10 @@ mod tests { a[2] = 12; a; "###; - let mut register = Register::default(); + let register = Register::default(); let binding = ContextBuilder::default(); let context = binding.build(); - let mut interpreter = Interpreter::new(&mut register, &context); - let mut parser = - parse(code).map(|x| interpreter.resolve(&x.expect("no parse error expected"))); + let mut parser = CodeInterpreter::new(code, register, &context); assert_eq!(parser.next(), Some(Ok(12.into()))); assert_eq!( parser.next(), @@ -360,12 +354,10 @@ mod tests { a[2] = 12; a; "###; - let mut register = Register::default(); + let register = Register::default(); let binding = ContextBuilder::default(); let context = binding.build(); - let mut interpreter = Interpreter::new(&mut register, &context); - let mut parser = - parse(code).map(|x| interpreter.resolve(&x.expect("no parse error expected"))); + let mut parser = CodeInterpreter::new(code, register, &context); assert_eq!(parser.next(), Some(Ok(12.into()))); assert_eq!(parser.next(), Some(Ok(12.into()))); assert_eq!(parser.next(), Some(Ok(12.into()))); @@ -386,12 +378,10 @@ mod tests { a; a['hi']; "###; - let mut register = Register::default(); + let register = Register::default(); let binding = ContextBuilder::default(); let context = binding.build(); - let mut interpreter = Interpreter::new(&mut register, &context); - let mut parser = - parse(code).map(|x| interpreter.resolve(&x.expect("no parse error expected"))); + let mut parser = CodeInterpreter::new(code, register, &context); assert_eq!(parser.next(), Some(Ok(12.into()))); assert_eq!( parser.next(), @@ -408,12 +398,10 @@ mod tests { let code = r###" a = [1, 2, 3]; "###; - let mut register = Register::default(); + let register = Register::default(); let binding = ContextBuilder::default(); let context = binding.build(); - let mut interpreter = Interpreter::new(&mut register, &context); - let mut parser = - parse(code).map(|x| interpreter.resolve(&x.expect("no parse error expected"))); + let mut parser = CodeInterpreter::new(code, register, &context); assert_eq!( parser.next(), Some(Ok(NaslValue::Array(vec![1.into(), 2.into(), 3.into()]))) diff --git a/rust/nasl-interpreter/src/call.rs b/rust/nasl-interpreter/src/call.rs index 8533833c3..389dc55a8 100644 --- a/rust/nasl-interpreter/src/call.rs +++ b/rust/nasl-interpreter/src/call.rs @@ -7,7 +7,7 @@ use nasl_syntax::{Statement, StatementKind::*, Token}; use crate::{ error::{FunctionError, InterpretError}, - interpreter::InterpretResult, + interpreter::{InterpretResult, RunSpecific}, Interpreter, }; @@ -47,12 +47,41 @@ where FC_ANON_ARGS.to_owned(), ContextType::Value(NaslValue::Array(position)), ); - self.registrat.create_root_child(named); - let result = match self.ctxconfigs.nasl_fn_execute(name, self.registrat) { - Some(r) => r.map_err(|x| FunctionError::new(name, x).into()), + self.register_mut().create_root_child(named); + let result = match self.ctxconfigs.nasl_fn_execute(name, self.register()) { + Some(r) => { + if let Ok(NaslValue::Fork(mut x)) = r { + Ok(if let Some(r) = x.pop() { + // this is a proposal for the case that the caller is immediately executing + // if not the position needs to be reset + if self.index == 0 { + let position = self.position().current_init_statement(); + for i in x { + tracing::trace!(return_value=?i, return_position=?self.position(), interpreter_position=?position, "creating interpreter instance" ); + self.run_specific.push(RunSpecific { + register: self.register().clone(), + position: position.clone(), + skip_until_return: Some((self.position().clone(), i)), + }); + } + } else { + tracing::trace!( + index = self.index, + "we only allow expanding of executions (fork) on root instance" + ); + } + tracing::trace!(return_value=?r, "returning interpreter instance" ); + r + } else { + NaslValue::Null + }) + } else { + r.map_err(|x| FunctionError::new(name, x).into()) + } + } None => { let found = self - .registrat + .register() .named(name) .ok_or_else(|| InterpretError::not_found(name))? .clone(); @@ -60,10 +89,10 @@ where ContextType::Function(params, stmt) => { // prepare default values for p in params { - match self.registrat.named(&p) { + match self.register().named(&p) { None => { // add default NaslValue::Null for each defined params - self.registrat + self.register_mut() .add_local(&p, ContextType::Value(NaslValue::Null)); } Some(_) => {} @@ -78,7 +107,7 @@ where } } }; - self.registrat.drop_last(); + self.register_mut().drop_last(); result } } @@ -97,12 +126,10 @@ mod tests { test(a: 1); test(); "###; - let mut register = Register::default(); + let register = Register::default(); let binding = ContextBuilder::default(); let context = binding.build(); - let mut interpreter = Interpreter::new(&mut register, &context); - let mut parser = - parse(code).map(|x| interpreter.resolve(&x.expect("unexpected parse error"))); + let mut parser = CodeInterpreter::new(code, register, &context); assert_eq!(parser.next(), Some(Ok(NaslValue::Null))); assert_eq!(parser.next(), Some(Ok(3.into()))); assert_eq!(parser.next(), Some(Ok(1.into()))); diff --git a/rust/nasl-interpreter/src/declare.rs b/rust/nasl-interpreter/src/declare.rs index a39f810c6..a230f1b87 100644 --- a/rust/nasl-interpreter/src/declare.rs +++ b/rust/nasl-interpreter/src/declare.rs @@ -39,7 +39,7 @@ where _ => return Err(InterpretError::unsupported(a, "variable")), } } - self.registrat + self.register_mut() .add_global(name, ContextType::Function(names, execution.clone())); Ok(NaslValue::Null) } @@ -49,16 +49,19 @@ pub(crate) trait DeclareVariableExtension { fn declare_variable(&mut self, scope: &Token, stmts: &[Statement]) -> InterpretResult; } -impl<'a, K> DeclareVariableExtension for Interpreter<'a, K> { +impl<'a, K> DeclareVariableExtension for Interpreter<'a, K> +where + K: AsRef, +{ fn declare_variable(&mut self, scope: &Token, stmts: &[Statement]) -> InterpretResult { let mut add = |key: &str| { let value = ContextType::Value(NaslValue::Null); match scope.category() { TokenCategory::Identifier(nasl_syntax::IdentifierType::GlobalVar) => { - self.registrat.add_global(key, value) + self.register_mut().add_global(key, value) } TokenCategory::Identifier(nasl_syntax::IdentifierType::LocalVar) => { - self.registrat.add_local(key, value) + self.register_mut().add_local(key, value) } _ => unreachable!( "{} should not be identified as an declare statement", @@ -93,12 +96,10 @@ mod tests { test(a: 1, b: 2); c; "###; - let mut register = Register::default(); + let register = Register::default(); let binding = ContextBuilder::default(); let context = binding.build(); - let mut interpreter = Interpreter::new(&mut register, &context); - let mut parser = - parse(code).map(|x| interpreter.resolve(&x.expect("unexpected parse error"))); + let mut parser = CodeInterpreter::new(code, register, &context); assert_eq!(parser.next(), Some(Ok(NaslValue::Null))); assert_eq!(parser.next(), Some(Ok(3.into()))); assert!(matches!(parser.next(), Some(Ok(NaslValue::Null)))); // not found @@ -112,12 +113,10 @@ mod tests { } test(a: 1, b: 2); "###; - let mut register = Register::default(); + let register = Register::default(); let binding = ContextBuilder::default(); let context = binding.build(); - let mut interpreter = Interpreter::new(&mut register, &context); - let mut parser = - parse(code).map(|x| interpreter.resolve(&x.expect("unexpected parse error"))); + let mut parser = CodeInterpreter::new(code, register, &context); assert_eq!(parser.next(), Some(Ok(NaslValue::Null))); assert_eq!(parser.next(), Some(Ok(3.into()))); } diff --git a/rust/nasl-interpreter/src/fork_interpreter.rs b/rust/nasl-interpreter/src/fork_interpreter.rs new file mode 100644 index 000000000..3e85243fa --- /dev/null +++ b/rust/nasl-interpreter/src/fork_interpreter.rs @@ -0,0 +1,147 @@ +//! Contains implementations of Interpreter that handle the simulation of forking methods for the +//! caller. + +use nasl_syntax::Statement; + +use crate::interpreter::InterpretResult; + +/// To allow closures we use a heap stored statement consumer +pub type StatementConsumer = Box; +/// Uses given code to return results based on that. +pub struct CodeInterpreter<'a, 'b, K> { + lexer: nasl_syntax::Lexer<'b>, + interpreter: crate::interpreter::Interpreter<'a, K>, + statement: Option, + /// call back function for Statements before they get interpret + pub statement_cb: Option, +} + +impl<'a, 'b, K> CodeInterpreter<'a, 'b, K> +where + K: AsRef, +{ + /// Creates a new code interpreter + /// + /// Example: + /// ``` + /// use nasl_syntax::NaslValue; + /// use nasl_interpreter::{Register, ContextBuilder, CodeInterpreter}; + /// let register = Register::default(); + /// let context_builder = ContextBuilder::default(); + /// let context = context_builder.build(); + /// let code = r#" + /// set_kb_item(name: "test", value: 1); + /// set_kb_item(name: "test", value: 2); + /// display(get_kb_item("test")); + /// "#; + /// let interpreter = CodeInterpreter::new(code, register, &context); + /// let results = interpreter.filter_map(|x|x.ok()).collect::>(); + /// assert_eq!(results, vec![NaslValue::Null; 4]); + /// ``` + pub fn new( + code: &'b str, + register: crate::Register, + context: &'a crate::Context<'a, K>, + ) -> CodeInterpreter<'a, 'b, K> { + let token = nasl_syntax::Tokenizer::new(code); + let lexer = nasl_syntax::Lexer::new(token); + let interpreter = crate::interpreter::Interpreter::new(register, context); + Self { + lexer, + interpreter, + statement: None, + statement_cb: None, + } + } + + /// Creates a new code interpreter with a callback before a statement gets executed + /// + /// Example: + /// ``` + /// use nasl_syntax::NaslValue; + /// use nasl_interpreter::{Register, ContextBuilder, CodeInterpreter}; + /// let register = Register::default(); + /// let context_builder = ContextBuilder::default(); + /// let context = context_builder.build(); + /// let code = r#" + /// set_kb_item(name: "test", value: 1); + /// set_kb_item(name: "test", value: 2); + /// display(get_kb_item("test")); + /// "#; + /// let interpreter = CodeInterpreter::with_statement_callback(code, register, &context, &|x|println!("{x}")); + /// let results = interpreter.filter_map(|x|x.ok()).collect::>(); + /// assert_eq!(results, vec![NaslValue::Null; 4]); + /// ``` + pub fn with_statement_callback( + code: &'b str, + register: crate::Register, + context: &'a crate::Context<'a, K>, + cb: &'static dyn Fn(&Statement), + ) -> CodeInterpreter<'a, 'b, K> { + let mut result = Self::new(code, register, context); + result.statement_cb = Some(Box::new(cb)); + result + } + + fn next_statement(&mut self) -> Option { + self.statement = None; + match self.lexer.next() { + Some(Ok(nstmt)) => { + if let Some(cb) = &self.statement_cb { + cb(&nstmt); + } + let results = Some(self.interpreter.retry_resolve_next(&nstmt, 5)); + self.statement = Some(nstmt); + results + } + Some(Err(err)) => Some(Err(err.into())), + None => None, + } + } + + /// Returns the Register of the underlying Interpreter + pub fn register(&self) -> &crate::Register { + self.interpreter.register() + } +} + +impl<'a, 'b, K> Iterator for CodeInterpreter<'a, 'b, K> +where + K: AsRef, +{ + type Item = InterpretResult; + + fn next(&mut self) -> Option { + if let Some(stmt) = self.statement.as_ref() { + match self.interpreter.next_interpreter() { + Some(inter) => Some(inter.retry_resolve(stmt, 5)), + None => self.next_statement(), + } + } else { + self.next_statement() + } + } +} + +#[cfg(test)] +mod rests { + #[test] + fn code_interpreter() { + use crate::{CodeInterpreter, ContextBuilder, Register}; + use nasl_syntax::NaslValue; + let register = Register::default(); + let context_builder = ContextBuilder::default(); + let context = context_builder.build(); + let code = r#" + set_kb_item(name: "test", value: 1); + set_kb_item(name: "test", value: 2); + display(get_kb_item("test")); + "#; + let interpreter = + CodeInterpreter::with_statement_callback(code, register, &context, &|x| { + println!("{x}") + }); + let results = interpreter.filter_map(|x| x.ok()).collect::>(); + assert_eq!(results, vec![NaslValue::Null; 4]); + } +} diff --git a/rust/nasl-interpreter/src/include.rs b/rust/nasl-interpreter/src/include.rs index 479b65145..149b7ef3a 100644 --- a/rust/nasl-interpreter/src/include.rs +++ b/rust/nasl-interpreter/src/include.rs @@ -41,14 +41,13 @@ mod tests { a; test(); "#; - let mut register = Register::default(); + let register = Register::default(); let context = ContextBuilder { loader: Box::new(loader), ..Default::default() }; let ctx = context.build(); - let mut interpreter = Interpreter::new(&mut register, &ctx); - let mut interpreter = parse(code).map(|x| interpreter.resolve(&x.expect("expected"))); + let mut interpreter = CodeInterpreter::new(code, register, &ctx); assert_eq!(interpreter.next(), Some(Ok(NaslValue::Null))); assert_eq!(interpreter.next(), Some(Ok(12.into()))); assert_eq!( diff --git a/rust/nasl-interpreter/src/interpreter.rs b/rust/nasl-interpreter/src/interpreter.rs index 1d76d222c..d182b3e17 100644 --- a/rust/nasl-interpreter/src/interpreter.rs +++ b/rust/nasl-interpreter/src/interpreter.rs @@ -20,10 +20,86 @@ use crate::{ use nasl_builtin_utils::{Context, ContextType, Register}; +/// Is used to identify the depth of the current statement +/// +/// Initial call of retry_resolce sets the first element all others are only +#[derive(Debug, Clone, PartialEq, Eq)] +pub(crate) struct Position { + index: Vec, +} + +impl Position { + pub fn new(index: usize) -> Self { + Self { index: vec![index] } + } + + pub fn up(&mut self) { + self.index.push(0); + } + + pub fn down(&mut self) -> Option { + self.index.pop() + } + + pub fn current_init_statement(&self) -> Self { + Self { + index: vec![*self.index.first().unwrap_or(&0)], + } + } + + fn root_index(&self) -> usize { + *self.index.first().unwrap_or(&0) + } +} + +/// Contains data that is specific for a single run +/// +/// Some methods start multiple runs (e.g. get_kb_item) and need to have their own specific data to +/// manipulate. To make it more convencient the data that is bound to run is summarized within this +/// struct. +pub(crate) struct RunSpecific { + pub(crate) register: Register, + pub(crate) position: Position, + pub(crate) skip_until_return: Option<(Position, NaslValue)>, +} + +/// Workaround for Context 'a Captures and impl Iterator +/// +/// This is used for function that returns StatementIter as a impl Iterator (e.g. resolve_all). +pub trait ContextLifeTimeCapture<'a> {} +impl<'a, T: ?Sized> ContextLifeTimeCapture<'a> for T {} + +struct StatementIter<'a, 'b, K> { + interpreter: &'b mut Interpreter<'a, K>, + statement: Statement, +} + +impl<'a, 'b, K> Iterator for StatementIter<'a, 'b, K> +where + K: AsRef, +{ + type Item = InterpretResult; + + fn next(&mut self) -> Option { + if self.interpreter.index == self.interpreter.run_specific.len() { + self.interpreter.index = 0; + return None; + } + let results = if self.interpreter.index == 0 { + Some(self.interpreter.retry_resolve_next(&self.statement, 5)) + } else { + Some(self.interpreter.retry_resolve(&self.statement, 5)) + }; + self.interpreter.index += 1; + results + } +} + /// Used to interpret a Statement pub struct Interpreter<'a, K> { - pub(crate) registrat: &'a mut Register, + pub(crate) run_specific: Vec, pub(crate) ctxconfigs: &'a Context<'a, K>, + pub(crate) index: usize, } /// Interpreter always returns a NaslValue or an InterpretError @@ -35,11 +111,17 @@ impl<'a, K> Interpreter<'a, K> where K: AsRef, { - /// Creates a new Interpreter. - pub fn new(register: &'a mut Register, ctxconfigs: &'a Context) -> Self { + /// Creates a new Interpreter + pub fn new(register: Register, ctxconfigs: &'a Context) -> Self { + let root_run = RunSpecific { + register, + position: Position::new(0), + skip_until_return: None, + }; Interpreter { - registrat: register, + run_specific: vec![root_run], ctxconfigs, + index: 0, } } @@ -50,11 +132,51 @@ where } } + /// Returns an iterator over all possible interpretations of a Statement + pub fn resolve_all<'b>( + &'b mut self, + statement: Statement, + ) -> impl Iterator + ContextLifeTimeCapture<'a> + 'b { + StatementIter { + interpreter: self, + statement, + } + } + + /// May return the next interpreter to run against that statement + /// + /// When the interpreter are done a None will be returned. Afterwards it will begin at at 0 + /// again. This is done to inform the caller that all interpreter interpret this statement and + /// the next Statement can be executed. + // TODO remove in favor of iterrator of run_specific + pub fn next_interpreter(&mut self) -> Option<&mut Interpreter<'a, K>> { + if self.run_specific.len() == 1 || self.index + 1 == self.run_specific.len() { + return None; + } + + // if self.forked_interpreter.is_empty() { + // return None; + // } + tracing::trace!(amount = self.run_specific.len(), index = self.index,); + + self.index += 1; + Some(self) + } + + /// Includes a script into to the current runtime by executing it and share the register as + /// well as DB of the current runtime. + /// + // NOTE: This is currently optimized for interpreting runs, but it is very inefficient if we want to + // switch to a jitc approach or do parallelization of statements within a script. For that it + // would be necessary to include the statements within a statement list of a script prior of + // execution. In the current usage (2024-04-02) it would be overkill, but I'm writing a note as + // I think this can be easily overlooked. fn include(&mut self, name: &Statement) -> InterpretResult { match self.resolve(name)? { NaslValue::String(key) => { let code = self.ctxconfigs.loader().load(&key)?; - let mut inter = Interpreter::new(self.registrat, self.ctxconfigs); + + let mut inter = Interpreter::new(self.register().clone(), self.ctxconfigs); let result = nasl_syntax::parse(&code) .map(|parsed| match parsed { Ok(stmt) => inter.resolve(&stmt), @@ -63,13 +185,35 @@ where .find(|e| e.is_err()); match result { Some(e) => e, - None => Ok(NaslValue::Null), + None => { + self.set_register(inter.register().clone()); + + Ok(NaslValue::Null) + } } } _ => Err(InterpretError::unsupported(name, "string")), } } + /// Changes the internal position and tries to interpret a statement while retrying n times on specific error + /// + /// When encountering a retrievable error: + /// - LoadError(Retry(_)) + /// - StorageError(Retry(_)) + /// - IOError(Interrupted(_)) + /// + /// then it retries the statement for a given max_attempts times. + /// + /// When max_attempts is set to 0 it will it execute it once. + pub fn retry_resolve_next(&mut self, stmt: &Statement, max_attempts: usize) -> InterpretResult { + if let Some(last) = self.position_mut().index.last_mut() { + *last += 1; + } + self.index = 0; + self.retry_resolve(stmt, max_attempts) + } + /// Tries to interpret a statement and retries n times on a retry error /// /// When encountering a retrievable error: @@ -89,7 +233,7 @@ where InterpretErrorKind::LoadError(LoadError::Retry(_)) | InterpretErrorKind::IOError(io::ErrorKind::Interrupted) | InterpretErrorKind::StorageError(StorageError::Retry(_)) => { - self.retry_resolve(stmt, max_attempts - 1) + self.retry_resolve_next(stmt, max_attempts - 1) } _ => Err(e), } @@ -101,12 +245,34 @@ where } /// Interprets a Statement - pub fn resolve(&mut self, statement: &Statement) -> InterpretResult { - match statement.kind(){ + pub(crate) fn resolve(&mut self, statement: &Statement) -> InterpretResult { + self.position_mut().up(); + tracing::trace!(position=?self.position(), statement=statement.to_string(), "executing"); + // On a fork statement run we skip until the root index is reached. Between the root index + // of the return value and the position of the return value the interpretation is + // continued. This is done because the client just executes higher statements. + if let Some((cp, rv)) = &self.skip_until_return() { + tracing::trace!(check_position=?cp); + if self.position().root_index() < cp.root_index() { + tracing::trace!("skip execution"); + self.position_mut().down(); + return Ok(NaslValue::Null); + } + if cp == self.position() { + tracing::trace!(return=?rv, "skip execution and returning"); + let rv = rv.clone(); + self.set_skip_until_return(None); + self.position_mut().down(); + return Ok(rv); + } + } + + let results = { + match statement.kind(){ Array(position) => { let name = Self::identifier(statement.start())?; let val = self - .registrat + .register() .named(&name) .unwrap_or(&ContextType::Value(NaslValue::Null)); let val = val.clone(); @@ -157,7 +323,7 @@ where Primitive => TryFrom::try_from(statement.as_token()).map_err(|e: TokenCategory| e.into()), Variable => { let name: NaslValue = TryFrom::try_from(statement.as_token())?; - match self.registrat.named(&name.to_string()) { + match self.register().named(&name.to_string()) { Some(ContextType::Value(result)) => Ok(result.clone()), None => Ok(NaslValue::Null), Some(ContextType::Function(_, _)) => { @@ -190,7 +356,7 @@ where Err(err) => Err(err), }, Block(blocks) => { - self.registrat.create_child(HashMap::default()); + self.register_mut().create_child(HashMap::default()); for stmt in blocks { match self.resolve(stmt) { Ok(x) => { @@ -201,14 +367,14 @@ where | NaslValue::Break | NaslValue::Continue ) { - self.registrat.drop_last(); + self.register_mut().drop_last(); return Ok(x); } } Err(e) => return Err(e), } } - self.registrat.drop_last(); + self.register_mut().drop_last(); // currently blocks don't return something Ok(NaslValue::Null) } @@ -231,9 +397,40 @@ where e } }) + }; + self.position_mut().down(); + results + } + + /// Returns used register + pub fn register(&self) -> &Register { + &self.run_specific[self.index].register + } + + /// Returns used register + pub(crate) fn register_mut(&mut self) -> &mut Register { + &mut self.run_specific[self.index].register + } + + pub(crate) fn position_mut(&mut self) -> &mut Position { + &mut self.run_specific[self.index].position + } + + pub(crate) fn position(&self) -> &Position { + &self.run_specific[self.index].position + } + + fn set_register(&mut self, val: Register) { + let rs = &mut self.run_specific[self.index]; + rs.register = val; + } + + pub(crate) fn set_skip_until_return(&mut self, val: Option<(Position, NaslValue)>) { + let rs = &mut self.run_specific[self.index]; + rs.skip_until_return = val; } - pub(crate) fn registrat(&self) -> &Register { - self.registrat + pub(crate) fn skip_until_return(&self) -> Option<&(Position, NaslValue)> { + self.run_specific[self.index].skip_until_return.as_ref() } } diff --git a/rust/nasl-interpreter/src/lib.rs b/rust/nasl-interpreter/src/lib.rs index 3b752eddd..f5a77eefd 100644 --- a/rust/nasl-interpreter/src/lib.rs +++ b/rust/nasl-interpreter/src/lib.rs @@ -10,6 +10,7 @@ mod error; mod assign; mod call; mod declare; +mod fork_interpreter; mod include; mod interpreter; mod loop_extension; @@ -18,7 +19,10 @@ mod operator; pub use error::FunctionError; pub use error::InterpretError; pub use error::InterpretErrorKind; +pub use fork_interpreter::*; +pub use interpreter::ContextLifeTimeCapture; pub use interpreter::Interpreter; + // we expose the other libraries to allow users to use them without having to import them pub use nasl_builtin_std::{nasl_std_functions, ContextBuilder, KeyDispatcherSet, RegisterBuilder}; pub use nasl_builtin_utils::{ diff --git a/rust/nasl-interpreter/src/loop_extension.rs b/rust/nasl-interpreter/src/loop_extension.rs index 2df4b2fbc..dd9f7acde 100644 --- a/rust/nasl-interpreter/src/loop_extension.rs +++ b/rust/nasl-interpreter/src/loop_extension.rs @@ -112,7 +112,8 @@ where // Iterate through the iterable Statement for val in Vec::::from(self.resolve(iterable)?) { // Change the value of the iteration variable after each iteration - self.registrat.add_local(iter_name, ContextType::Value(val)); + self.register_mut() + .add_local(iter_name, ContextType::Value(val)); // Execute loop body let ret = self.resolve(body)?; @@ -181,8 +182,8 @@ mod tests { "###; let binding = ContextBuilder::default(); let context = binding.build(); - let mut register = Register::default(); - let mut interpreter = Interpreter::new(&mut register, &context); + let register = Register::default(); + let mut interpreter = Interpreter::new(register, &context); let mut interpreter = parse(code).map(|x| interpreter.resolve(&x.expect("unexpected parse error"))); assert_eq!(interpreter.next(), Some(Ok(0.into()))); @@ -199,10 +200,10 @@ mod tests { } a; "###; - let mut register = Register::default(); + let register = Register::default(); let binding = ContextBuilder::default(); let context = binding.build(); - let mut interpreter = Interpreter::new(&mut register, &context); + let mut interpreter = Interpreter::new(register, &context); let mut interpreter = parse(code).map(|x| interpreter.resolve(&x.expect("unexpected parse error"))); assert_eq!(interpreter.next(), Some(Ok(0.into()))); @@ -221,10 +222,10 @@ mod tests { } a; "###; - let mut register = Register::default(); + let register = Register::default(); let binding = ContextBuilder::default(); let context = binding.build(); - let mut interpreter = Interpreter::new(&mut register, &context); + let mut interpreter = Interpreter::new(register, &context); let mut interpreter = parse(code).map(|x| interpreter.resolve(&x.expect("unexpected parse error"))); assert_eq!(interpreter.next(), Some(Ok(3.into()))); @@ -247,10 +248,10 @@ mod tests { a; i; "###; - let mut register = Register::default(); + let register = Register::default(); let binding = ContextBuilder::default(); let context = binding.build(); - let mut interpreter = Interpreter::new(&mut register, &context); + let mut interpreter = Interpreter::new(register, &context); let mut interpreter = parse(code).map(|x| interpreter.resolve(&x.expect("unexpected parse error"))); assert_eq!(interpreter.next(), Some(Ok(4.into()))); @@ -274,10 +275,10 @@ mod tests { a; i; "###; - let mut register = Register::default(); + let register = Register::default(); let binding = ContextBuilder::default(); let context = binding.build(); - let mut interpreter = Interpreter::new(&mut register, &context); + let mut interpreter = Interpreter::new(register, &context); let mut interpreter = parse(code).map(|x| interpreter.resolve(&x.expect("unexpected parse error"))); assert_eq!(interpreter.next(), Some(Ok(10.into()))); @@ -306,10 +307,10 @@ mod tests { a; i; "###; - let mut register = Register::default(); + let register = Register::default(); let binding = ContextBuilder::default(); let context = binding.build(); - let mut interpreter = Interpreter::new(&mut register, &context); + let mut interpreter = Interpreter::new(register, &context); let mut interpreter = parse(code).map(|x| interpreter.resolve(&x.expect("unexpected parse error"))); assert_eq!(interpreter.next(), Some(Ok(0.into()))); diff --git a/rust/nasl-interpreter/src/operator.rs b/rust/nasl-interpreter/src/operator.rs index 82b0e82f2..690ba1134 100644 --- a/rust/nasl-interpreter/src/operator.rs +++ b/rust/nasl-interpreter/src/operator.rs @@ -256,10 +256,10 @@ mod tests { $( #[test] fn $name() { - let mut register = Register::default(); + let register = Register::default(); let binding = ContextBuilder::default(); let context = binding.build(); - let mut interpreter = Interpreter::new(&mut register, &context); + let mut interpreter = Interpreter::new(register, &context); let parser = parse($code).map(|x| interpreter.resolve(&x.expect("unexpected parse error")) ); diff --git a/rust/nasl-interpreter/tests/description.rs b/rust/nasl-interpreter/tests/description.rs index fb6e0b0ea..aed329855 100644 --- a/rust/nasl-interpreter/tests/description.rs +++ b/rust/nasl-interpreter/tests/description.rs @@ -72,7 +72,7 @@ if(description) "description".to_owned(), ContextType::Value(NaslValue::Number(1)), )]; - let mut register = Register::root_initial(&initial); + let register = Register::root_initial(&initial); let logger = DefaultLogger::default(); let key = "test.nasl".to_owned(); let target = String::new(); @@ -80,10 +80,10 @@ if(description) let ctxconfigs = Context::new( &key, &target, &storage, &storage, &loader, &logger, &functions, ); - let mut interpreter = Interpreter::new(&mut register, &ctxconfigs); + let mut interpreter = Interpreter::new(register, &ctxconfigs); let results = parse(code) .map(|stmt| match stmt { - Ok(stmt) => interpreter.resolve(&stmt), + Ok(stmt) => interpreter.retry_resolve_next(&stmt, 1), Err(r) => Err(InterpretError::from(r)), }) .last() diff --git a/rust/nasl-interpreter/tests/local_var.rs b/rust/nasl-interpreter/tests/local_var.rs index 51ef092ee..9d35220f8 100644 --- a/rust/nasl-interpreter/tests/local_var.rs +++ b/rust/nasl-interpreter/tests/local_var.rs @@ -20,12 +20,12 @@ if (a) { a; "###; let dc = ContextBuilder::default(); - let mut register = Register::default(); + let register = Register::default(); let ctx = dc.build(); - let mut interpreter = Interpreter::new(&mut register, &ctx); + let mut interpreter = Interpreter::new(register, &ctx); let results = parse(code) .map(|stmt| match stmt { - Ok(stmt) => interpreter.resolve(&stmt), + Ok(stmt) => interpreter.retry_resolve_next(&stmt, 1), Err(r) => Err(InterpretError::from(r)), }) .last() diff --git a/rust/nasl-syntax/src/lexer.rs b/rust/nasl-syntax/src/lexer.rs index 55ee56f9d..d91d08c35 100644 --- a/rust/nasl-syntax/src/lexer.rs +++ b/rust/nasl-syntax/src/lexer.rs @@ -43,13 +43,6 @@ impl End { End::Continue => false, } } - - // pub fn category(&self) -> &Option { - // match self { - // End::Done(t) => &Some(t.category), - // End::Continue => &None, - // } - // } } impl Not for End { diff --git a/rust/nasl-syntax/src/naslvalue.rs b/rust/nasl-syntax/src/naslvalue.rs index 8983f175d..752e115b6 100644 --- a/rust/nasl-syntax/src/naslvalue.rs +++ b/rust/nasl-syntax/src/naslvalue.rs @@ -28,6 +28,22 @@ pub enum NaslValue { Null, /// Returns value of the context Return(Box), + /// Creates n runs for each entry + /// + /// If the value is more than one element the interpreter creates n - 1 shadow clones from + /// itself and will execute each following statement based on each stored instance. This needs + /// to be done for downwards compatible reasons. Within `openvas` `get_kb_item` does create for + /// each item within found key when it is a list a fork to allow scripts like: + /// ```text + /// set_kb_item(name: "test", value: 1); + /// set_kb_item(name: "test", value: 2); + /// set_kb_item(name: "test", value: 3); + /// set_kb_item(name: "test", value: 4); + /// set_kb_item(name: "test", value: 5); + /// display(get_kb_item("test")); + /// ``` + /// to print each kb_item within test. + Fork(Vec), /// Signals continuing a loop Continue, /// Signals a break of a control structure @@ -99,6 +115,15 @@ impl Display for NaslValue { NaslValue::Return(rc) => write!(f, "return({:?})", *rc), NaslValue::Continue => write!(f, "continue"), NaslValue::Break => write!(f, "break"), + NaslValue::Fork(x) => write!( + f, + "Creates {} runs, for {}", + x.len(), + x.iter() + .map(|v| v.to_string()) + .collect::>() + .join(",") + ), } } } @@ -170,6 +195,7 @@ impl From for Vec { value.to_string().as_bytes().into() } NaslValue::AttackCategory(_) + | NaslValue::Fork(_) | NaslValue::Null | NaslValue::Return(_) | NaslValue::Continue @@ -194,6 +220,7 @@ impl From for bool { NaslValue::Return(_) => true, NaslValue::Continue => false, NaslValue::Break => false, + NaslValue::Fork(v) => v.is_empty(), } } } @@ -213,6 +240,7 @@ impl From<&NaslValue> for i64 { &NaslValue::Return(_) => -1, &NaslValue::Continue => 0, &NaslValue::Break => 0, + NaslValue::Fork(_) => 1, } } } diff --git a/rust/scannerctl/src/interpret/mod.rs b/rust/scannerctl/src/interpret/mod.rs index 629f1d11e..b1062f14a 100644 --- a/rust/scannerctl/src/interpret/mod.rs +++ b/rust/scannerctl/src/interpret/mod.rs @@ -6,8 +6,8 @@ use std::path::PathBuf; use feed::HashSumNameLoader; use nasl_interpreter::{ - load_non_utf8_path, logger::DefaultLogger, logger::NaslLogger, ContextBuilder, FSPluginLoader, - Interpreter, KeyDispatcherSet, LoadError, Loader, NaslValue, NoOpLoader, RegisterBuilder, + load_non_utf8_path, CodeInterpreter, ContextBuilder, FSPluginLoader, KeyDispatcherSet, + LoadError, Loader, NaslValue, NoOpLoader, RegisterBuilder, }; use redis_storage::FEEDUPDATE_SELECTOR; use storage::DefaultDispatcher; @@ -76,44 +76,37 @@ impl Run { } fn run(&self, script: &str) -> Result<(), CliErrorKind> { - let logger = DefaultLogger::default(); let context = self.context_builder.build(); - let mut register = RegisterBuilder::build(); - let mut interpreter = Interpreter::new(&mut register, &context); + let register = RegisterBuilder::build(); let code = self.load(script)?; - for stmt in nasl_syntax::parse(&code) { - match stmt { - Ok(stmt) => { - tracing::debug!("> {stmt}"); - let r = match interpreter.retry_resolve(&stmt, 5) { - Ok(x) => x, - Err(e) => match &e.kind { - nasl_interpreter::InterpretErrorKind::FunctionCallError( - nasl_interpreter::FunctionError { - function: _, - kind: nasl_interpreter::FunctionErrorKind::Diagnostic(_, x), - }, - ) => { - logger.warning(&e.to_string()); - x.clone().unwrap_or_default() - } - _ => return Err(e.into()), + let interpreter = + CodeInterpreter::with_statement_callback(&code, register, &context, &|x| { + tracing::debug!("> {x}") + }); + for result in interpreter { + let r = match result { + Ok(x) => x, + Err(e) => match &e.kind { + nasl_interpreter::InterpretErrorKind::FunctionCallError( + nasl_interpreter::FunctionError { + function: _, + kind: nasl_interpreter::FunctionErrorKind::Diagnostic(_, x), }, - }; - match r { - NaslValue::Exit(rc) => std::process::exit(rc as i32), - _ => { - tracing::debug!("=> {r:?}", r = r); - } + ) => { + tracing::warn!(error=?e, "function call error"); + x.clone().unwrap_or_default() } - } - - Err(e) => { - context.executor().nasl_fn_cache_clear(); - return Err(e.into()); - } + _ => return Err(e.into()), + }, }; + match r { + NaslValue::Exit(rc) => std::process::exit(rc as i32), + _ => { + tracing::debug!("=> {r:?}", r = r); + } + } } + context.executor().nasl_fn_cache_clear(); Ok(()) } diff --git a/rust/storage/src/retrieve.rs b/rust/storage/src/retrieve.rs index 563551253..df991c086 100644 --- a/rust/storage/src/retrieve.rs +++ b/rust/storage/src/retrieve.rs @@ -85,6 +85,8 @@ impl Retrieve { } /// Retrieves fields based on a key and scope. +// TODO: remove K infavor of a enum, as a user of that interface it is very hard to differentiate +// when to use an OID and when not. A better solution would be to use enums. pub trait Retriever { /// Gets Fields find by key and scope. This is to get all instances. fn retrieve( @@ -94,6 +96,8 @@ pub trait Retriever { ) -> Result>, StorageError>; /// Gets Fields find by field and scope. + /// + /// This is used to filter results. fn retrieve_by_field( &self, field: Field,