wez Sat Sep 24 22:05:06 2005 EDT Modified files: (Branch: PHP_5_1) /php-src/ext/pdo_mysql mysql_statement.c Log: Fixup LOB handling for inserts (refs #34630). Also tripped over the return of PECL #5200; looks like mysql doesn't return an accurate length for the columns. The PDO driver will sanity check the real length against the buffer size it allocated (based on the info provided by mysql), so that we won't overrun the buffer. In addition, if a varchar field is reported as having a length of less than 128, we'll allocate 128 just in case. If the data is truncated, report it via the appropriate sqlstate code. There must be a better way to do this stuff. http://cvs.php.net/diff.php/php-src/ext/pdo_mysql/mysql_statement.c?r1=1.48.2.1&r2=1.48.2.2&ty=u Index: php-src/ext/pdo_mysql/mysql_statement.c diff -u php-src/ext/pdo_mysql/mysql_statement.c:1.48.2.1 php-src/ext/pdo_mysql/mysql_statement.c:1.48.2.2 --- php-src/ext/pdo_mysql/mysql_statement.c:1.48.2.1 Wed Aug 31 21:57:01 2005 +++ php-src/ext/pdo_mysql/mysql_statement.c Sat Sep 24 22:05:03 2005 @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: mysql_statement.c,v 1.48.2.1 2005/09/01 01:57:01 iliaa Exp $ */ +/* $Id: mysql_statement.c,v 1.48.2.2 2005/09/25 02:05:03 wez Exp $ */ #ifdef HAVE_CONFIG_H #include "config.h" @@ -142,6 +142,26 @@ S->fields[i].max_length? S->fields[i].max_length: S->fields[i].length; } +#if 0 + printf("%d: max_length=%d length=%d buffer_length=%d type=%d\n", + i, + S->fields[i].max_length, + S->fields[i].length, + S->bound_result[i].buffer_length, + S->fields[i].type + ); +#endif + + /* there are cases where the length reported by mysql is too short. + * eg: when describing a table that contains an enum column. Since + * we have no way of knowing the true length either, we'll bump up + * our buffer size to a reasonable size, just in case */ + if (S->fields[i].max_length == 0 && S->bound_result[i].buffer_length < 128 && MYSQL_TYPE_VAR_STRING) { + S->bound_result[i].buffer_length = 128; + } + + S->out_length[i] = 0; + S->bound_result[i].buffer = emalloc(S->bound_result[i].buffer_length); S->bound_result[i].is_null = &S->out_null[i]; S->bound_result[i].length = &S->out_length[i]; @@ -291,9 +311,24 @@ } switch (PDO_PARAM_TYPE(param->param_type)) { - case PDO_PARAM_LOB: case PDO_PARAM_STMT: return 0; + case PDO_PARAM_LOB: + if (Z_TYPE_P(param->parameter) == IS_RESOURCE) { + php_stream *stm; + php_stream_from_zval_no_verify(stm, ¶m->parameter); + if (stm) { + SEPARATE_ZVAL_IF_NOT_REF(¶m->parameter); + Z_TYPE_P(param->parameter) = IS_STRING; + Z_STRLEN_P(param->parameter) = php_stream_copy_to_mem(stm, + &Z_STRVAL_P(param->parameter), PHP_STREAM_COPY_ALL, 0); + } else { + pdo_raise_impl_error(stmt->dbh, stmt, "HY105", "Expected a stream resource"); + return 0; + } + } + /* fall through */ + default: ; } @@ -423,6 +458,13 @@ return 1; } *ptr = S->bound_result[colno].buffer; + if (S->out_length[colno] > S->bound_result[colno].buffer_length) { + /* mysql lied about the column width */ + strcpy(stmt->error_code, "01004"); /* truncated */ + S->out_length[colno] = S->bound_result[colno].buffer_length; + *len = S->out_length[colno]; + return 0; + } *len = S->out_length[colno]; return 1; }
-- PHP CVS Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php