Index: driver/utility.c =================================================================== --- driver/utility.c (revision 977) +++ driver/utility.c (working copy) @@ -132,15 +132,12 @@ irrec->precision= (SQLSMALLINT) irrec->length; break; } - irrec->octet_length= get_transfer_octet_length(stmt, field) + - test(field->charsetnr != BINARY_CHARSET_NUMBER); - if (stmt->dbc->flag & FLAG_COLUMN_SIZE_S32) - { - if (irrec->length > INT_MAX32) - irrec->length= INT_MAX32; - if (irrec->octet_length > INT_MAX32) - irrec->octet_length= INT_MAX32; - } + irrec->octet_length= get_transfer_octet_length(stmt, field); + /* prevent overflowing */ + if (irrec->octet_length < INT_MAX32) + irrec->octet_length+= test(field->charsetnr != BINARY_CHARSET_NUMBER); + if (stmt->dbc->flag & FLAG_COLUMN_SIZE_S32 && irrec->length > INT_MAX32) + irrec->length= INT_MAX32; irrec->scale= max(0, (SQLSMALLINT) get_decimal_digits(stmt, field)); if ((field->flags & NOT_NULL_FLAG) && !(field->flags & TIMESTAMP_FLAG) && @@ -1261,7 +1258,12 @@ */ SQLLEN get_transfer_octet_length(STMT *stmt, MYSQL_FIELD *field) { - SQLLEN length= field->length; + SQLLEN length; + /* cap at INT_MAX32 due to signed value */ + if (field->length > INT_MAX32) + length= INT_MAX32; + else + length= field->length; switch (field->type) { case MYSQL_TYPE_TINY: @@ -1418,10 +1420,17 @@ case MYSQL_TYPE_LONG_BLOB: case MYSQL_TYPE_BLOB: case MYSQL_TYPE_GEOMETRY: - if (field->charsetnr == BINARY_CHARSET_NUMBER) - return field->length * 2; - else - return field->length / mbmaxlen; + { + unsigned long length; + if (field->charsetnr == BINARY_CHARSET_NUMBER) + length= field->length * 2; + else + length= field->length / mbmaxlen; + /* display size is signed and cannot exceed this */ + if (length > INT_MAX32) + length= INT_MAX32; + return length; + } } return SQL_NO_TOTAL; Index: test/my_result.c =================================================================== --- test/my_result.c (revision 977) +++ test/my_result.c (working copy) @@ -2025,6 +2025,7 @@ SQLULEN pcColSz; SQLCHAR szColName[MAX_NAME_LEN]; SQLSMALLINT pfSqlType, pcbScale, pfNullable; + SQLLEN display_size, octet_length; SET_DSN_OPTION(1 << 27); @@ -2041,6 +2042,14 @@ /* Size of LONGTEXT should have been capped to 1 << 31. */ is_num(pcColSz, 2147483647L); + /* also, check display size and octet length (see bug#30890) */ + ok_stmt(hstmt1, SQLColAttribute(hstmt1, 1, SQL_DESC_DISPLAY_SIZE, NULL, + 0, NULL, &display_size)); + ok_stmt(hstmt1, SQLColAttribute(hstmt1, 1, SQL_DESC_OCTET_LENGTH, NULL, + 0, NULL, &octet_length)); + is_num(display_size, 2147483647L); + is_num(octet_length, 2147483647L); + ok_stmt(hstmt1, SQLFreeStmt(hstmt1, SQL_CLOSE)); ok_sql(hstmt1, "DROP TABLE IF EXISTS t_bug13776");