mirror of
https://github.com/php/php-src.git
synced 2024-09-23 10:57:26 +00:00
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.
This commit is contained in:
parent
fab0baa274
commit
fdd42afa6c
@ -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, ¶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 @@ 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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user