Uploaded image for project: 'Qt'
  1. Qt
  2. QTBUG-5765

Invalid buffer allocation causes improper data truncation

    XMLWordPrintable

Details

    • Bug
    • Resolution: Done
    • P2: Important
    • 4.6.3
    • 4.5.3
    • SQL Support
    • None
    • 46d5f85a03bd87708152baba2674f2e5f36afe22

    Description

      Since the MYSQL_FIELD member named length describes the width of a column as the "display length" ( http://dev.mysql.com/doc/refman/5.0/en/c-api-datatypes.html ), it includes formatting information--such as the display width for numeric types. As documented at http://dev.mysql.com/doc/refman/5.0/en/numeric-types.html , "The display width does not constrain the range of values that can be stored in the column, nor the number of digits that are displayed for values having a width exceeding that specified for the column. For example, a column specified as SMALLINT(3) has the usual SMALLINT range of -32768 to 32767, and values outside the range allowed by three characters are displayed using more than three characters." Therefore, when using length to allocate buffers in QMYSQLResultPrivate::bindInValues(), the buffer may be too small to hold values.

      The db_length, on the other hand describes the width of the column as represented in the database. Therefore, the attached patch changes QMYSQLResultPrivate::bindInValues() to use db_length when allocating buffers for non-BLOB fields.

      The attached test application, test_qt_data_truncation.cpp , can be used to see the effect of the invalid buffer allocation. The application creates a temporary table with a TINYINT(1) column and populates the table with rows, including a row in the middle of the table with a value of 127. To use the test application edit the database host, database name, username, and password as appropriate.

      Without the attached patch, qt-4.5-use_db_length_for_buffer_allocation.patch , the call to QSqlQuery::next() for the row with the value 127 when the statement was executed as a prepared statement results in mysql_stmt_fetch() returning MYSQL_DATA_TRUNCATED because the allocated buffer is too small to hold the field value. When this occurs, QSqlQuery::next() returns false and the loop is terminated--without accessing the rest of the values in the result.

      Note, also, that the patch at http://bugreports.qt.nokia.com/browse/QTBUG-5758 ensures that a lastError is set when an error or data truncation occurs in QMYSQLResult::fetchNext() (so without the patch in QTBUG-5758, the lastError will be empty when the failure occurs).

      Additional notes for reproducing the issue:

      Before Qt4, the Qt MySQL drivers never used real prepared queries. Therefore, this issue did not occur in Qt3.

      In Qt4 version 4.4.x and below,~prepared statements were only used if the developer explicitly requested prepared statements with QSqlQuery::prepare().

      In Qt4 version 4.5.0 and above, the Qt MySQL drivers always attempt to use prepared queries (and succeed for SELECT statements), even if the developer does not request a prepared query using QSqlQuery::prepare(). Therefore, the described bug will always affect users of Qt 4.5.x and above.

      Attachments

        No reviews matched the request. Check your Options in the drop-down menu of this sections header.

        Activity

          People

            bilking Bill King
            sphery Michael T. Dean
            Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved:

              Gerrit Reviews

                There are no open Gerrit changes