Skip to content

Commit 7c5c7da

Browse files
committed
fix(iast): gevent
1 parent 7bc53f5 commit 7c5c7da

File tree

2 files changed

+68
-1
lines changed

2 files changed

+68
-1
lines changed

ddtrace/appsec/_iast/_taint_tracking/context/taint_engine_context.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,8 @@
3434

3535
#include <atomic>
3636
#include <memory>
37-
#include <optional>
3837
#include <mutex>
38+
#include <optional>
3939
#include <string>
4040
#include <vector>
4141

ddtrace/appsec/_iast/_taint_tracking/tests/test_taint_engine_context.cpp

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -397,3 +397,70 @@ TEST_F(ApplicationContextTest, ClearAllIsIdempotent)
397397
taint_engine_context->clear_all_request_context_slots();
398398
ASSERT_EQ(taint_engine_context->get_tainted_object_map_by_ctx_id(id), nullptr);
399399
}
400+
401+
TEST_F(ApplicationContextTest, ShuttingDownBlocksStartAndLookups)
402+
{
403+
// Enable shutdown: all operations should early-return
404+
TaintEngineContext::set_shutting_down(true);
405+
406+
// start_request_context should refuse to allocate a slot
407+
auto idx = taint_engine_context->start_request_context();
408+
ASSERT_FALSE(idx.has_value());
409+
410+
// Lookups should be short-circuited
411+
py::str s("x");
412+
auto m_obj = taint_engine_context->get_tainted_object_map(s.ptr());
413+
ASSERT_EQ(m_obj, nullptr);
414+
415+
std::vector<PyObject*> objs{ s.ptr() };
416+
auto m_list = taint_engine_context->get_tainted_object_map_from_list_of_pyobjects(objs);
417+
ASSERT_EQ(m_list, nullptr);
418+
419+
// By-index lookup should also be blocked
420+
auto m_by_id = taint_engine_context->get_tainted_object_map_by_ctx_id(0);
421+
ASSERT_EQ(m_by_id, nullptr);
422+
423+
// Reset shutdown flag for following tests
424+
TaintEngineContext::set_shutting_down(false);
425+
}
426+
427+
TEST_F(ApplicationContextTest, ClearingShuttingDownRestoresOperation)
428+
{
429+
// Block then unblock and verify operations resume
430+
TaintEngineContext::set_shutting_down(true);
431+
ASSERT_FALSE(taint_engine_context->start_request_context().has_value());
432+
433+
TaintEngineContext::set_shutting_down(false);
434+
auto idx = taint_engine_context->start_request_context();
435+
ASSERT_TRUE(idx.has_value());
436+
auto m = taint_engine_context->get_tainted_object_map_by_ctx_id(*idx);
437+
ASSERT_NE(m, nullptr);
438+
}
439+
440+
TEST_F(ApplicationContextTest, AtexitHandlerClearsAndResetsContext)
441+
{
442+
// Import the native module to trigger its PYBIND11_MODULE initializer,
443+
// which registers an atexit handler that sets shutting_down=true,
444+
// clears slots, and resets the global taint_engine_context.
445+
auto mod = py::module::import("ddtrace.appsec._iast._taint_tracking._native");
446+
auto ctx = mod.attr("context");
447+
448+
// Before running exit funcs, capacity should be > 0 (module created a context)
449+
auto before_size = ctx.attr("debug_context_array_size")().cast<size_t>();
450+
ASSERT_GT(before_size, static_cast<size_t>(0));
451+
452+
// Execute Python atexit callbacks
453+
auto atexit = py::module::import("atexit");
454+
atexit.attr("_run_exitfuncs")();
455+
456+
// After atexit, context helpers should reflect cleared/reset state
457+
auto after_size = ctx.attr("debug_context_array_size")().cast<size_t>();
458+
ASSERT_EQ(after_size, static_cast<size_t>(0));
459+
460+
// get_tainted_object_map_by_ctx_id returns bool; should be False (nullptr)
461+
auto by_id_exists = ctx.attr("get_tainted_object_map_by_ctx_id")(0).cast<bool>();
462+
ASSERT_FALSE(by_id_exists);
463+
464+
// Recreate a fresh context manually to not affect subsequent tests
465+
taint_engine_context = std::make_unique<TaintEngineContext>();
466+
}

0 commit comments

Comments
 (0)