Patch Firebird_Native_Data_Types for PDO Firebird Bug #63356
Patch version 2012-10-25 08:11 UTC
Return to Bug #63356 |
Download this patch
Patch Revisions:
Developer: james@kenjim.com
diff --git a/ext/pdo/pdo_stmt.c b/ext/pdo/pdo_stmt.c
index 31932eb..6f20c4a 100644
--- a/ext/pdo/pdo_stmt.c
+++ b/ext/pdo/pdo_stmt.c
@@ -564,8 +564,9 @@ static inline void fetch_value(pdo_stmt_t *stmt, zval *dest, int colno, int *typ
case PDO_PARAM_ZVAL:
if (value && value_len == sizeof(zval)) {
int need_copy = (new_type != PDO_PARAM_ZVAL || stmt->dbh->stringify) ? 1 : 0;
- zval *zv = *(zval**)value;
- ZVAL_ZVAL(dest, zv, need_copy, 1);
+ zval *zv = (zval*)value;
+ ZVAL_ZVAL(dest, zv, need_copy, caller_frees);
+ caller_frees = 0;
} else {
ZVAL_NULL(dest);
}
diff --git a/ext/pdo_firebird/firebird_statement.c b/ext/pdo_firebird/firebird_statement.c
index ae05870..eed817b 100644
--- a/ext/pdo_firebird/firebird_statement.c
+++ b/ext/pdo_firebird/firebird_statement.c
@@ -208,7 +208,7 @@ static int firebird_stmt_describe(pdo_stmt_t *stmt, int colno TSRMLS_DC) /* {{{
}
memmove(cp, var->aliasname, var->aliasname_length);
*(cp+var->aliasname_length) = '\0';
- col->param_type = PDO_PARAM_STR;
+ col->param_type = PDO_PARAM_ZVAL;
return 1;
}
@@ -269,7 +269,7 @@ static int firebird_fetch_blob(pdo_stmt_t *stmt, int colno, char **ptr, /* {{{ *
unsigned short seg_len;
ISC_STATUS stat;
- *ptr = S->fetch_buf[colno] = erealloc(*ptr, *len+1);
+ *ptr = erealloc(*ptr, *len+1);
for (cur_len = stat = 0; (!stat || stat == isc_segment) && cur_len < *len; cur_len += seg_len) {
@@ -302,12 +302,18 @@ static int firebird_stmt_get_col(pdo_stmt_t *stmt, int colno, char **ptr, /* {{
{
pdo_firebird_stmt *S = (pdo_firebird_stmt*)stmt->driver_data;
XSQLVAR const *var = &S->out_sqlda.sqlvar[colno];
+ zval *result;
if (*var->sqlind == -1) {
/* A NULL value */
*ptr = NULL;
*len = 0;
} else {
+ MAKE_STD_ZVAL(result);
+ *len = sizeof(zval);
+ *ptr = (char*)result;
+ *caller_frees = 1;
+
if (var->sqlscale < 0) {
static ISC_INT64 const scales[] = { 1, 10, 100, 1000,
10000,
@@ -339,49 +345,55 @@ static int firebird_stmt_get_col(pdo_stmt_t *stmt, int colno, char **ptr, /* {{
n = *(ISC_INT64*)var->sqldata;
}
- *ptr = FETCH_BUF(S->fetch_buf[colno], char, CHAR_BUF_LEN, NULL);
+ char* tmp = FETCH_BUF(S->fetch_buf[colno], char, CHAR_BUF_LEN, NULL);
+ int tmp_len = 0;
if (n >= 0) {
- *len = slprintf(*ptr, CHAR_BUF_LEN, "%" LL_MASK "d.%0*" LL_MASK "d",
+ tmp_len = slprintf(tmp, CHAR_BUF_LEN, "%" LL_MASK "d.%0*" LL_MASK "d",
n / f, -var->sqlscale, n % f);
} else if (n < -f) {
- *len = slprintf(*ptr, CHAR_BUF_LEN, "%" LL_MASK "d.%0*" LL_MASK "d",
+ tmp_len = slprintf(tmp, CHAR_BUF_LEN, "%" LL_MASK "d.%0*" LL_MASK "d",
n / f, -var->sqlscale, -n % f);
- } else {
- *len = slprintf(*ptr, CHAR_BUF_LEN, "-0.%0*" LL_MASK "d", -var->sqlscale, -n % f);
+ } else {
+ tmp_len = slprintf(tmp, CHAR_BUF_LEN, "-0.%0*" LL_MASK "d", -var->sqlscale, -n % f);
}
+ ZVAL_STRINGL(result, tmp, tmp_len, 0);
} else {
switch (var->sqltype & ~1) {
struct tm t;
char *fmt;
case SQL_VARYING:
- *ptr = &var->sqldata[2];
- *len = *(short*)var->sqldata;
+ ZVAL_STRINGL(result, &var->sqldata[2], *(short*)var->sqldata, 1);
break;
case SQL_TEXT:
- *ptr = var->sqldata;
- *len = var->sqllen;
+ ZVAL_STRINGL(result, var->sqldata, var->sqllen, 1);
break;
case SQL_SHORT:
- *ptr = FETCH_BUF(S->fetch_buf[colno], char, CHAR_BUF_LEN, NULL);
- *len = slprintf(*ptr, CHAR_BUF_LEN, "%d", *(short*)var->sqldata);
+ ZVAL_LONG(result, *(short*)var->sqldata);
break;
case SQL_LONG:
- *ptr = FETCH_BUF(S->fetch_buf[colno], char, CHAR_BUF_LEN, NULL);
- *len = slprintf(*ptr, CHAR_BUF_LEN, "%ld", *(ISC_LONG*)var->sqldata);
+ ZVAL_LONG(result, *(ISC_LONG*)var->sqldata);
break;
case SQL_INT64:
- *ptr = FETCH_BUF(S->fetch_buf[colno], char, CHAR_BUF_LEN, NULL);
- *len = slprintf(*ptr, CHAR_BUF_LEN, "%" LL_MASK "d", *(ISC_INT64*)var->sqldata);
+ {
+ ISC_INT64 tmpValue = *(ISC_INT64*)var->sqldata;
+ if((tmpValue > LONG_MAX) || (tmpValue < LONG_MIN)) { //Too big to fit in a long.
+ char* tmp = FETCH_BUF(S->fetch_buf[colno], char, CHAR_BUF_LEN, NULL);
+ int temp_len = slprintf(tmp, CHAR_BUF_LEN, "%" LL_MASK "d", *(ISC_INT64*)var->sqldata);
+ ZVAL_STRINGL(result, tmp, temp_len, 0);
+ } else {
+ ZVAL_LONG(result, *(ISC_INT64*)var->sqldata);
+ }
+
+ }
+
break;
case SQL_FLOAT:
- *ptr = FETCH_BUF(S->fetch_buf[colno], char, CHAR_BUF_LEN, NULL);
- *len = slprintf(*ptr, CHAR_BUF_LEN, "%F", *(float*)var->sqldata);
+ ZVAL_DOUBLE(result, *(float*)var->sqldata);
break;
case SQL_DOUBLE:
- *ptr = FETCH_BUF(S->fetch_buf[colno], char, CHAR_BUF_LEN, NULL);
- *len = slprintf(*ptr, CHAR_BUF_LEN, "%F" , *(double*)var->sqldata);
+ ZVAL_DOUBLE(result, *(double*)var->sqldata);
break;
case SQL_TYPE_DATE:
isc_decode_sql_date((ISC_DATE*)var->sqldata, &t);
@@ -396,13 +408,27 @@ static int firebird_stmt_get_col(pdo_stmt_t *stmt, int colno, char **ptr, /* {{
fmt = S->H->timestamp_format ? S->H->timestamp_format : PDO_FB_DEF_TIMESTAMP_FMT;
}
/* convert the timestamp into a string */
- *len = 80;
- *ptr = FETCH_BUF(S->fetch_buf[colno], char, *len, NULL);
- *len = strftime(*ptr, *len, fmt, &t);
+ char *buffer = FETCH_BUF(S->fetch_buf[colno], char, 80, NULL);
+ int temp_len = strftime(buffer, 80, fmt, &t);
+ ZVAL_STRINGL(result, buffer, temp_len, 1);
break;
case SQL_BLOB:
- return firebird_fetch_blob(stmt,colno,ptr,len,
- (ISC_QUAD*)var->sqldata TSRMLS_CC);
+ {
+ char *blob_buffer = NULL;
+ unsigned long blob_len = 0;
+ if(!firebird_fetch_blob(stmt,colno,
+ &blob_buffer, &blob_len,
+ (ISC_QUAD*)var->sqldata TSRMLS_CC)) {
+ ZVAL_NULL(result);
+ return 0;
+ }
+
+
+ if(blob_len > INT_MAX) {
+ blob_len = INT_MAX;
+ }
+ ZVAL_STRINGL(result, blob_buffer, blob_len, 0);
+ }
}
}
}
@@ -424,30 +450,28 @@ static int firebird_bind_blob(pdo_stmt_t *stmt, ISC_QUAD *blob_id, zval *param T
return 0;
}
- SEPARATE_ZVAL(¶m);
-
- convert_to_string_ex(¶m);
+ //Blobs are always strings or nulls.
+ if(Z_TYPE_P(param) == IS_STRING) { //Make sure we did not get passed a NULL
+ char *buffer = Z_STRVAL_P(param);
+ for (rem_cnt = Z_STRLEN_P(param); rem_cnt > 0; rem_cnt -= chunk_size) {
- for (rem_cnt = Z_STRLEN_P(param); rem_cnt > 0; rem_cnt -= chunk_size) {
-
- chunk_size = rem_cnt > USHRT_MAX ? USHRT_MAX : (unsigned short)rem_cnt;
-
- if (isc_put_segment(H->isc_status, &h, chunk_size, &Z_STRVAL_P(param)[put_cnt])) {
- RECORD_ERROR(stmt);
- result = 0;
- break;
+ chunk_size = rem_cnt > USHRT_MAX ? USHRT_MAX : (unsigned short)rem_cnt;
+
+ if (isc_put_segment(H->isc_status, &h, chunk_size, &buffer[put_cnt])) {
+ RECORD_ERROR(stmt);
+ result = 0;
+ break;
+ }
+ put_cnt += chunk_size;
}
- put_cnt += chunk_size;
}
-
- zval_dtor(param);
if (isc_close_blob(H->isc_status, &h)) {
RECORD_ERROR(stmt);
return 0;
}
return result;
-}
+}
static int firebird_stmt_param_hook(pdo_stmt_t *stmt, struct pdo_bound_param_data *param, /* {{{ */
enum pdo_param_event event_type TSRMLS_DC)
@@ -582,49 +606,23 @@ static int firebird_stmt_param_hook(pdo_stmt_t *stmt, struct pdo_bound_param_dat
break;
case PDO_PARAM_EVT_FETCH_POST:
- if (param->paramno == -1) {
- return 0;
- }
- if (param->is_param) {
- break;
+ if (param->paramno == -1) {
+ return 0;
}
- value = NULL;
- value_len = 0;
- caller_frees = 0;
-
- if (firebird_stmt_get_col(stmt, param->paramno, &value, &value_len, &caller_frees TSRMLS_CC)) {
- switch (PDO_PARAM_TYPE(param->param_type)) {
- case PDO_PARAM_STR:
- if (value) {
- ZVAL_STRINGL(param->parameter, value, value_len, 1);
- break;
- }
- case PDO_PARAM_INT:
- if (value) {
- ZVAL_LONG(param->parameter, *(long*)value);
- break;
- }
- case PDO_PARAM_EVT_NORMALIZE:
- if (!param->is_param) {
- char *s = param->name;
- while (*s != '\0') {
- *s = toupper(*s);
- s++;
- }
- }
- break;
- default:
- ZVAL_NULL(param->parameter);
- }
- if (value && caller_frees) {
- efree(value);
+ break;
+
+ case PDO_PARAM_EVT_NORMALIZE:
+ if (!param->is_param) {
+ char *s = param->name;
+ while (*s != '\0') {
+ *s = toupper(*s);
+ s++;
}
- return 1;
}
- return 0;
+ break;
default:
;
- }
+ }
return 1;
}
/* }}} */
diff --git a/ext/pdo_mysql/mysql_statement.c b/ext/pdo_mysql/mysql_statement.c
index fc5ec51..b408a88 100644
--- a/ext/pdo_mysql/mysql_statement.c
+++ b/ext/pdo_mysql/mysql_statement.c
@@ -719,7 +719,7 @@ static int pdo_mysql_stmt_get_col(pdo_stmt_t *stmt, int colno, char **ptr, unsig
#if PDO_USE_MYSQLND
if (S->stmt) {
Z_ADDREF_P(S->stmt->data->result_bind[colno].zv);
- *ptr = (char*)&S->stmt->data->result_bind[colno].zv;
+ *ptr = (char*)S->stmt->data->result_bind[colno].zv;
*len = sizeof(zval);
PDO_DBG_RETURN(1);
}
|