return 1;
}
-static int pdo_dblib_stmt_stringify_col(pdo_stmt_t *stmt, int coltype)
+static int pdo_dblib_stmt_should_stringify_col(pdo_stmt_t *stmt, int coltype)
{
pdo_dblib_stmt *S = (pdo_dblib_stmt*)stmt->driver_data;
pdo_dblib_db_handle *H = S->H;
return 0;
}
+static void pdo_dblib_stmt_stringify_col(int coltype, LPBYTE data, DBINT data_len, zval **ptr)
+{
+ DBCHAR *tmp_data;
+ DBINT tmp_data_len;
+ zval *zv;
+
+ /* FIXME: We allocate more than we need here */
+ tmp_data_len = 32 + (2 * (data_len));
+
+ switch (coltype) {
+ case SQLDATETIME:
+ case SQLDATETIM4: {
+ if (tmp_data_len < DATETIME_MAX_LEN) {
+ tmp_data_len = DATETIME_MAX_LEN;
+ }
+ break;
+ }
+ }
+
+ tmp_data = emalloc(tmp_data_len);
+ data_len = dbconvert(NULL, coltype, data, data_len, SQLCHAR, (LPBYTE) tmp_data, tmp_data_len);
+
+ zv = emalloc(sizeof(zval));
+ if (data_len > 0) {
+ /* to prevent overflows, tmp_data_len is provided as a dest len for dbconvert()
+ * this code previously passed a dest len of -1
+ * the FreeTDS impl of dbconvert() does an rtrim with that value, so replicate that behavior
+ */
+ while (data_len > 0 && tmp_data[data_len - 1] == ' ') {
+ data_len--;
+ }
+
+ ZVAL_STRINGL(zv, tmp_data, data_len);
+ } else {
+ ZVAL_EMPTY_STRING(zv);
+ }
+
+ efree(tmp_data);
+
+ *ptr = zv;
+}
+
static int pdo_dblib_stmt_get_col(pdo_stmt_t *stmt, int colno, char **ptr,
zend_ulong *len, int *caller_frees)
{
data_len = dbdatlen(H->link, colno+1);
if (data_len != 0 || data != NULL) {
- if (pdo_dblib_stmt_stringify_col(stmt, coltype) && dbwillconvert(coltype, SQLCHAR)) {
- tmp_data_len = 32 + (2 * (data_len)); /* FIXME: We allocate more than we need here */
- tmp_data = emalloc(tmp_data_len);
- data_len = dbconvert(NULL, coltype, data, data_len, SQLCHAR, (LPBYTE) tmp_data, -1);
-
- zv = emalloc(sizeof(zval));
- ZVAL_STRING(zv, tmp_data);
-
- efree(tmp_data);
+ if (pdo_dblib_stmt_should_stringify_col(stmt, coltype) && dbwillconvert(coltype, SQLCHAR)) {
+ pdo_dblib_stmt_stringify_col(coltype, data, data_len, &zv);
}
if (!zv) {
zv = emalloc(sizeof(zval));
ZVAL_STRINGL(zv, tmp_data, data_len);
efree(tmp_data);
-
} else {
/* 16-byte binary representation */
zv = emalloc(sizeof(zval));
default: {
if (dbwillconvert(coltype, SQLCHAR)) {
- tmp_data_len = 32 + (2 * (data_len)); /* FIXME: We allocate more than we need here */
- tmp_data = emalloc(tmp_data_len);
- data_len = dbconvert(NULL, coltype, data, data_len, SQLCHAR, (LPBYTE) tmp_data, -1);
-
- zv = emalloc(sizeof(zval));
- ZVAL_STRING(zv, tmp_data);
-
- efree(tmp_data);
+ pdo_dblib_stmt_stringify_col(coltype, data, data_len, &zv);
}
break;