Summary
sdk/typescript/_bundled_plugin/scripts/snapshot_sqlite.py can hang indefinitely when the destination refers to the same SQLite database file as the source.
The helper opens the source read-only, opens the destination separately, and then calls source_connection.backup(destination_connection). SQLite's backup API does not make progress when both connections refer to the same database file.
Reproduction
python3 - <<'PY'
import sqlite3
path = "/tmp/codex-security-snapshot-repro.sqlite3"
with sqlite3.connect(path) as connection:
connection.execute("CREATE TABLE IF NOT EXISTS t(value TEXT)")
PY
python3 sdk/typescript/_bundled_plugin/scripts/snapshot_sqlite.py \
/tmp/codex-security-snapshot-repro.sqlite3 \
/tmp/codex-security-snapshot-repro.sqlite3
The second command does not return.
Aliases to the same file can reach the same condition, so comparing path strings alone would not be sufficient.
Expected behavior
The helper should reject an existing destination that identifies the same filesystem object as the source before calling SQLite backup.
Suggested fix
Use filesystem identity (Path.samefile / os.path.samefile) when the destination already exists, fail fast with a clear diagnostic, and add a regression with a process timeout so this cannot silently become an unbounded test hang.
Summary
sdk/typescript/_bundled_plugin/scripts/snapshot_sqlite.pycan hang indefinitely when the destination refers to the same SQLite database file as the source.The helper opens the source read-only, opens the destination separately, and then calls
source_connection.backup(destination_connection). SQLite's backup API does not make progress when both connections refer to the same database file.Reproduction
The second command does not return.
Aliases to the same file can reach the same condition, so comparing path strings alone would not be sufficient.
Expected behavior
The helper should reject an existing destination that identifies the same filesystem object as the source before calling SQLite backup.
Suggested fix
Use filesystem identity (
Path.samefile/os.path.samefile) when the destination already exists, fail fast with a clear diagnostic, and add a regression with a process timeout so this cannot silently become an unbounded test hang.