mirror of
https://github.com/n8n-io/n8n.git
synced 2026-08-30 18:01:23 +08:00
fix(core): Keep submodules of safe modules in native Python runner (#20284)
This commit is contained in:
@@ -405,8 +405,12 @@ class TaskExecutor:
|
||||
else:
|
||||
safe_modules.update(external_allow)
|
||||
|
||||
# keep modules marked as safe and submodules of those
|
||||
modules_to_remove = [
|
||||
name for name in sys.modules.keys() if name not in safe_modules
|
||||
name
|
||||
for name in sys.modules.keys()
|
||||
if name not in safe_modules
|
||||
and not any(name.startswith(safe + ".") for safe in safe_modules)
|
||||
]
|
||||
|
||||
for module_name in modules_to_remove:
|
||||
|
||||
@@ -27,9 +27,11 @@ class TaskRunnerManager:
|
||||
self,
|
||||
task_broker_url: str = LOCAL_TASK_BROKER_URL,
|
||||
graceful_shutdown_timeout: float | None = None,
|
||||
custom_env: dict[str, str] | None = None,
|
||||
):
|
||||
self.task_broker_url = task_broker_url
|
||||
self.graceful_shutdown_timeout = graceful_shutdown_timeout
|
||||
self.custom_env = custom_env or {}
|
||||
self.subprocess: asyncio.subprocess.Process | None = None
|
||||
self.stdout_buffer: list[str] = []
|
||||
self.stderr_buffer: list[str] = []
|
||||
@@ -49,6 +51,7 @@ class TaskRunnerManager:
|
||||
self.graceful_shutdown_timeout
|
||||
)
|
||||
env_vars["PYTHONPATH"] = str(project_root)
|
||||
env_vars.update(self.custom_env)
|
||||
|
||||
self.subprocess = await asyncio.create_subprocess_exec(
|
||||
sys.executable,
|
||||
|
||||
@@ -27,6 +27,18 @@ async def broker():
|
||||
await broker.stop()
|
||||
|
||||
|
||||
@pytest_asyncio.fixture
|
||||
async def manager_with_stdlib_wildcard():
|
||||
manager = TaskRunnerManager(
|
||||
custom_env={
|
||||
"N8N_RUNNERS_STDLIB_ALLOW": "*",
|
||||
}
|
||||
)
|
||||
await manager.start()
|
||||
yield manager
|
||||
await manager.stop()
|
||||
|
||||
|
||||
def create_task_settings(
|
||||
code: str,
|
||||
node_mode: str,
|
||||
|
||||
@@ -230,3 +230,19 @@ async def test_timeout_during_execution(broker, manager):
|
||||
|
||||
assert error_msg["taskId"] == task_id
|
||||
assert "timed out" in error_msg["error"]["message"].lower()
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_stdlib_submodules_with_wildcard(broker, manager_with_stdlib_wildcard):
|
||||
task_id = nanoid()
|
||||
code = textwrap.dedent("""
|
||||
from collections.abc import Iterable
|
||||
result = isinstance([1, 2, 3], Iterable)
|
||||
return [{"json": {"is_iterable": result}}]
|
||||
""")
|
||||
task_settings = create_task_settings(code=code, node_mode="all_items")
|
||||
await broker.send_task(task_id=task_id, task_settings=task_settings)
|
||||
|
||||
result = await wait_for_task_done(broker, task_id)
|
||||
|
||||
assert result["data"]["result"] == [{"json": {"is_iterable": True}}]
|
||||
|
||||
Reference in New Issue
Block a user