PDO DBLIB would segfault on getcolumn meta when colno was
out of bounds. DBLIB connection specified null arg to dbsetopt
per Microsoft technical docs, but FreeTDS complains. The SQL USE
statement was invalid for SQL Azure, use DBSETLDBNAME instead.
This commit is contained in:
Stanley Sufficool 2013-05-31 22:53:08 -07:00
parent d22c7368e7
commit 0e2bcf3373
3 changed files with 31 additions and 16 deletions

View File

@ -315,10 +315,10 @@ static int pdo_dblib_handle_factory(pdo_dbh_t *dbh, zval *driver_options TSRMLS_
DBSETOPT(H->link, DBTEXTSIZE, "2147483647"); DBSETOPT(H->link, DBTEXTSIZE, "2147483647");
/* allow double quoted indentifiers */ /* allow double quoted indentifiers */
DBSETOPT(H->link, DBQUOTEDIDENT, NULL); DBSETOPT(H->link, DBQUOTEDIDENT, "1");
if (vars[3].optval && FAIL == dbuse(H->link, vars[3].optval)) { if (vars[3].optval) {
goto cleanup; DBSETLDBNAME(H->login, vars[3].optval);
} }
ret = 1; ret = 1;

View File

@ -87,6 +87,7 @@ static int dblib_dblib_stmt_cursor_closer(pdo_stmt_t *stmt TSRMLS_DC)
/* Cancel any pending results */ /* Cancel any pending results */
dbcancel(H->link); dbcancel(H->link);
efree(stmt->columns); efree(stmt->columns);
stmt->columns = NULL; stmt->columns = NULL;
@ -110,7 +111,12 @@ static int pdo_dblib_stmt_next_rowset(pdo_stmt_t *stmt TSRMLS_DC)
ret = dbresults(H->link); ret = dbresults(H->link);
if (ret == FAIL || ret == NO_MORE_RESULTS) { if (FAIL == ret) {
pdo_raise_impl_error(stmt->dbh, stmt, "HY000", "DBLIB: dbresults() returned FAIL" TSRMLS_CC);
return 0;
}
if(NO_MORE_RESULTS == ret) {
return 0; return 0;
} }
@ -161,7 +167,12 @@ static int pdo_dblib_stmt_fetch(pdo_stmt_t *stmt,
ret = dbnextrow(H->link); ret = dbnextrow(H->link);
if (ret == FAIL || ret == NO_MORE_ROWS) { if (FAIL == ret) {
pdo_raise_impl_error(stmt->dbh, stmt, "HY000", "DBLIB: dbnextrow() returned FAIL" TSRMLS_CC);
return 0;
}
if(NO_MORE_ROWS == ret) {
return 0; return 0;
} }
@ -173,6 +184,10 @@ static int pdo_dblib_stmt_describe(pdo_stmt_t *stmt, int colno TSRMLS_DC)
pdo_dblib_stmt *S = (pdo_dblib_stmt*)stmt->driver_data; pdo_dblib_stmt *S = (pdo_dblib_stmt*)stmt->driver_data;
pdo_dblib_db_handle *H = S->H; pdo_dblib_db_handle *H = S->H;
if(colno >= stmt->column_count || colno < 0) {
return FAILURE;
}
struct pdo_column_data *col = &stmt->columns[colno]; struct pdo_column_data *col = &stmt->columns[colno];
col->name = (char*)dbcolname(H->link, colno+1); col->name = (char*)dbcolname(H->link, colno+1);
@ -224,20 +239,12 @@ static int pdo_dblib_stmt_get_col(pdo_stmt_t *stmt, int colno, char **ptr,
*ptr = tmp_ptr; *ptr = tmp_ptr;
break; break;
} }
#ifdef SQLUNIQUE
case SQLUNIQUE: { case SQLUNIQUE: {
#else
case 36: { /* FreeTDS hack, also used by ext/mssql */
#endif
*len = 36+1; *len = 36+1;
tmp_ptr = emalloc(*len + 1); tmp_ptr = emalloc(*len + 1);
/* uniqueidentifier is a 16-byte binary number, convert to 32 char hex string */ /* uniqueidentifier is a 16-byte binary number, convert to 32 char hex string */
#ifdef SQLUNIQUE
*len = dbconvert(NULL, SQLUNIQUE, *ptr, *len, SQLCHAR, tmp_ptr, *len); *len = dbconvert(NULL, SQLUNIQUE, *ptr, *len, SQLCHAR, tmp_ptr, *len);
#else
*len = dbconvert(NULL, 36, *ptr, *len, SQLCHAR, tmp_ptr, *len);
#endif
php_strtoupper(tmp_ptr, *len); php_strtoupper(tmp_ptr, *len);
*ptr = tmp_ptr; *ptr = tmp_ptr;
break; break;
@ -269,12 +276,18 @@ static int pdo_dblib_stmt_get_column_meta(pdo_stmt_t *stmt, long colno, zval *re
{ {
pdo_dblib_stmt *S = (pdo_dblib_stmt*)stmt->driver_data; pdo_dblib_stmt *S = (pdo_dblib_stmt*)stmt->driver_data;
pdo_dblib_db_handle *H = S->H; pdo_dblib_db_handle *H = S->H;
DBTYPEINFO* dbtypeinfo;
if(colno >= stmt->column_count || colno < 0) {
return FAILURE;
}
array_init(return_value); array_init(return_value);
DBTYPEINFO* dbtypeinfo;
dbtypeinfo = dbcoltypeinfo(H->link, colno+1); dbtypeinfo = dbcoltypeinfo(H->link, colno+1);
if(!dbtypeinfo) return FAILURE;
add_assoc_long(return_value, "max_length", dbcollen(H->link, colno+1) ); add_assoc_long(return_value, "max_length", dbcollen(H->link, colno+1) );
add_assoc_long(return_value, "precision", (int) dbtypeinfo->precision ); add_assoc_long(return_value, "precision", (int) dbtypeinfo->precision );
add_assoc_long(return_value, "scale", (int) dbtypeinfo->scale ); add_assoc_long(return_value, "scale", (int) dbtypeinfo->scale );

View File

@ -71,6 +71,8 @@
# define SQLVARBINARY SYBVARBINARY # define SQLVARBINARY SYBVARBINARY
# ifdef SYBUNIQUE # ifdef SYBUNIQUE
# define SQLUNIQUE SYBUNIQUE # define SQLUNIQUE SYBUNIQUE
#else
# define SQLUNIQUE 36 /* FreeTDS Hack */
# endif # endif
# define DBERRHANDLE(a, b) dberrhandle(b) # define DBERRHANDLE(a, b) dberrhandle(b)