Skip to content

Commit

Permalink
Implemented cmd and repl in the cli completely, add also sandboxing p…
Browse files Browse the repository at this point in the history
…lugin in the cmd.
  • Loading branch information
viferga committed May 15, 2024
1 parent 799ddb8 commit d18f130
Show file tree
Hide file tree
Showing 18 changed files with 674 additions and 114 deletions.
89 changes: 35 additions & 54 deletions source/cli/metacallcli/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -211,10 +211,8 @@ add_test(NAME ${target}
COMMAND ${CMAKE_COMMAND} -D "EXECUTABLE=$<TARGET_FILE:${target}>" -D "INPUT=${TEST_COMMAND_INPUT}.txt" -P ${TEST_COMMAND_RUNNER}
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
)
set_property(TEST ${target}
PROPERTY LABELS ${target}
)
set_tests_properties(${target} PROPERTIES
LABELS ${target}
PASS_REGULAR_EXPRESSION "function three_str\\(a_str, b_str, c_str\\)"
)
test_environment_variables(${target}
Expand All @@ -239,10 +237,8 @@ if(OPTION_BUILD_LOADERS AND OPTION_BUILD_LOADERS_NODE AND OPTION_BUILD_SCRIPTS A
COMMAND ${CMAKE_COMMAND} -D "EXECUTABLE=$<TARGET_FILE:${target}>" -D "INPUT=${TEST_COMMAND_INPUT}-node.txt" -P ${TEST_COMMAND_RUNNER}
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
)
set_property(TEST ${target}-node
PROPERTY LABELS ${target}-node
)
set_tests_properties(${target}-node PROPERTIES
LABELS ${target}-node
PASS_REGULAR_EXPRESSION "4001534"
)
test_environment_variables(${target}-node
Expand All @@ -254,10 +250,8 @@ if(OPTION_BUILD_LOADERS AND OPTION_BUILD_LOADERS_NODE AND OPTION_BUILD_SCRIPTS A
COMMAND ${CMAKE_COMMAND} -D "EXECUTABLE=$<TARGET_FILE:${target}>" -D "INPUT=${TEST_COMMAND_INPUT}-node-port-py.txt" -P ${TEST_COMMAND_RUNNER}
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
)
set_property(TEST ${target}-node-port-py
PROPERTY LABELS ${target}-node-port-py
)
set_tests_properties(${target}-node-port-py PROPERTIES
LABELS ${target}-node-port-py
PASS_REGULAR_EXPRESSION "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
)
test_environment_variables(${target}-node-port-py
Expand All @@ -284,10 +278,8 @@ if(OPTION_BUILD_LOADERS AND OPTION_BUILD_LOADERS_NODE AND OPTION_BUILD_SCRIPTS A
COMMAND ${CMAKE_COMMAND} -D "EXECUTABLE=$<TARGET_FILE:${target}>" -D "INPUT=${TEST_COMMAND_INPUT}-node-null.txt" -P ${TEST_COMMAND_RUNNER}
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
)
set_property(TEST ${target}-node-null
PROPERTY LABELS ${target}-node-null
)
set_tests_properties(${target}-node-null PROPERTIES
LABELS ${target}-node-null
PASS_REGULAR_EXPRESSION "Hello 342521512461246!"
)
test_environment_variables(${target}-node-null
Expand All @@ -299,10 +291,8 @@ if(OPTION_BUILD_LOADERS AND OPTION_BUILD_LOADERS_NODE AND OPTION_BUILD_SCRIPTS A
COMMAND ${CMAKE_COMMAND} -D "EXECUTABLE=$<TARGET_FILE:${target}>" -D "INPUT=${TEST_COMMAND_INPUT}-node-null-empty.txt" -P ${TEST_COMMAND_RUNNER}
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
)
set_property(TEST ${target}-node-null-empty
PROPERTY LABELS ${target}-node-null-empty
)
set_tests_properties(${target}-node-null-empty PROPERTIES
LABELS ${target}-node-null-empty
PASS_REGULAR_EXPRESSION "Hello 342521512461246!"
)
test_environment_variables(${target}-node-null-empty
Expand All @@ -314,10 +304,8 @@ if(OPTION_BUILD_LOADERS AND OPTION_BUILD_LOADERS_NODE AND OPTION_BUILD_SCRIPTS A
COMMAND ${CMAKE_COMMAND} -D "EXECUTABLE=$<TARGET_FILE:${target}>" -D "INPUT=${TEST_COMMAND_INPUT}-node-null-undefined.txt" -P ${TEST_COMMAND_RUNNER}
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
)
set_property(TEST ${target}-node-null-undefined
PROPERTY LABELS ${target}-node-null-undefined
)
set_tests_properties(${target}-node-null-undefined PROPERTIES
LABELS ${target}-node-null-undefined
PASS_REGULAR_EXPRESSION "(null)"
)
test_environment_variables(${target}-node-null-undefined
Expand All @@ -330,10 +318,8 @@ if(OPTION_BUILD_LOADERS AND OPTION_BUILD_LOADERS_NODE AND OPTION_BUILD_SCRIPTS A
COMMAND ${CMAKE_COMMAND} -D "EXECUTABLE=$<TARGET_FILE:${target}>" -D "INPUT=${TEST_COMMAND_INPUT}-py-port.txt" -P ${TEST_COMMAND_RUNNER}
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
)
set_property(TEST ${target}-py-port
PROPERTY LABELS ${target}-py-port
)
set_tests_properties(${target}-py-port PROPERTIES
LABELS ${target}-py-port
PASS_REGULAR_EXPRESSION "1234"
)
test_environment_variables(${target}-py-port
Expand All @@ -346,10 +332,8 @@ if(OPTION_BUILD_LOADERS AND OPTION_BUILD_LOADERS_NODE AND OPTION_BUILD_SCRIPTS A
COMMAND ${CMAKE_COMMAND} -D "EXECUTABLE=$<TARGET_FILE:${target}>" -D "INPUT=${TEST_COMMAND_INPUT}-py-port-rb.txt" -P ${TEST_COMMAND_RUNNER}
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
)
set_property(TEST ${target}-py-port-rb
PROPERTY LABELS ${target}-py-port-rb
)
set_tests_properties(${target}-py-port-rb PROPERTIES
LABELS ${target}-py-port-rb
PASS_REGULAR_EXPRESSION "0123456789ABCDEFasd"
)
test_environment_variables(${target}-py-port-rb
Expand All @@ -365,10 +349,8 @@ if(OPTION_BUILD_LOADERS AND OPTION_BUILD_LOADERS_FILE AND OPTION_BUILD_SCRIPTS A
COMMAND ${CMAKE_COMMAND} -D "EXECUTABLE=$<TARGET_FILE:${target}>" -D "INPUT=${TEST_COMMAND_INPUT}-file.txt" -P ${TEST_COMMAND_RUNNER}
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
)
set_property(TEST ${target}-file
PROPERTY LABELS ${target}-file
)
set_tests_properties(${target}-file PROPERTIES
LABELS ${target}-file
PASS_REGULAR_EXPRESSION "${LOADER_SCRIPT_PATH}/template.html"
)
test_environment_variables(${target}-file
Expand All @@ -379,10 +361,8 @@ if(OPTION_BUILD_LOADERS AND OPTION_BUILD_LOADERS_FILE AND OPTION_BUILD_SCRIPTS A
COMMAND $<TARGET_FILE:${target}> this-does-not-exist
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
)
set_property(TEST ${target}-file-fail
PROPERTY LABELS ${target}-file-fail
)
set_tests_properties(${target}-file-fail PROPERTIES
LABELS ${target}-file-fail
PASS_REGULAR_EXPRESSION "Error: Failed to load script 'this-does-not-exist' with loader 'file'"
)
test_environment_variables(${target}-file-fail
Expand All @@ -396,10 +376,8 @@ if(OPTION_BUILD_LOADERS AND OPTION_BUILD_LOADERS_PY)
COMMAND $<TARGET_FILE:${target}> test.py
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
)
set_property(TEST ${target}-py-naming
PROPERTY LABELS ${target}-py-naming
)
set_tests_properties(${target}-py-naming PROPERTIES
LABELS ${target}-py-naming
PASS_REGULAR_EXPRESSION "Test: 66673332"
)
test_environment_variables(${target}-py-naming
Expand All @@ -410,10 +388,8 @@ if(OPTION_BUILD_LOADERS AND OPTION_BUILD_LOADERS_PY)
COMMAND $<TARGET_FILE:${target}> cli-test-argv.py
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
)
set_property(TEST ${target}-py-argv
PROPERTY LABELS ${target}-py-argv
)
set_tests_properties(${target}-py-argv PROPERTIES
LABELS ${target}-py-argv
PASS_REGULAR_EXPRESSION "Test: cli-test-argv.py"
)
test_environment_variables(${target}-py-argv
Expand All @@ -424,10 +400,8 @@ if(OPTION_BUILD_LOADERS AND OPTION_BUILD_LOADERS_PY)
COMMAND $<TARGET_FILE:${target}> cli-test-main.py
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
)
set_property(TEST ${target}-py-main
PROPERTY LABELS ${target}-py-main
)
set_tests_properties(${target}-py-main PROPERTIES
LABELS ${target}-py-main
PASS_REGULAR_EXPRESSION "Test: 1234567890abcd"
)
test_environment_variables(${target}-py-main
Expand All @@ -438,10 +412,8 @@ if(OPTION_BUILD_LOADERS AND OPTION_BUILD_LOADERS_PY)
COMMAND ${CMAKE_COMMAND} -D "EXECUTABLE=$<TARGET_FILE:${target}>" -D "INPUT=${TEST_COMMAND_INPUT}-py-exception.txt" -P ${TEST_COMMAND_RUNNER}
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
)
set_property(TEST ${target}-py-exception
PROPERTY LABELS ${target}-py-exception
)
set_tests_properties(${target}-py-exception PROPERTIES
LABELS ${target}-py-exception
PASS_REGULAR_EXPRESSION "66"
)
test_environment_variables(${target}-py-exception
Expand All @@ -455,10 +427,8 @@ if(OPTION_BUILD_LOADERS AND OPTION_BUILD_LOADERS_TS AND OPTION_BUILD_SCRIPTS AND
COMMAND ${CMAKE_COMMAND} -D "EXECUTABLE=$<TARGET_FILE:${target}>" -D "INPUT=${TEST_COMMAND_INPUT}-ts.txt" -P ${TEST_COMMAND_RUNNER}
WORKING_DIRECTORY ${LOADER_SCRIPT_PATH}/typedfunc
)
set_property(TEST ${target}-ts
PROPERTY LABELS ${target}-ts
)
set_tests_properties(${target}-ts PROPERTIES
LABELS ${target}-ts
PASS_REGULAR_EXPRESSION "51354"
)
test_environment_variables(${target}-ts
Expand All @@ -469,10 +439,8 @@ if(OPTION_BUILD_LOADERS AND OPTION_BUILD_LOADERS_TS AND OPTION_BUILD_SCRIPTS AND
COMMAND ${CMAKE_COMMAND} -D "EXECUTABLE=$<TARGET_FILE:${target}>" -D "INPUT=${TEST_COMMAND_INPUT}-tsx-templating.txt" -P ${TEST_COMMAND_RUNNER}
WORKING_DIRECTORY ${LOADER_SCRIPT_PATH}/templating
)
set_property(TEST ${target}-tsx-templating
PROPERTY LABELS ${target}-tsx-templating
)
set_tests_properties(${target}-tsx-templating PROPERTIES
LABELS ${target}-tsx-templating
PASS_REGULAR_EXPRESSION "Hello metaprogrammer"
)
test_environment_variables(${target}-tsx-templating
Expand Down Expand Up @@ -506,10 +474,8 @@ if(OPTION_BUILD_LOADERS AND OPTION_BUILD_LOADERS_TS AND OPTION_BUILD_SCRIPTS AND
COMMAND $<TARGET_FILE:${target}> loopfail.tsx
WORKING_DIRECTORY ${LOADER_SCRIPT_PATH}/loopfail
)
set_property(TEST ${target}-tsx-loop-fail
PROPERTY LABELS ${target}-tsx-loop-fail
)
set_tests_properties(${target}-tsx-loop-fail PROPERTIES
LABELS ${target}-tsx-loop-fail
PASS_REGULAR_EXPRESSION "Error: Cannot find module 'yeet-oof/whatever'"
)
test_environment_variables(${target}-tsx-loop-fail
Expand All @@ -523,10 +489,8 @@ if(OPTION_BUILD_LOADERS AND OPTION_BUILD_LOADERS_TS AND OPTION_BUILD_SCRIPTS AND
COMMAND ${CMAKE_COMMAND} -D "EXECUTABLE=$<TARGET_FILE:${target}>" -D "INPUT=${TEST_COMMAND_INPUT}-py-tsx.txt" -P ${TEST_COMMAND_RUNNER}
WORKING_DIRECTORY ${LOADER_SCRIPT_PATH}/templating
)
set_property(TEST ${target}-py-tsx
PROPERTY LABELS ${target}-py-tsx
)
set_tests_properties(${target}-py-tsx PROPERTIES
LABELS ${target}-py-tsx
PASS_REGULAR_EXPRESSION "Hello World"
)
test_environment_variables(${target}-py-tsx
Expand All @@ -539,3 +503,20 @@ if(OPTION_BUILD_LOADERS AND OPTION_BUILD_LOADERS_TS AND OPTION_BUILD_SCRIPTS AND
)
endif()
endif()

if(OPTION_BUILD_LOADERS AND OPTION_BUILD_LOADERS_EXT AND OPTION_BUILD_EXTENSIONS AND OPTION_BUILD_LOADERS_NODE AND OPTION_BUILD_LOADERS_PY AND OPTION_BUILD_PLUGINS_SANDBOX AND PROJECT_OS_FAMILY STREQUAL unix)
if(NOT OPTION_BUILD_THREAD_SANITIZER AND NOT OPTION_BUILD_ADDRESS_SANITIZER)
add_test(NAME ${target}-cmd-sandboxing
COMMAND ${CMAKE_COMMAND} -E env $<TARGET_FILE:${target}> --sandboxing --disable_time time.py
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
)
set_tests_properties(${target}-cmd-sandboxing PROPERTIES
LABELS ${target}-cmd-sandboxing
WILL_FAIL TRUE
)
test_environment_variables(${target}-cmd-sandboxing
""
${TESTS_ENVIRONMENT_VARIABLES}
)
endif()
endif()
92 changes: 76 additions & 16 deletions source/cli/metacallcli/source/application.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,29 @@ bool application::cmd(std::vector<std::string> &arguments)
/* Get the command parsing function */
void *command_parse_func = metacall_handle_function(plugin_cli_handle, "command_parse");

/* By default, when executing the cmd, it will exit of the REPL */
exit_condition = true;

if (command_parse_func == NULL)
{
std::cout << "Warning: CLI Arguments Parser was not loaded, "
"using fallback argument parser with positional arguments only. "
<< std::endl
<< "Any command line option like '--help' will result into error. "
"Only files are allowed: $ metacall a.py b.js c.rb"
<< std::endl;

/* Use fallback parser, it can execute files but does not support command line arguments as options (i.e: -h, --help) */
/* Parse program arguments if any (e.g metacall (0) a.py (1) b.js (2) c.rb (3)) */
arguments_parse(arguments);

return true;
}

/* Check first if the command function is registered */
void *command_function_func = metacall_handle_function(plugin_cli_handle, "command_function");

if (command_function_func == NULL)
{
return false;
}
Expand Down Expand Up @@ -149,15 +171,51 @@ bool application::cmd(std::vector<std::string> &arguments)
void **ret_array = metacall_value_to_array(ret);
void **command_map = metacall_value_to_map(ret_array[0]);
size_t command_size = metacall_value_count(ret_array[0]);
void **positional_array = metacall_value_to_map(ret_array[1]);
void **positional_array = metacall_value_to_array(ret_array[1]);
size_t positional_size = metacall_value_count(ret_array[1]);

/* Execute arguments */
for (size_t iterator = 0; iterator < command_size; ++iterator)
{
void **command_pair = metacall_value_to_array(command_map[iterator]);

void *args[] = {
command_pair[0]
};

void *command_func = metacallfv_s(command_function_func, args, sizeof(args) / sizeof(args[0]));

if (metacall_value_id(command_func) == METACALL_FUNCTION)
{
/* Execute the function */
void *command_ret = metacallfv_s(command_func, &command_pair[1], 1);
metacall_value_destroy(command_func);
check_for_exception(command_ret);
continue;
}
else if (metacall_value_id(command_func) == METACALL_DOUBLE)
{
static const double COMMAND_NOT_REGISTERED = 0.0;

/* The command is not registered, skip it */
if (metacall_value_to_double(command_func) == COMMAND_NOT_REGISTERED)
{
metacall_value_destroy(command_func);
continue;
}

/* If the function is undefined, try to match the command with a function in the handle scope */
metacall_value_destroy(command_func);
}
else
{
check_for_exception(command_func);
return false;
}

/* Otherwise use the cmd handle scope for obtaining the function */
const char *command_str = metacall_value_to_string(command_pair[0]);
void *command_func = metacall_handle_function(plugin_cmd_handle, command_str);
command_func = metacall_handle_function(plugin_cmd_handle, command_str);

if (command_func == NULL)
{
Expand All @@ -177,6 +235,7 @@ bool application::cmd(std::vector<std::string> &arguments)
{
/* Initialize the REPL */
repl();
exit_condition = false;
}
else
{
Expand All @@ -189,7 +248,7 @@ bool application::cmd(std::vector<std::string> &arguments)
positional_arguments.push_back(metacall_value_to_string(positional_array[iterator]));
}

arguments_parse(arguments);
arguments_parse(positional_arguments);
}

metacall_value_destroy(ret);
Expand Down Expand Up @@ -233,19 +292,8 @@ application::application(int argc, char *argv[]) :
/* Launch the CMD (parse arguments) */
if (!cmd(arguments))
{
std::cout << "Warning: CLI Arguments Parser was not loaded, "
"using fallback argument parser with positional arguments only. "
<< std::endl
<< "Any command line option like '--help' will result into error. "
"Only files are allowed: $ metacall a.py b.js c.rb"
<< std::endl;

/* Use fallback parser, it can execute files but does not support command line arguments as options (i.e: -h, --help) */
/* Parse program arguments if any (e.g metacall (0) a.py (1) b.js (2) c.rb (3)) */
arguments_parse(arguments);
/* TODO: Report something? */
}

exit_condition = true;
}
}

Expand Down Expand Up @@ -472,12 +520,24 @@ void application::run()
metacall_value_destroy(await_data.v);
}

/* Close REPL */
if (plugin_cli_handle != NULL)
{
/* Close REPL */
void *ret = metacallhv_s(plugin_cli_handle, "repl_close", metacall_null_args, 0);

check_for_exception(ret);

/* Get the command destroy function */
void *command_destroy_func = metacall_handle_function(plugin_cli_handle, "command_destroy");

/* Destroy the commands */
if (command_destroy_func != NULL)
{
/* Parse the arguments with the CMD plugin command parse function */
ret = metacallfv_s(command_destroy_func, metacall_null_args, 0);

check_for_exception(ret);
}
}
}

Expand Down
3 changes: 3 additions & 0 deletions source/cli/metacallcli/test/time.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import time

time.sleep(1)
Loading

0 comments on commit d18f130

Please sign in to comment.