summaryrefslogtreecommitdiff
path: root/ext/pdo_mysql/mysql_statement.c
diff options
context:
space:
mode:
Diffstat (limited to 'ext/pdo_mysql/mysql_statement.c')
-rwxr-xr-xext/pdo_mysql/mysql_statement.c44
1 files changed, 43 insertions, 1 deletions
diff --git a/ext/pdo_mysql/mysql_statement.c b/ext/pdo_mysql/mysql_statement.c
index 51255b7f12..6db1ea29bc 100755
--- a/ext/pdo_mysql/mysql_statement.c
+++ b/ext/pdo_mysql/mysql_statement.c
@@ -142,6 +142,26 @@ static int pdo_mysql_stmt_execute(pdo_stmt_t *stmt TSRMLS_DC)
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 @@ static int pdo_mysql_stmt_param_hook(pdo_stmt_t *stmt, struct pdo_bound_param_da
}
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, &param->parameter);
+ if (stm) {
+ SEPARATE_ZVAL_IF_NOT_REF(&param->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 @@ static int pdo_mysql_stmt_get_col(pdo_stmt_t *stmt, int colno, char **ptr, unsig
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;
}