Fixed memory leak in parser

This commit is contained in:
Georg Richter
2021-08-03 11:31:31 +02:00
parent cb0c3c8f5a
commit 8cd33d55c1
6 changed files with 52 additions and 43 deletions

View File

@ -16,7 +16,7 @@ The mariadb module supports the standard defined by DB API 2.0 (PEP-249).
Establishes a connection to a database server and returns a new connection
object.
:parameters:
Parameters:
.. versionadded:: 1.1.0
@ -54,8 +54,10 @@ The mariadb module supports the standard defined by DB API 2.0 (PEP-249).
- **ssl_verify_cert** (bool): Enables server certificate verification.
- **ssl** (bool): Always use a secure TLS connection
.. versionadded:: 1.0.1
- **autocommit** (bool or None): Specifies the autocommit settings: None will use the server default. True will enable autocommit, False will disable it (default).
.. versionadded:: 1.0.3
- **converter** (dict): Specifies a conversion dictionary, where keys are FIELD_TYPE values and values are conversion functions.
:return: Returns a connection object or raises an error if the connection between client and server couldn't be established.

View File

@ -16,7 +16,7 @@ The mariadb module supports the standard defined by DB API 2.0 (PEP-249).
Establishes a connection to a database server and returns a new connection
object.
:parameters:
Parameters:
.. versionadded:: 1.1.0
@ -54,8 +54,10 @@ The mariadb module supports the standard defined by DB API 2.0 (PEP-249).
- **ssl_verify_cert** (bool): Enables server certificate verification.
- **ssl** (bool): Always use a secure TLS connection
.. versionadded:: 1.0.1
- **autocommit** (bool or None): Specifies the autocommit settings: None will use the server default. True will enable autocommit, False will disable it (default).
.. versionadded:: 1.0.3
- **converter** (dict): Specifies a conversion dictionary, where keys are FIELD_TYPE values and values are conversion functions.
:return: Returns a connection object or raises an error if the connection between client and server couldn't be established.

View File

@ -52,12 +52,9 @@
<span class="sig-prename descclassname"><span class="pre">mariadb.</span></span><span class="sig-name descname"><span class="pre">connect</span></span><span class="sig-paren">(</span><em class="sig-param"><span class="n"><span class="pre">cursorclass</span></span><span class="o"><span class="pre">=</span></span><span class="default_value"><span class="pre">mariadb.connections.Connection</span> <span class="pre">**</span> <span class="pre">kwargs</span></span></em><span class="sig-paren">)</span><a class="headerlink" href="#mariadb.connect" title="Permalink to this definition"></a></dt>
<dd><p>Establishes a connection to a database server and returns a new connection
object.</p>
<p>Parameters:</p>
</dd></dl>
<dl class="field-list simple">
<dt class="field-odd">parameters</dt>
<dd class="field-odd"><p></p></dd>
</dl>
<div class="versionadded">
<p><span class="versionmodified added">New in version 1.1.0: </span></p>
<ul class="simple">
@ -102,10 +99,16 @@ be used</p>
</ul>
</div>
<div class="versionadded">
<p><span class="versionmodified added">New in version 1.0.1: </span>- <strong>autocommit</strong> (bool or None): Specifies the autocommit settings: None will use the server default. True will enable autocommit, False will disable it (default).</p>
<p><span class="versionmodified added">New in version 1.0.1: </span></p>
<ul class="simple">
<li><p><strong>autocommit</strong> (bool or None): Specifies the autocommit settings: None will use the server default. True will enable autocommit, False will disable it (default).</p></li>
</ul>
</div>
<div class="versionadded">
<p><span class="versionmodified added">New in version 1.0.3: </span>- <strong>converter</strong> (dict): Specifies a conversion dictionary, where keys are FIELD_TYPE values and values are conversion functions.</p>
<p><span class="versionmodified added">New in version 1.0.3: </span></p>
<ul class="simple">
<li><p><strong>converter</strong> (dict): Specifies a conversion dictionary, where keys are FIELD_TYPE values and values are conversion functions.</p></li>
</ul>
<dl class="field-list simple">
<dt class="field-odd">return</dt>
<dd class="field-odd"><p>Returns a connection object or raises an error if the connection between client and server couldnt be established.</p>

View File

@ -99,6 +99,7 @@ class Cursor(mariadb._mariadb.cursor):
new_stmt= self.statement
replace_diff= 0
if self._paramlist:
for i in range (0,len(self._paramlist)):
if self._paramstyle == PARAMSTYLE_PYFORMAT:
val= self._data[self._keys[i]]
@ -138,8 +139,8 @@ class Cursor(mariadb._mariadb.cursor):
# check if number of place holders matches the number of
# supplied elements in data tuple
if (not self._data and len(self._paramlist) > 0) or \
(len(self._data) != len(self._paramlist)):
if self._paramlist and ((not self._data and len(self._paramlist) > 0) or \
(len(self._data) != len(self._paramlist))):
raise mariadb.DataError("Number of parameters in statement (%s)"\
" doesn't match the number of data elements (%s)."\
% (len(self._paramlist), len(self._data)))
@ -342,7 +343,6 @@ class Cursor(mariadb._mariadb.cursor):
The cursor will be unusable from this point forward; an Error (or subclass)
exception will be raised if any operation is attempted with the cursor."
"""
super().close()
def fetchone(self):
@ -462,7 +462,6 @@ class Cursor(mariadb._mariadb.cursor):
def __exit__(self, exc_type, exc_val, exc_tb):
"""Closes cursor."""
self.close()
def __del__(self):

View File

@ -391,6 +391,8 @@ void MrdbCursor_clearparseinfo(MrdbParseInfo *parseinfo)
if (parseinfo->statement)
MARIADB_FREE_MEM(parseinfo->statement);
Py_XDECREF(parseinfo->keys);
if (parseinfo->paramlist)
Py_XDECREF(parseinfo->paramlist);
memset(parseinfo, 0, sizeof(MrdbParseInfo));
}
@ -467,8 +469,7 @@ void MrdbCursor_clear(MrdbCursor *self, uint8_t new_stmt)
self->fields= NULL;
self->row_count= 0;
self->affected_rows= 0;
MARIADB_FREE_MEM(self->parseinfo.statement);
memset(&self->parseinfo, 0, sizeof(MrdbParseInfo));
MrdbCursor_clearparseinfo(&self->parseinfo);
MARIADB_FREE_MEM(self->values);
MARIADB_FREE_MEM(self->bind);
MARIADB_FREE_MEM(self->statement);
@ -520,8 +521,7 @@ void ma_cursor_close(MrdbCursor *self)
self->stmt= NULL;
}
MARIADB_FREE_MEM(self->parseinfo.statement);
MrdbCursor_clearparseinfo(&self->parseinfo);
self->is_closed= 1;
}
}
@ -822,10 +822,12 @@ static PyObject *MrdbCursor_seek(MrdbCursor *self, PyObject *args)
{
return NULL;
}
Py_BEGIN_ALLOW_THREADS;
if (self->parseinfo.is_text)
mysql_data_seek(self->result, new_position);
else
mysql_stmt_data_seek(self->stmt, new_position);
Py_END_ALLOW_THREADS;
Py_RETURN_NONE;
}
@ -899,8 +901,7 @@ Mariadb_row_count(MrdbCursor *self)
static PyObject *
Mariadb_row_number(MrdbCursor *self)
{
unsigned int field_count= self->field_count;
if (!field_count) {
if (!self->field_count) {
Py_RETURN_NONE;
}
return PyLong_FromLongLong(self->row_number);
@ -989,6 +990,7 @@ MrdbCursor_parse(MrdbCursor *self, PyObject *args)
memcpy(self->parseinfo.statement, parser->statement.str, parser->statement.length);
self->parseinfo.statement_len= parser->statement.length;
self->parseinfo.paramlist= parser->param_list;
parser->param_list= NULL;
self->parseinfo.is_text= (parser->command == SQL_NONE || parser->command == SQL_OTHER);
self->parseinfo.command= parser->command;
@ -1000,6 +1002,7 @@ MrdbCursor_parse(MrdbCursor *self, PyObject *args)
PyObject *key;
key= PyUnicode_FromString(parser->keys[i].str);
PyTuple_SetItem(tmp, i, key);
Py_DECREF(key);
}
self->parseinfo.keys= tmp;
}

View File

@ -106,9 +106,9 @@ MrdbParser_init(MYSQL *mysql, const char *statement, size_t length)
memcpy(p->statement.str, statement, length);
p->statement.length= length;
p->mysql= mysql;
p->param_list= PyList_New(0);
p->param_count= 0;
}
p->param_list= PyList_New(0);
return p;
}