Files
codeql/python/ql/test/library-tests/frameworks/hdbcli/pep249.py
copilot-swe-agent[bot] 0ea1b8596e Add PEP249 connection tracking through class attribute wrappers
Introduce two new Connection::InstanceSource subclasses in PEP249.qll:

- ConnectionGetterAttributeRead: recognises self._conn reads inside
  getter methods of classes whose __init__ stores a connect() call in
  that attribute. The AttrRead node coincides with the return node, so
  the existing TypeTracker returnStep propagates the connection type to
  all call sites automatically.

- ConnectionConstructorAttributeRead: recognises ClassName()._conn
  direct attribute reads on constructor-call results.

Both classes share the classStoresConnectionInInit helper predicate
that checks for the self.attr = dbapi.connect() store pattern in __init__.

Also adds test cases for the new patterns in the hdbcli test suite
and a change note.
2026-05-21 23:22:29 +00:00

56 lines
1.7 KiB
Python

from hdbcli import dbapi
conn = dbapi.connect(address="hostname", port=300, user="username", password="password")
cursor = conn.cursor()
cursor.execute("some sql", (42,)) # $ getSql="some sql"
cursor.executemany("some sql", (42,)) # $ getSql="some sql"
cursor.close()
# ---------------------------------------------------------------------------
# Connection stored in a class attribute and accessed via various patterns
# ---------------------------------------------------------------------------
class WrapperA:
def __init__(self):
self._conn = dbapi.connect(address="hostname", port=300, user="username", pass_arg="testpass")
def get_connection(self):
return self._conn
# Getter called on a fresh constructor result
conn_a1 = WrapperA().get_connection()
cursor_a1 = conn_a1.cursor()
cursor_a1.execute("some sql", (42,)) # $ getSql="some sql"
# Getter called via a stored wrapper instance
wrapper_instance = WrapperA()
conn_a2 = wrapper_instance.get_connection()
cursor_a2 = conn_a2.cursor()
cursor_a2.execute("some sql", (42,)) # $ getSql="some sql"
# Direct attribute access on a fresh constructor result
conn_b = WrapperA()._conn
cursor_b = conn_b.cursor()
cursor_b.execute("some sql", (42,)) # $ getSql="some sql"
class WrapperB:
"""Stores the connection under a different attribute name."""
def __init__(self):
self._hana = dbapi.connect(address="hostname", port=300, user="username", pass_arg="testpass")
def cursor(self):
return self._hana.cursor()
# Direct attribute access on a stored instance (mirrors hdb_con3 in the issue)
conn_c = WrapperB()._hana
cursor_c = conn_c.cursor()
cursor_c.execute("some sql", (42,)) # $ getSql="some sql"