]> granicus.if.org Git - php/commitdiff
FIX BUG #55647, #60512, #60512, #61900, #64338, #64808, #63638
authorStanley Sufficool <ssufficool@php.net>
Tue, 4 Jun 2013 03:34:47 +0000 (20:34 -0700)
committerStanley Sufficool <ssufficool@php.net>
Tue, 4 Jun 2013 03:34:47 +0000 (20:34 -0700)
Return an error on passwords longer than 30 chars instead of segfault.
Set error and message handlers properly.
Do not segfault in out of bound colnums in getColumnMeta()
Fix DBSETOPT to use a blank string instead of NULL to stop FreeTDS complaints.
Use DBSETLDBNAME for compatibillity with SQL Azure.

ext/pdo_dblib/dblib_driver.c
ext/pdo_dblib/dblib_stmt.c
ext/pdo_dblib/pdo_dblib.c
ext/pdo_dblib/php_pdo_dblib_int.h

index ffc910177fdd3ff2a452152f54416967db75c683..9baedbe9d24a639ae69f0fb2c386a8e488822972 100644 (file)
@@ -262,17 +262,19 @@ static struct pdo_dbh_methods dblib_methods = {
 static int pdo_dblib_handle_factory(pdo_dbh_t *dbh, zval *driver_options TSRMLS_DC)
 {
        pdo_dblib_db_handle *H;
-       int i, ret = 0;
+       int i, nvars, ret = 0;
        struct pdo_data_src_parser vars[] = {
-               { "charset",    NULL,   0 },
-               { "appname",    "PHP " PDO_DBLIB_FLAVOUR,       0 },
-               { "host",               "127.0.0.1", 0 },
-               { "dbname",             NULL,   0 },
-               { "secure",             NULL,   0 }, /* DBSETLSECURE */
-               /* TODO: DBSETLVERSION */
+               { "charset",    NULL,   0 }
+               ,{ "appname",   "PHP " PDO_DBLIB_FLAVOUR,       0 }
+               ,{ "host",              "127.0.0.1", 0 }
+               ,{ "dbname",    NULL,   0 }
+               ,{ "secure",    NULL,   0 } /* DBSETLSECURE */
+               /* TODO: DBSETLVERSION */
        };
-
-       php_pdo_parse_data_source(dbh->data_source, dbh->data_source_len, vars, 5);
+       
+       nvars = sizeof(vars)/sizeof(vars[0]);
+       
+       php_pdo_parse_data_source(dbh->data_source, dbh->data_source_len, vars, nvars);
 
        H = pecalloc(1, sizeof(*H), dbh->is_persistent);
        H->login = dblogin();
@@ -283,10 +285,15 @@ static int pdo_dblib_handle_factory(pdo_dbh_t *dbh, zval *driver_options TSRMLS_
        }
 
        if (dbh->username) {
-               DBSETLUSER(H->login, dbh->username);
+               if(FAIL == DBSETLUSER(H->login, dbh->username)) {
+                       goto cleanup;
+               }
        }
+
        if (dbh->password) {
-               DBSETLPWD(H->login, dbh->password);
+               if(FAIL == DBSETLPWD(H->login, dbh->password)) {
+                       goto cleanup;
+               }
        }
        
 #if !PHP_DBLIB_IS_MSSQL
@@ -297,14 +304,12 @@ static int pdo_dblib_handle_factory(pdo_dbh_t *dbh, zval *driver_options TSRMLS_
 
        DBSETLAPP(H->login, vars[1].optval);
 
-#if PHP_DBLIB_IS_MSSQL
-       dbprocerrhandle(H->login, (EHANDLEFUNC) error_handler);
-       dbprocmsghandle(H->login, (MHANDLEFUNC) msg_handler);
-#endif
+       DBERRHANDLE(H->login, (EHANDLEFUNC) error_handler);
+       DBMSGHANDLE(H->login, (MHANDLEFUNC) msg_handler);
 
        H->link = dbopen(H->login, vars[2].optval);
 
-       if (H->link == NULL) {
+       if (!H->link) {
                goto cleanup;
        }
 
@@ -315,10 +320,10 @@ static int pdo_dblib_handle_factory(pdo_dbh_t *dbh, zval *driver_options TSRMLS_
        DBSETOPT(H->link, DBTEXTSIZE, "2147483647");
 
        /* 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)) {
-               goto cleanup;
+       if (vars[3].optval) {
+               DBSETLDBNAME(H->login, vars[3].optval);
        }
 
        ret = 1;
@@ -326,7 +331,7 @@ static int pdo_dblib_handle_factory(pdo_dbh_t *dbh, zval *driver_options TSRMLS_
        dbh->alloc_own_columns = 1;
 
 cleanup:
-       for (i = 0; i < sizeof(vars)/sizeof(vars[0]); i++) {
+       for (i = 0; i < nvars; i++) {
                if (vars[i].freeme) {
                        efree(vars[i].optval);
                }
index 1a2fefd47a9b189e96729a5b52fd8e8b9f9c2dd7..c303045a3f4201ea31580418859411da33320a73 100644 (file)
@@ -87,8 +87,8 @@ static int dblib_dblib_stmt_cursor_closer(pdo_stmt_t *stmt TSRMLS_DC)
 
        /* Cancel any pending results */
        dbcancel(H->link);
-
-       efree(stmt->columns);
+       
+       efree(stmt->columns); 
        stmt->columns = NULL;
        
        return 1;
@@ -98,8 +98,6 @@ static int pdo_dblib_stmt_dtor(pdo_stmt_t *stmt TSRMLS_DC)
 {
        pdo_dblib_stmt *S = (pdo_dblib_stmt*)stmt->driver_data;
 
-       dblib_dblib_stmt_cursor_closer(stmt TSRMLS_CC);
-
        efree(S);
                
        return 1;
@@ -113,7 +111,12 @@ static int pdo_dblib_stmt_next_rowset(pdo_stmt_t *stmt TSRMLS_DC)
        
        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;
        }
        
@@ -131,6 +134,8 @@ static int pdo_dblib_stmt_execute(pdo_stmt_t *stmt TSRMLS_DC)
        
        dbsetuserdata(H->link, (BYTE*) &S->err);
        
+       dblib_dblib_stmt_cursor_closer(stmt TSRMLS_CC);
+       
        if (FAIL == dbcmd(H->link, stmt->active_query_string)) {
                return 0;
        }
@@ -141,10 +146,6 @@ static int pdo_dblib_stmt_execute(pdo_stmt_t *stmt TSRMLS_DC)
        
        ret = pdo_dblib_stmt_next_rowset(stmt TSRMLS_CC);
        
-       if (ret == 0) {
-               return 0;
-       }
-       
        stmt->row_count = DBCOUNT(H->link);
        stmt->column_count = dbnumcols(H->link);
        
@@ -162,7 +163,12 @@ static int pdo_dblib_stmt_fetch(pdo_stmt_t *stmt,
        
        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;
        }
        
@@ -174,6 +180,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_db_handle *H = S->H;
        
+       if(colno >= stmt->column_count || colno < 0)  {
+               return FAILURE;
+       }
+       
        struct pdo_column_data *col = &stmt->columns[colno];
        
        col->name = (char*)dbcolname(H->link, colno+1);
@@ -225,20 +235,12 @@ static int pdo_dblib_stmt_get_col(pdo_stmt_t *stmt, int colno, char **ptr,
                        *ptr = tmp_ptr;
                        break;
                }
-#ifdef SQLUNIQUE
                case SQLUNIQUE: {
-#else
-               case 36: { /* FreeTDS hack, also used by ext/mssql */
-#endif
                        *len = 36+1;
                        tmp_ptr = emalloc(*len + 1);
 
                        /* 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);
-#else
-                       *len = dbconvert(NULL, 36, *ptr, *len, SQLCHAR, tmp_ptr, *len);
-#endif
                        php_strtoupper(tmp_ptr, *len);
                        *ptr = tmp_ptr;
                        break;
@@ -270,11 +272,17 @@ 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_db_handle *H = S->H;
-       
+       DBTYPEINFO* dbtypeinfo;
+
+       if(colno >= stmt->column_count || colno < 0)  {
+               return FAILURE;
+       }
+
        array_init(return_value);
 
-       DBTYPEINFO* dbtypeinfo;
        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, "precision", (int) dbtypeinfo->precision );
index ed79aea20d16e9ee7e9fb41530e6be8d25ed040a..bc5d364ed338449485ec4d0590dedf1e2b5a1ea3 100644 (file)
@@ -93,8 +93,12 @@ int error_handler(DBPROCESS *dbproc, int severity, int dberr,
        char *state = "HY000";
        TSRMLS_FETCH();
 
-       einfo = (pdo_dblib_err*)dbgetuserdata(dbproc);
-       if (!einfo) einfo = &DBLIB_G(err);
+       if(dbproc) {
+               einfo = (pdo_dblib_err*)dbgetuserdata(dbproc);
+               if (!einfo) einfo = &DBLIB_G(err);
+       } else {
+               einfo = &DBLIB_G(err);
+       }       
 
        einfo->severity = severity;
        einfo->oserr = oserr;
index dd06a1d94fb12dfd095aa4a9c85ce5e653999d5d..3670de7439791959334df2c26d2bbb5648f588b5 100644 (file)
@@ -71,6 +71,8 @@
 # define SQLVARBINARY  SYBVARBINARY
 # ifdef SYBUNIQUE
 #  define SQLUNIQUE            SYBUNIQUE
+#else 
+#  define SQLUNIQUE            36 /* FreeTDS Hack */
 # endif
 
 # define DBERRHANDLE(a, b)     dberrhandle(b)