Edgewall Software

#13513 closed defect (fixed)

Maximum recursion depth when mysql connection string has an invalid connection parameter — at Version 1

Reported by: Jun Omae Owned by: Jun Omae
Priority: normal Milestone: 1.4.4
Component: database backend Version: 1.0.20
Severity: normal Keywords: mysql
Cc: Branch:
Release Notes:

Fixed maximum recursion depth error raising when database connection string to MySQL has an invalid parameter.

API Changes:
Internal Changes:

Description

Maximum recursion depth raises due to accessing self.log attribute before setting the self.log attribute. It seems that this issue is introduced in r10407

trunk

$ TRAC_TEST_DB_URI='mysql://tracuser:password@127.0.0.1/trac_utf8mb4?unknown=value' ~/venv/py39/bin/python
Python 3.9.16 (main, Dec  7 2022, 01:11:51)
[GCC 9.4.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> from trac.test import EnvironmentStub, get_dburi
>>> get_dburi()
'mysql://tracuser:password@127.0.0.1/trac_utf8mb4?unknown=value'
>>> env = EnvironmentStub()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/jun66j5/src/tracdev/git/trac/core.py", line 142, in __call__
    self.__init__(*args, **kwargs)
  File "/home/jun66j5/src/tracdev/git/trac/test.py", line 392, in __init__
    self.reset_db(default_data)
  File "/home/jun66j5/src/tracdev/git/trac/test.py", line 443, in reset_db
    dbm.init_db()
  File "/home/jun66j5/src/tracdev/git/trac/db/api.py", line 283, in init_db
    connector.init_db(**args)
  File "/home/jun66j5/src/tracdev/git/trac/db/mysql_backend.py", line 131, in init_db
    cnx = self.get_connection(path, log, user, password, host, port,
  File "/home/jun66j5/src/tracdev/git/trac/db/mysql_backend.py", line 117, in get_connection
    cnx = MySQLConnection(path, log, user, password, host, port, params)
  File "/home/jun66j5/src/tracdev/git/trac/db/mysql_backend.py", line 401, in __init__
    self.log.warning("Invalid connection string parameter '%s'",
  File "/home/jun66j5/src/tracdev/git/trac/db/util.py", line 114, in __getattr__
    if self.readonly and name in ('commit', 'rollback'):
  File "/home/jun66j5/src/tracdev/git/trac/db/util.py", line 114, in __getattr__
    if self.readonly and name in ('commit', 'rollback'):
  File "/home/jun66j5/src/tracdev/git/trac/db/util.py", line 114, in __getattr__
    if self.readonly and name in ('commit', 'rollback'):
  [Previous line repeated 987 more times]
RecursionError: maximum recursion depth exceeded

1.0-stable

$ TRAC_TEST_DB_URI='mysql://tracuser:password@127.0.0.1/trac_utf8mb4?unknown=value' ~/venv/py27/bin/python    Python 2.7.18 (default, Jul  1 2022, 12:27:04)
[GCC 9.4.0] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> from trac.test import EnvironmentStub, get_dburi
>>> get_dburi()
'mysql://tracuser:password@127.0.0.1/trac_utf8mb4?unknown=value'
>>> env = EnvironmentStub()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "trac/core.py", line 124, in __call__
    self.__init__(*args, **kwargs)
  File "trac/test.py", line 432, in __init__
    self.reset_db(default_data)
  File "trac/test.py", line 479, in reset_db
    self.global_databasemanager.init_db()
  File "trac/db/api.py", line 253, in init_db
    connector.init_db(**args)
  File "trac/db/mysql_backend.py", line 123, in init_db
    params)
  File "trac/db/mysql_backend.py", line 104, in get_connection
    cnx = MySQLConnection(path, log, user, password, host, port, params)
  File "trac/db/mysql_backend.py", line 375, in __init__
    self.log.warning("Invalid connection string parameter '%s'",
  File "trac/db/util.py", line 113, in __getattr__
    if self.readonly and name in ('commit', 'rollback'):
  File "trac/db/util.py", line 113, in __getattr__
    if self.readonly and name in ('commit', 'rollback'):
  File "trac/db/util.py", line 113, in __getattr__
    if self.readonly and name in ('commit', 'rollback'):
  ...
  File "trac/db/util.py", line 113, in __getattr__
    if self.readonly and name in ('commit', 'rollback'):
  File "trac/db/util.py", line 113, in __getattr__
    if self.readonly and name in ('commit', 'rollback'):
RuntimeError: maximum recursion depth exceeded while calling a Python object

Patch to trunk

  • trac/db/mysql_backend.py

    index 16b5faca8..a58f20cda 100644
    a b class MySQLConnection(ConnectionBase, ConnectionWrapper):  
    395395                if value in ('utf8', 'utf8mb4'):
    396396                    opts[name] = value
    397397                else:
    398                     self.log.warning("Invalid connection string parameter "
    399                                      "'%s=%s'", name, value)
     398                    log.warning("Invalid connection string parameter '%s=%s'",
     399                                name, value)
    400400            else:
    401                 self.log.warning("Invalid connection string parameter '%s'",
    402                                  name)
     401                log.warning("Invalid connection string parameter '%s'", name)
    403402        cnx = pymysql.connect(db=path, user=user, passwd=password, host=host,
    404403                              port=port, **opts)
    405404        cursor = cnx.cursor()

Change History (1)

comment:1 by Jun Omae, 17 months ago

Release Notes: modified (diff)
Resolution: fixed
Status: assignedclosed

Fixed and merged in [17636-17641].

Note: See TracTickets for help on using tickets.