libc+tests: Check for manual modifications of environ
All checks were successful
continuous-integration/drone/push Build is passing
All checks were successful
continuous-integration/drone/push Build is passing
Closes #31.
This commit is contained in:
parent
5f698b4774
commit
2951d6d112
@ -94,12 +94,30 @@ static void _update_env()
|
||||
environ = g_dynamic_env.data();
|
||||
}
|
||||
|
||||
// Check if a user has modified environ, in which case we should reset env_is_dynamic and free our buffers.
|
||||
static void _check_dynamic_env()
|
||||
{
|
||||
if (!env_is_dynamic) return;
|
||||
|
||||
env_is_dynamic = environ == g_dynamic_env.data();
|
||||
|
||||
if (!env_is_dynamic)
|
||||
{
|
||||
for (auto element : g_dynamic_env)
|
||||
{
|
||||
if (element) free(element);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extern "C"
|
||||
{
|
||||
char** environ = nullptr;
|
||||
|
||||
int clearenv()
|
||||
{
|
||||
_check_dynamic_env();
|
||||
|
||||
if (env_is_dynamic)
|
||||
{
|
||||
for (auto element : g_dynamic_env)
|
||||
@ -127,6 +145,8 @@ extern "C"
|
||||
auto index = _findenv(key, nullptr);
|
||||
if (index < 0) return 0;
|
||||
|
||||
_check_dynamic_env();
|
||||
|
||||
if (!env_is_dynamic)
|
||||
{
|
||||
if (_move_env() < 0) return -1;
|
||||
@ -149,6 +169,8 @@ extern "C"
|
||||
auto index = _findenv(key, nullptr);
|
||||
if (index >= 0 && !overwrite) return 0;
|
||||
|
||||
_check_dynamic_env();
|
||||
|
||||
if (!env_is_dynamic)
|
||||
{
|
||||
if (_move_env() < 0) return -1;
|
||||
|
@ -21,6 +21,7 @@ luna_test(libluna/TestHashTable.cpp TestHashTable)
|
||||
luna_test(libluna/TestCPath.cpp TestCPath)
|
||||
luna_test(libc/TestScanf.cpp TestScanf)
|
||||
luna_test(libc/TestString.cpp TestString)
|
||||
luna_test(libc/TestEnv.cpp TestEnv)
|
||||
|
||||
luna_app(run-tests.cpp run-tests)
|
||||
endif()
|
||||
|
85
tests/libc/TestEnv.cpp
Normal file
85
tests/libc/TestEnv.cpp
Normal file
@ -0,0 +1,85 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <test.h>
|
||||
|
||||
extern char** environ;
|
||||
|
||||
TestResult test_setenv_then_getenv()
|
||||
{
|
||||
clearenv();
|
||||
|
||||
validate(setenv("sample", "value", 1) == 0);
|
||||
|
||||
char* value = getenv("sample");
|
||||
validate(value);
|
||||
validate(!strcmp(value, "value"));
|
||||
|
||||
test_success;
|
||||
}
|
||||
|
||||
TestResult test_setenv_dont_overwrite()
|
||||
{
|
||||
clearenv();
|
||||
|
||||
validate(setenv("sample", "value", 1) == 0);
|
||||
|
||||
char* value = getenv("sample");
|
||||
validate(value);
|
||||
validate(!strcmp(value, "value"));
|
||||
|
||||
validate(setenv("sample", "other_value", 0) == 0);
|
||||
|
||||
value = getenv("sample");
|
||||
validate(value);
|
||||
validate(!strcmp(value, "value"));
|
||||
|
||||
test_success;
|
||||
}
|
||||
|
||||
TestResult test_unsetenv()
|
||||
{
|
||||
clearenv();
|
||||
|
||||
validate(setenv("sample", "value", 1) == 0);
|
||||
|
||||
char* value = getenv("sample");
|
||||
validate(value);
|
||||
validate(!strcmp(value, "value"));
|
||||
|
||||
validate(unsetenv("sample") == 0);
|
||||
|
||||
value = getenv("sample");
|
||||
validate(!value);
|
||||
|
||||
test_success;
|
||||
}
|
||||
|
||||
TestResult test_setenv_before_and_after_manual_environ_modification()
|
||||
{
|
||||
clearenv();
|
||||
|
||||
validate(setenv("sample", "value", 1) == 0);
|
||||
|
||||
char* list[] = { "hello=world", NULL };
|
||||
environ = list;
|
||||
|
||||
validate(setenv("other", "value", 1) == 0);
|
||||
|
||||
char* value = getenv("hello");
|
||||
validate(value);
|
||||
validate(!strcmp(value, "world"));
|
||||
|
||||
test_success;
|
||||
}
|
||||
|
||||
Result<void> test_main()
|
||||
{
|
||||
test_prelude;
|
||||
|
||||
run_test(test_setenv_then_getenv);
|
||||
run_test(test_setenv_dont_overwrite);
|
||||
run_test(test_unsetenv);
|
||||
run_test(test_setenv_before_and_after_manual_environ_modification);
|
||||
|
||||
return {};
|
||||
}
|
Loading…
Reference in New Issue
Block a user