cvs: php-src(PHP_5_1) /ext/pdo_mysql mysql_statement.c
| From: | Wez Furlong | Date: | Sun, 25 Sep 2005 02:05:06 +0000 |
| Subject: | cvs: php-src(PHP_5_1) /ext/pdo_mysql mysql_statement.c | ||
| Groups: | php.cvs | ||
| Request: | Send a blank email to php-cvs+get-34126@lists.php.net to get a copy of this message | ||
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;
}