You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@apr.apache.org by tr...@apache.org on 2011/03/09 19:58:18 UTC

svn commit: r1079933 - /apr/apr-util/branches/1.5.x/dbd/apr_dbd_odbc.c

Author: trawick
Date: Wed Mar  9 18:58:18 2011
New Revision: 1079933

URL: http://svn.apache.org/viewvc?rev=1079933&view=rev
Log:
merge from apr trunk:

r1078737:
fix some existing parameter range checking that had a bad
assumption about the size of array entries

add the same range check in another path

r1078744:
replace some strcpy() calls with apr_cpystrn()
(no overflow currently)

r1079872:
zap the never-used apr_env_get() retcode

r1079901:
apr_dbd odbc: Fix stack buffer overwrite when an unexpected 
number of parameters is passed to open.

Modified:
    apr/apr-util/branches/1.5.x/dbd/apr_dbd_odbc.c

Modified: apr/apr-util/branches/1.5.x/dbd/apr_dbd_odbc.c
URL: http://svn.apache.org/viewvc/apr/apr-util/branches/1.5.x/dbd/apr_dbd_odbc.c?rev=1079933&r1=1079932&r2=1079933&view=diff
==============================================================================
--- apr/apr-util/branches/1.5.x/dbd/apr_dbd_odbc.c (original)
+++ apr/apr-util/branches/1.5.x/dbd/apr_dbd_odbc.c Wed Mar  9 18:58:18 2011
@@ -202,7 +202,7 @@ typedef struct {
 
 /* SQL datatype mappings to DBD datatypes 
  * These tables must correspond *exactly* to the apr_dbd_type_e enum 
- * in apr_dbd_internal.h 
+ * in apr_dbd.h
  */
 
 /* ODBC "C" types to DBD datatypes  */
@@ -231,6 +231,7 @@ static SQLSMALLINT const sqlCtype[] = {
     SQL_LONGVARCHAR,                /* APR_DBD_TYPE_CLOB,       \%pDc */
     SQL_TYPE_NULL                   /* APR_DBD_TYPE_NULL        \%pDn */
 };
+#define NUM_APR_DBD_TYPES (sizeof(sqlCtype) / sizeof(sqlCtype[0]))
 
 /*  ODBC Base types to DBD datatypes */
 static SQLSMALLINT const sqlBaseType[] = {
@@ -528,6 +529,10 @@ static SQLRETURN odbc_bind_param(apr_poo
     }
     /* bind a non-NULL data value */
     else {
+        if (type < 0 || type >= NUM_APR_DBD_TYPES) {
+            return APR_EGENERAL;
+        }
+
         baseType = sqlBaseType[type];
         cType = sqlCtype[type];
         indicator = NULL;
@@ -814,7 +819,7 @@ static apr_status_t odbc_parse_params(ap
                                int *defaultBufferSize, int *nattrs,
                                int **attrs, int **attrvals)
 {
-    char *seps, *last, *name[MAX_PARAMS], *val[MAX_PARAMS];
+    char *seps, *last, *next, *name[MAX_PARAMS], *val[MAX_PARAMS];
     int nparams = 0, i, j;
 
     *attrs = apr_pcalloc(pool, MAX_PARAMS * sizeof(char *));
@@ -834,8 +839,18 @@ static apr_status_t odbc_parse_params(ap
         }
         val[nparams] = apr_strtok(NULL, seps, &last);
         seps = DEFAULTSEPS;
-        name[++nparams] = apr_strtok(NULL, seps, &last);
-    } while (nparams <= MAX_PARAMS && name[nparams] != NULL);
+
+        ++nparams;
+        next = apr_strtok(NULL, seps, &last);
+        if (!next) {
+            break;
+        }
+        if (nparams >= MAX_PARAMS) {
+            /* too many parameters, no place to store */
+            return APR_EGENERAL;
+        }
+        name[nparams] = next;
+    } while (1);
 
     for (j = i = 0; i < nparams; i++) {
         if (!apr_strnatcasecmp(name[i], "CONNECT")) {
@@ -904,15 +919,16 @@ static void check_error(apr_dbd_t *dbc, 
     SQLSMALLINT reslength;
     char *res, *p, *end, *logval = NULL;
     int i;
-    apr_status_t r;
 
     /* set info about last error in dbc  - fast return for SQL_SUCCESS  */
     if (rc == SQL_SUCCESS) {
         char successMsg[] = "[dbd_odbc] SQL_SUCCESS ";
+        apr_size_t successMsgLen = sizeof successMsg - 1;
 
         dbc->lasterrorcode = SQL_SUCCESS;
-        strcpy(dbc->lastError, successMsg);
-        strcpy(dbc->lastError + sizeof(successMsg) - 1, step);
+        apr_cpystrn(dbc->lastError, successMsg, sizeof dbc->lastError);
+        apr_cpystrn(dbc->lastError + successMsgLen, step,
+                    sizeof dbc->lastError - successMsgLen);
         return;
     }
     switch (rc) {
@@ -953,7 +969,7 @@ static void check_error(apr_dbd_t *dbc, 
         if (SQL_SUCCEEDED(rc) && (p < (end - 280))) 
             p += sprintf(p, "%.256s %.20s ", buffer, sqlstate);
     }
-    r = apr_env_get(&logval, "apr_dbd_odbc_log", dbc->pool);
+    apr_env_get(&logval, "apr_dbd_odbc_log", dbc->pool);
     /* if env var was set or call was init/open (no dbname) - log to stderr */
     if (logval || !dbc->dbname ) {
         char timestamp[APR_CTIME_LEN];
@@ -969,7 +985,8 @@ static APR_INLINE int odbc_check_rollbac
 {
     if (handle->can_commit == APR_DBD_TRANSACTION_ROLLBACK) {
         handle->lasterrorcode = SQL_ERROR;
-        strcpy(handle->lastError, "[dbd_odbc] Rollback pending ");
+        apr_cpystrn(handle->lastError, "[dbd_odbc] Rollback pending ",
+                    sizeof handle->lastError);
         return 1;
     }
     return 0;
@@ -1338,15 +1355,17 @@ static apr_status_t odbc_datum_get(const
 {
     SQLSMALLINT sqltype;
     void *p;
-    int len = sqlSizes[dbdtype];
+    int len;
 
     if (col >= row->res->ncols)
         return APR_EGENERAL;
 
-    if (dbdtype < 0 || dbdtype >= sizeof(sqlCtype)) {
+    if (dbdtype < 0 || dbdtype >= NUM_APR_DBD_TYPES) {
         data = NULL;            /* invalid type */
         return APR_EGENERAL;
     }
+
+    len = sqlSizes[dbdtype];
     sqltype = sqlCtype[dbdtype];
 
     /* must not memcpy a brigade, sentinals are relative to orig loc */