diff --git a/source/jst_session.c b/source/jst_session.c index ceec720..69f542f 100644 --- a/source/jst_session.c +++ b/source/jst_session.c @@ -164,6 +164,12 @@ static duk_ret_t session_create(duk_context *ctx) char* session_id = NULL; session_id = (char*)malloc(SESSION_ID_BYTES_LENGTH+1); + if(!session_id) + { + CosaPhpExtLog("Failed to allocate session_id!\n"); + RETURN_FALSE; + } + n = syscall(SYS_getrandom, bytes, SESSION_ID_BYTES_LENGTH, 0); if(n != SESSION_ID_BYTES_LENGTH) { @@ -177,16 +183,27 @@ static duk_ret_t session_create(duk_context *ctx) session_id[i] = BYTE_TO_PRINTABLE_HEX_CODE(bytes[i]); } + if(session_identifier) + { + char filename[SESSION_FILE_MAX_PATH]; + snprintf(filename, SESSION_FILE_MAX_PATH, "%s/%s", SESSION_TMP_DIR, session_identifier); + unlink(filename); + free(session_identifier); + session_identifier = NULL; + } + session_identifier = (char*)malloc(SESSION_ID_LENGTH+1); if(!session_identifier) { CosaPhpExtLog("Failed to allocate session_identifier!\n"); + free(session_id); RETURN_FALSE; } memset(session_identifier, 0, SESSION_ID_LENGTH+1); session_id[SESSION_ID_BYTES_LENGTH] = '\0'; snprintf(session_identifier, SESSION_ID_LENGTH+1, "%s%s", SESSION_PREFIX, session_id); + free(session_id); RETURN_TRUE; return 1; diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 2628f71..013f6ef 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -73,6 +73,7 @@ add_executable( parser_test ../tests/parser_test.cpp ../source/jst_parser.c + ../source/jst_session.c ../source/jst_internal.c ../source/duktape/duktape.c) target_link_libraries(parser_test libgtest libgmock -pthread) diff --git a/tests/parser_test.cpp b/tests/parser_test.cpp index cd97b54..a3bc427 100644 --- a/tests/parser_test.cpp +++ b/tests/parser_test.cpp @@ -20,12 +20,17 @@ #include #include #include +#include #include "jst.h" #include #include #include #include +extern "C" { + duk_ret_t ccsp_session_module_open(duk_context *ctx); +} + using namespace std; class BufferFreer @@ -106,6 +111,85 @@ TEST(general, parser) { } } +TEST(general, session_create_multiple_calls_succeed) +{ + duk_context* ctx = duk_create_heap_default(); + ASSERT_NE(ctx, nullptr); + + duk_push_c_function(ctx, ccsp_session_module_open, 0); + ASSERT_EQ(duk_pcall(ctx, 0), DUK_EXEC_SUCCESS); + duk_put_global_string(ctx, "ccsp_session"); + + duk_get_global_string(ctx, "ccsp_session"); + duk_get_prop_string(ctx, -1, "create"); + ASSERT_EQ(duk_pcall(ctx, 0), DUK_EXEC_SUCCESS); + EXPECT_TRUE(duk_get_boolean(ctx, -1)); + duk_pop_2(ctx); + + duk_get_global_string(ctx, "ccsp_session"); + duk_get_prop_string(ctx, -1, "create"); + ASSERT_EQ(duk_pcall(ctx, 0), DUK_EXEC_SUCCESS); + EXPECT_TRUE(duk_get_boolean(ctx, -1)); + duk_pop_2(ctx); + + duk_get_global_string(ctx, "ccsp_session"); + duk_get_prop_string(ctx, -1, "destroy"); + ASSERT_EQ(duk_pcall(ctx, 0), DUK_EXEC_SUCCESS); + EXPECT_TRUE(duk_get_boolean(ctx, -1)); + duk_pop_2(ctx); + + duk_destroy_heap(ctx); +} + +TEST(general, session_create_destroy_cycle_and_id_format) +{ + duk_context* ctx = duk_create_heap_default(); + ASSERT_NE(ctx, nullptr); + + duk_push_c_function(ctx, ccsp_session_module_open, 0); + ASSERT_EQ(duk_pcall(ctx, 0), DUK_EXEC_SUCCESS); + duk_put_global_string(ctx, "ccsp_session"); + + duk_get_global_string(ctx, "ccsp_session"); + duk_get_prop_string(ctx, -1, "create"); + ASSERT_EQ(duk_pcall(ctx, 0), DUK_EXEC_SUCCESS); + EXPECT_TRUE(duk_get_boolean(ctx, -1)); + duk_pop_2(ctx); + + duk_get_global_string(ctx, "ccsp_session"); + duk_get_prop_string(ctx, -1, "getId"); + ASSERT_EQ(duk_pcall(ctx, 0), DUK_EXEC_SUCCESS); + const char* first_id = duk_get_string(ctx, -1); + ASSERT_NE(first_id, nullptr); + EXPECT_EQ(strlen(first_id), 40u); + EXPECT_EQ(strncmp(first_id, "jst_sess", 8), 0); + + char first_session_file[128] = {0}; + snprintf(first_session_file, sizeof(first_session_file), "/tmp/%s", first_id); + duk_pop_2(ctx); + + FILE* stale = fopen(first_session_file, "w"); + ASSERT_NE(stale, nullptr); + fclose(stale); + ASSERT_EQ(access(first_session_file, F_OK), 0); + + duk_get_global_string(ctx, "ccsp_session"); + duk_get_prop_string(ctx, -1, "create"); + ASSERT_EQ(duk_pcall(ctx, 0), DUK_EXEC_SUCCESS); + EXPECT_TRUE(duk_get_boolean(ctx, -1)); + duk_pop_2(ctx); + + EXPECT_NE(access(first_session_file, F_OK), 0); + + duk_get_global_string(ctx, "ccsp_session"); + duk_get_prop_string(ctx, -1, "destroy"); + ASSERT_EQ(duk_pcall(ctx, 0), DUK_EXEC_SUCCESS); + EXPECT_TRUE(duk_get_boolean(ctx, -1)); + duk_pop_2(ctx); + + duk_destroy_heap(ctx); +} + int main(int argc, char* argv[]) { ::testing::InitGoogleTest(&argc, argv);