From 4d44165af04d40e8aad405a9fbe31d7304c654c8 Mon Sep 17 00:00:00 2001 From: Hiroshi Inoue Date: Sat, 27 Feb 2016 11:23:23 +0900 Subject: [PATCH] Fix NULL dereferences which causes application crash. Patch by Tsunakawa, Takayuki. --- connection.c | 54 +++++++++++++++--------------------------------- connection.h | 2 -- convert.c | 16 +++++++++++---- descriptor.c | 12 +++++++++-- dlg_specific.c | 4 ++++ drvconn.c | 1 + environ.c | 3 ++- info.c | 45 +++++++++++++++++++++++++++++++++++----- misc.c | 1 + multibyte.c | 2 ++ odbcapi30w.c | 33 +++++++++++++++++++++-------- odbcapiw.c | 56 ++++++++++++++++++++++++++++++++++++++++---------- parse.c | 6 ++++++ pgapi30.c | 6 ++++++ psqlodbc.h | 7 +++++-- results.c | 42 ++++++++++++++++++++++++++----------- setup.c | 12 ++++++++--- statement.c | 8 +++++++- statement.h | 11 ++++++++++ tuple.c | 5 ++--- 20 files changed, 234 insertions(+), 92 deletions(-) diff --git a/connection.c b/connection.c index 8d2d7e7..41fd507 100644 --- a/connection.c +++ b/connection.c @@ -50,7 +50,6 @@ * at a time */ static void CC_lookup_lo(ConnectionClass *self); -static char *CC_create_errormsg(ConnectionClass *self); static int CC_close_eof_cursors(ConnectionClass *self); static void LIBPQ_update_transaction_status(ConnectionClass *self); @@ -522,7 +521,6 @@ CC_clear_error(ConnectionClass *self) self->__error_message = NULL; } self->sqlstate[0] = '\0'; - self->errormsg_created = FALSE; CONNLOCK_RELEASE(self); } @@ -1218,30 +1216,6 @@ mylog("max_identifier_length=%d\n", len); return len < 0 ? 0 : len; } -/* - * Create a more informative error message by concatenating the connection - * error message with its socket error message. - * - * XXX: actually, there is no such thing as socket error message anymore - */ -static char * -CC_create_errormsg(ConnectionClass *self) -{ - char msg[4096]; - - mylog("enter CC_create_errormsg\n"); - - msg[0] = '\0'; - - if (CC_get_errormsg(self)) - strncpy_null(msg, CC_get_errormsg(self), sizeof(msg)); - - mylog("msg = '%s'\n", msg); - - mylog("exit CC_create_errormsg\n"); - return strdup(msg); -} - void CC_set_error(ConnectionClass *self, int number, const char *message, const char *func) @@ -1274,20 +1248,10 @@ char CC_get_error(ConnectionClass *self, int *number, char **message) { int rv; - char *msgcrt; mylog("enter CC_get_error\n"); CONNLOCK_ACQUIRE(self); - /* Create a very informative errormsg if it hasn't been done yet. */ - if (!self->errormsg_created) - { - msgcrt = CC_create_errormsg(self); - if (self->__error_message) - free(self->__error_message); - self->__error_message = msgcrt; - self->errormsg_created = TRUE; - } if (CC_get_errornumber(self)) { @@ -1755,6 +1719,13 @@ CC_send_query_append(ConnectionClass *self, const char *query, QueryInfo *qi, UD if (query_completed) /* allow for "show" style notices */ { res->next = QR_Constructor(); + if (!res->next) + { + CC_set_error(self, CONNECTION_COULD_NOT_RECEIVE, "Could not create result info in send_query.", func); + ReadyToReturn = TRUE; + retres = NULL; + break; + } res = res->next; nrarg.res = res; } @@ -1904,6 +1875,13 @@ inolog("Discarded the first SAVEPOINT\n"); if (query_completed) { res->next = QR_Constructor(); + if (!res->next) + { + CC_set_error(self, CONNECTION_COULD_NOT_RECEIVE, "Could not create result info in send_query.", func); + ReadyToReturn = TRUE; + retres = NULL; + break; + } res = res->next; nrarg.res = res; } @@ -2369,7 +2347,8 @@ CC_get_current_schema(ConnectionClass *conn) if (curschema) conn->current_schema = strdup(curschema); } - conn->current_schema_valid = TRUE; + if (conn->current_schema) + conn->current_schema_valid = TRUE; } QR_Destructor(res); } @@ -3050,6 +3029,7 @@ PgDtc_isolate(void *self, DWORD option) return newconn; } newconn = CC_Constructor(); + if (!newconn) return NULL; CC_copy_conninfo(&newconn->connInfo, &sconn->connInfo); CC_initialize_pg_version(newconn); newconn->asdum = sconn->asdum; diff --git a/connection.h b/connection.h index c3c5f12..bc2ee7e 100644 --- a/connection.h +++ b/connection.h @@ -354,8 +354,6 @@ struct ConnectionClass_ DriverToDataSourceProc DriverToDataSource; char transact_status; /* Is a transaction is currently * in progress */ - char errormsg_created; /* has an informative error msg - * been created ? */ char pg_version[MAX_INFO_STRING]; /* Version of PostgreSQL * we're connected to - * DJP 25-1-2001 */ diff --git a/convert.c b/convert.c index 2297e6a..af40270 100644 --- a/convert.c +++ b/convert.c @@ -3046,6 +3046,11 @@ inolog("type=%d concur=%d\n", stmt->options.cursor_type, stmt->options.scroll_co } npos -= qp->declare_pos; stmt->load_statement = malloc(npos + 1); + if (!stmt->load_statement) + { + retval = SQL_ERROR; + goto cleanup; + } memcpy(stmt->load_statement, qb->query_statement + qp->declare_pos, npos); stmt->load_statement[npos] = '\0'; } @@ -4160,10 +4165,13 @@ inolog("ipara=%p paramType=%d %d proc_return=%d\n", ipara, ipara ? ipara->paramT if (SQL_NTS == used) used = strlen(buffer); allocbuf = malloc(WCLEN * (used + 1)); - used = msgtowstr(buffer, (int) used, (LPWSTR) allocbuf, (int) (used + 1)); - buf = ucs2_to_utf8((SQLWCHAR *) allocbuf, used, &used, FALSE); - free(allocbuf); - allocbuf = buf; + if (allocbuf) + { + used = msgtowstr(buffer, (int) used, (LPWSTR) allocbuf, (int) (used + 1)); + buf = ucs2_to_utf8((SQLWCHAR *) allocbuf, used, &used, FALSE); + free(allocbuf); + allocbuf = buf; + } #else buf = buffer; #endif /* WIN_UNICODE_SUPPORT */ diff --git a/descriptor.c b/descriptor.c index f30a0d7..bf851fd 100644 --- a/descriptor.c +++ b/descriptor.c @@ -352,7 +352,8 @@ static void ARDFields_copy(const ARDFields *src, ARDFields *target) if (src->bookmark) { BindInfoClass *bookmark = ARD_AllocBookmark(target); - BindInfoClass_copy(src->bookmark, bookmark); + if (bookmark) + BindInfoClass_copy(src->bookmark, bookmark); } if (src->allocated <= 0) { @@ -364,6 +365,8 @@ static void ARDFields_copy(const ARDFields *src, ARDFields *target) int i; target->bindings = malloc(target->allocated * sizeof(BindInfoClass)); + if (!target->bindings) + target->allocated = 0; for (i = 0; i < target->allocated; i++) BindInfoClass_copy(&src->bindings[i], &target->bindings[i]); } @@ -379,7 +382,8 @@ static void APDFields_copy(const APDFields *src, APDFields *target) if (src->bookmark) { target->bookmark = malloc(sizeof(ParameterInfoClass)); - ParameterInfoClass_copy(src->bookmark, target->bookmark); + if (target->bookmark) + ParameterInfoClass_copy(src->bookmark, target->bookmark); } if (src->allocated <= 0) { @@ -391,6 +395,8 @@ static void APDFields_copy(const APDFields *src, APDFields *target) int i; target->parameters = malloc(target->allocated * sizeof(ParameterInfoClass)); + if (!target->parameters) + target->allocated = 0; for (i = 0; i < target->allocated; i++) ParameterInfoClass_copy(&src->parameters[i], &target->parameters[i]); } @@ -413,6 +419,8 @@ static void IPDFields_copy(const IPDFields *src, IPDFields *target) int i; target->parameters = (ParameterImplClass *) malloc(target->allocated * sizeof(ParameterImplClass)); + if (!target->parameters) + target->allocated = 0; for (i = 0; i < target->allocated; i++) ParameterImplClass_copy(&src->parameters[i], &target->parameters[i]); } diff --git a/dlg_specific.c b/dlg_specific.c index 6ab7464..93f7d92 100644 --- a/dlg_specific.c +++ b/dlg_specific.c @@ -1544,6 +1544,8 @@ decode(const char *in) return out; } outs = (char *) malloc(ilen + 1); + if (!outs) + return out; for (i = 0; i < ilen; i++) { inc = in[i]; @@ -1687,6 +1689,8 @@ char *extract_extra_attribute_setting(const pgNAME setting, const char *attr) if (!sptr) return NULL; rptr = malloc(len + 1); + if (!rptr) + return NULL; memcpy(rptr, sptr, len); rptr[len] = '\0'; mylog("extracted a %s '%s' from %s\n", attr, rptr, str); diff --git a/drvconn.c b/drvconn.c index 01c4240..4880baf 100644 --- a/drvconn.c +++ b/drvconn.c @@ -47,6 +47,7 @@ static char * hide_password(const char *str) if (!str) return NULL; outstr = strdup(str); + if (!outstr) return NULL; if (pwdp = strstr(outstr, "PWD="), !pwdp) pwdp = strstr(outstr, "pwd="); if (pwdp) diff --git a/environ.c b/environ.c index 8a79921..99ebfee 100644 --- a/environ.c +++ b/environ.c @@ -174,7 +174,8 @@ ER_Dup(const PG_ErrorInfo *self) if (self->errorsize > 0) alsize += self->errorsize; new = (PG_ErrorInfo *) malloc(alsize); - memcpy(new, self, alsize); + if (new) + memcpy(new, self, alsize); return new; } diff --git a/info.c b/info.c index c68e139..a73232f 100644 --- a/info.c +++ b/info.c @@ -1518,6 +1518,7 @@ simpleCatalogEscape(const SQLCHAR *src, SQLLEN srclen, const ConnectionClass *co mylog("simple in=%s(%d)\n", src, srclen); encoded_str_constr(&encstr, conn->ccsc, (char *) src); dest = malloc(2 * srclen + 1); + if (!dest) return NULL; for (i = 0, in = (char *) src, outlen = 0; i < srclen; i++, in++) { encoded_nextchar(&encstr); @@ -1558,6 +1559,7 @@ adjustLikePattern(const SQLCHAR *src, int srclen, const ConnectionClass *conn) mylog("adjust in=%.*s(%d)\n", srclen, src, srclen); encoded_str_constr(&encstr, conn->ccsc, (char *) src); dest = malloc(4 * srclen + 1); + if (!dest) return NULL; for (i = 0, in = (char *) src, outlen = 0; i < srclen; i++, in++) { encoded_nextchar(&encstr); @@ -2502,6 +2504,12 @@ retry_public_schema: { mylog("len_needed=%d\n", len_needed); attdef = malloc(len_needed + 1); + if (!attdef) + { + SC_set_error(stmt, STMT_NO_MEMORY_ERROR, "Couldn't allocate memory for attdef.", func); + goto cleanup; + } + PGAPI_GetData(hcol_stmt, 13, internal_asis_type, attdef, len_needed + 1, &len_needed); mylog(" and the data=%s\n", attdef); } @@ -2912,6 +2920,12 @@ retry_public_schema: hcol_stmt = NULL; res = QR_Constructor(); + if (!res) + { + SC_set_error(stmt, STMT_NO_MEMORY_ERROR, "Couldn't allocate memory for query.", func); + result = SQL_ERROR; + goto cleanup; + } SC_set_Result(stmt, res); extend_column_bindings(SC_get_ARDF(stmt), 8); @@ -3177,12 +3191,16 @@ PGAPI_Statistics(HSTMT hstmt, alcount = 4; else alcount *= 2; - column_names = - (struct columns_idx *) realloc(column_names, - alcount * sizeof(struct columns_idx)); + SC_REALLOC_gexit_with_error(column_names, struct columns_idx, alcount * sizeof(struct columns_idx), stmt, "Couldn't allocate memory for column names.", (result = SQL_ERROR)); } column_names[total_columns].col_name = (char *) malloc(strlen(column_name) + 1); + if (!column_names[total_columns].col_name) + { + SC_set_error(stmt, STMT_NO_MEMORY_ERROR, "Couldn't allocate memory for column name.", func); + result = SQL_ERROR; + goto cleanup; + } strcpy(column_names[total_columns].col_name, column_name); column_names[total_columns].pnum = field_number; total_columns++; @@ -4008,8 +4026,14 @@ getClientColumnName(ConnectionClass *conn, UInt4 relid, char *serverColumnName, { if (QR_get_num_cached_tuples(res) > 0) { - ret = strdup(QR_get_value_backend_text(res, 0, 0)); - *nameAlloced = TRUE; + char *tmp; + + tmp = strdup(QR_get_value_backend_text(res, 0, 0)); + if (tmp) + { + ret = tmp; + *nameAlloced = TRUE; + } } } QR_Destructor(res); @@ -5424,6 +5448,11 @@ PGAPI_TablePrivileges(HSTMT hstmt, stmt->catalog_result = TRUE; /* set the field names */ res = QR_Constructor(); + if (!res) + { + SC_set_error(stmt, STMT_NO_MEMORY_ERROR, "Couldn't allocate memory for query.", func); + return SQL_ERROR; + } SC_set_Result(stmt, res); QR_set_num_fields(res, result_cols); QR_set_field_info_v(res, 0, "TABLE_CAT", PG_TYPE_VARCHAR, MAX_INFO_STRING); @@ -5511,6 +5540,12 @@ retry_public_schema: } usercount = (Int4) QR_get_num_cached_tuples(allures); useracl = (char (*)[ACLMAX]) malloc(usercount * sizeof(char [ACLMAX])); + if (!useracl) + { + SC_set_error(stmt, STMT_NO_MEMORY_ERROR, "Couldn't allocate memory for user acl.", func); + ret = SQL_ERROR; + goto cleanup; + } for (i = 0; i < tablecount; i++) { memset(useracl, 0, usercount * sizeof(char[ACLMAX])); diff --git a/misc.c b/misc.c index 4de590f..f76705a 100644 --- a/misc.c +++ b/misc.c @@ -182,6 +182,7 @@ make_lstring_ifneeded(ConnectionClass *conn, const SQLCHAR *s, ssize_t len, BOOL if (!str) { str = malloc(length + 1); + if (!str) return NULL; memcpy(str, s, length); str[length] = '\0'; } diff --git a/multibyte.c b/multibyte.c index b0bdd62..3955313 100644 --- a/multibyte.c +++ b/multibyte.c @@ -189,6 +189,8 @@ check_client_encoding(const pgNAME conn_settings) if (!sptr) return NULL; rptr = malloc(len + 1); + if (!rptr) + return NULL; memcpy(rptr, sptr, len); rptr[len] = '\0'; mylog("extracted a client_encoding '%s' from conn_settings\n", rptr); diff --git a/odbcapi30w.c b/odbcapi30w.c index 9d8b692..8434d50 100644 --- a/odbcapi30w.c +++ b/odbcapi30w.c @@ -158,7 +158,7 @@ SQLGetDescFieldW(SQLHDESC hdesc, SQLSMALLINT iRecord, SQLSMALLINT iField, CSTR func = "SQLGetDescFieldW"; RETCODE ret; SQLINTEGER blen = 0, bMax, *pcbV; - char *rgbV = NULL; + char *rgbV = NULL, *rgbVt; mylog("[%s]", func); switch (iField) @@ -175,10 +175,16 @@ SQLGetDescFieldW(SQLHDESC hdesc, SQLSMALLINT iRecord, SQLSMALLINT iField, case SQL_DESC_TABLE_NAME: case SQL_DESC_TYPE_NAME: bMax = cbValueMax * 3 / WCLEN; - rgbV = malloc(bMax + 1); + rgbVt = malloc(bMax + 1); pcbV = &blen; - for (;; bMax = blen + 1, rgbV = realloc(rgbV, bMax)) + for (;; bMax = blen + 1, rgbVt = realloc(rgbV, bMax)) { + if (!rgbVt) + { + ret = SQL_ERROR; + break; + } + rgbV = rgbVt; ret = PGAPI_GetDescField(hdesc, iRecord, iField, rgbV, bMax, pcbV); if (SQL_SUCCESS_WITH_INFO != ret || blen < bMax) break; @@ -279,7 +285,7 @@ SQLColAttributeW(SQLHSTMT hstmt, RETCODE ret; StatementClass *stmt = (StatementClass *) hstmt; SQLSMALLINT *rgbL, blen = 0, bMax; - char *rgbD = NULL; + char *rgbD = NULL, *rgbDt; mylog("[%s]", func); ENTER_STMT_CS(stmt); @@ -300,10 +306,16 @@ SQLColAttributeW(SQLHSTMT hstmt, case SQL_DESC_TYPE_NAME: case SQL_COLUMN_NAME: bMax = cbCharAttrMax * 3 / WCLEN; - rgbD = malloc(bMax); + rgbDt = malloc(bMax); rgbL = &blen; - for (;; bMax = blen + 1, rgbD = realloc(rgbD, bMax)) + for (;; bMax = blen + 1, rgbDt = realloc(rgbD, bMax)) { + if (!rgbDt) + { + ret = SQL_ERROR; + break; + } + rgbD = rgbDt; ret = PGAPI_ColAttributes(hstmt, iCol, iField, rgbD, bMax, rgbL, pNumAttr); if (SQL_SUCCESS_WITH_INFO != ret || blen < bMax) @@ -349,7 +361,7 @@ SQLGetDiagFieldW(SQLSMALLINT fHandleType, CSTR func = "SQLGetDiagFieldW"; RETCODE ret; SQLSMALLINT *rgbL, blen = 0, bMax; - char *rgbD = NULL; + char *rgbD = NULL, *rgbDt; mylog("[[%s]] Handle=(%u,%p) Rec=%d Id=%d info=(%p,%d)\n", func, fHandleType, handle, iRecord, fDiagField, rgbDiagInfo, cbDiagInfoMax); @@ -363,11 +375,14 @@ SQLGetDiagFieldW(SQLSMALLINT fHandleType, case SQL_DIAG_SQLSTATE: case SQL_DIAG_SUBCLASS_ORIGIN: bMax = cbDiagInfoMax * 3 / WCLEN + 1; - if (rgbD = malloc(bMax), !rgbD) + if (rgbDt = malloc(bMax), !rgbD) return SQL_ERROR; rgbL = &blen; - for (;; bMax = blen + 1, rgbD = realloc(rgbD, bMax)) + for (;; bMax = blen + 1, rgbDt = realloc(rgbD, bMax)) { + if (!rgbDt) + return SQL_ERROR; + rgbD = rgbDt; ret = PGAPI_GetDiagField(fHandleType, handle, iRecord, fDiagField, rgbD, bMax, rgbL); if (SQL_SUCCESS_WITH_INFO != ret || blen < bMax) diff --git a/odbcapiw.c b/odbcapiw.c index 8a8b4b1..7bd1ec7 100644 --- a/odbcapiw.c +++ b/odbcapiw.c @@ -141,6 +141,12 @@ SQLDriverConnectW(HDBC hdbc, { obuflen = maxlen + 1; szOut = malloc(obuflen); + if (!szOut) + { + CC_set_error(conn, CONN_NO_MEMORY_ERROR, "Could not allocate memory for output buffer", func); + ret = SQL_ERROR; + goto cleanup; + } pCSO = &olen; } else if (pcbConnStrOut) @@ -169,6 +175,7 @@ inolog("cbConnstrOutMax=%d pcb=%p\n", cbConnStrOutMax, pcbConnStrOut); if (pcbConnStrOut) *pcbConnStrOut = (SQLSMALLINT) outlen; } +cleanup: LEAVE_CONN_CS(conn); if (szOut) free(szOut); @@ -200,8 +207,14 @@ SQLBrowseConnectW(HDBC hdbc, szIn = ucs2_to_utf8(szConnStrIn, cbConnStrIn, &inlen, FALSE); obuflen = cbConnStrOutMax + 1; szOut = malloc(obuflen); - ret = PGAPI_BrowseConnect(hdbc, (SQLCHAR *) szIn, (SQLSMALLINT) inlen, - (SQLCHAR *) szOut, cbConnStrOutMax, &olen); + if (szOut) + ret = PGAPI_BrowseConnect(hdbc, (SQLCHAR *) szIn, (SQLSMALLINT) inlen, + (SQLCHAR *) szOut, cbConnStrOutMax, &olen); + else + { + CC_set_error(conn, CONN_NO_MEMORY_ERROR, "Could not allocate memory for output buffer", func); + ret = SQL_ERROR; + } LEAVE_CONN_CS(conn); if (ret != SQL_ERROR) { @@ -243,7 +256,7 @@ SQLDescribeColW(HSTMT StatementHandle, RETCODE ret; StatementClass *stmt = (StatementClass *) StatementHandle; SQLSMALLINT buflen, nmlen; - char *clName = NULL; + char *clName = NULL, *clNamet = NULL; mylog("[%s]", func); buflen = 0; @@ -252,12 +265,19 @@ SQLDescribeColW(HSTMT StatementHandle, else if (NameLength) buflen = 32; if (buflen > 0) - clName = malloc(buflen); + clNamet = malloc(buflen); ENTER_STMT_CS(stmt); SC_clear_error(stmt); StartRollbackState(stmt); - for (;; buflen = nmlen + 1, clName = realloc(clName, buflen)) + for (;; buflen = nmlen + 1, clNamet = realloc(clName, buflen)) { + if (!clNamet) + { + SC_set_error(stmt, STMT_NO_MEMORY_ERROR, "Could not allocate memory for column name", func); + ret = SQL_ERROR; + break; + } + clName = clNamet; ret = PGAPI_DescribeCol(StatementHandle, ColumnNumber, (SQLCHAR *) clName, buflen, &nmlen, DataType, ColumnSize, @@ -323,7 +343,7 @@ SQLGetCursorNameW(HSTMT StatementHandle, CSTR func = "SQLGetCursorNameW"; RETCODE ret; StatementClass * stmt = (StatementClass *) StatementHandle; - char *crName; + char *crName = NULL, *crNamet; SQLSMALLINT clen, buflen; mylog("[%s]", func); @@ -331,12 +351,19 @@ SQLGetCursorNameW(HSTMT StatementHandle, buflen = BufferLength * 3; else buflen = 32; - crName = malloc(buflen); + crNamet = malloc(buflen); ENTER_STMT_CS(stmt); SC_clear_error(stmt); StartRollbackState(stmt); - for (;; buflen = clen + 1, crName = realloc(crName, buflen)) + for (;; buflen = clen + 1, crNamet = realloc(crName, buflen)) { + if (!crNamet) + { + SC_set_error(stmt, STMT_NO_MEMORY_ERROR, "Could not allocate memory for cursor name", func); + ret = SQL_ERROR; + break; + } + crName = crNamet; ret = PGAPI_GetCursorName(StatementHandle, (SQLCHAR *) crName, buflen, &clen); if (SQL_SUCCESS_WITH_INFO != ret || clen < buflen) break; @@ -693,7 +720,7 @@ SQLNativeSqlW(HDBC hdbc, { CSTR func = "SQLNativeSqlW"; RETCODE ret; - char *szIn, *szOut = NULL; + char *szIn, *szOut = NULL, *szOutt = NULL; SQLLEN slen; SQLINTEGER buflen, olen; ConnectionClass *conn = (ConnectionClass *) hdbc; @@ -706,9 +733,16 @@ SQLNativeSqlW(HDBC hdbc, szIn = ucs2_to_utf8(szSqlStrIn, cbSqlStrIn, &slen, FALSE); buflen = 3 * cbSqlStrMax; if (buflen > 0) - szOut = malloc(buflen); - for (;; buflen = olen + 1, szOut = realloc(szOut, buflen)) + szOutt = malloc(buflen); + for (;; buflen = olen + 1, szOutt = realloc(szOut, buflen)) { + if (!szOutt) + { + CC_set_error(conn, CONN_NO_MEMORY_ERROR, "Could not allocate memory for output buffer", func); + ret = SQL_ERROR; + break; + } + szOut = szOutt; ret = PGAPI_NativeSql(hdbc, (SQLCHAR *) szIn, (SQLINTEGER) slen, (SQLCHAR *) szOut, buflen, &olen); if (SQL_SUCCESS_WITH_INFO != ret || olen < buflen) diff --git a/parse.c b/parse.c index 8fd2571..3b2a5a5 100644 --- a/parse.c +++ b/parse.c @@ -616,6 +616,7 @@ inolog(" multi=%d\n", multi_table); static BOOL ColAttSet(StatementClass *stmt, TABLE_INFO *rti) { + CSTR func = "ColAttSet"; QResultClass *res = SC_get_Curres(stmt); IRDFields *irdflds = SC_get_IRDF(stmt); COL_INFO *col_info = NULL; @@ -663,6 +664,11 @@ mylog("->%d\n", updatable); if (wfi = fi[i], NULL == wfi) { wfi = (FIELD_INFO *) malloc(sizeof(FIELD_INFO)); + if (wfi == NULL) + { + SC_set_error(stmt, STMT_NO_MEMORY_ERROR, "Couldn't allocate memory for field info.", func); + return FALSE; + } fi_reuse = FALSE; fi[i] = wfi; } diff --git a/pgapi30.c b/pgapi30.c index c9942f4..1880802 100644 --- a/pgapi30.c +++ b/pgapi30.c @@ -1951,6 +1951,7 @@ typedef struct static RETCODE bulk_ope_callback(RETCODE retcode, void *para) { + CSTR func = "bulk_ope_callback"; RETCODE ret = retcode; bop_cdata *s = (bop_cdata *) para; SQLULEN offset, global_idx; @@ -2001,6 +2002,11 @@ RETCODE bulk_ope_callback(RETCODE retcode, void *para) if (SQL_NEED_DATA == ret) { bop_cdata *cbdata = (bop_cdata *) malloc(sizeof(bop_cdata)); + if (!cbdata) + { + SC_set_error(s->stmt, STMT_NO_MEMORY_ERROR, "Couldn't allocate memory for cbdata.", func); + return SQL_ERROR; + } memcpy(cbdata, s, sizeof(bop_cdata)); cbdata->need_data_callback = TRUE; if (0 == enqueueNeedDataCallback(s->stmt, bulk_ope_callback, cbdata)) diff --git a/psqlodbc.h b/psqlodbc.h index 8a3bb3f..67ec683 100644 --- a/psqlodbc.h +++ b/psqlodbc.h @@ -400,8 +400,11 @@ do { \ if (str) \ { \ (the_name).name = malloc((n) + 1); \ - memcpy((the_name).name, str, (n)); \ - (the_name).name[(n)] = '\0'; \ + if ((the_name).name) \ + { \ + memcpy((the_name).name, str, (n)); \ + (the_name).name[(n)] = '\0'; \ + } \ } \ else \ (the_name).name = NULL; \ diff --git a/results.c b/results.c index c8676a9..7ec7acd 100644 --- a/results.c +++ b/results.c @@ -1965,6 +1965,11 @@ inolog("AddRollback %d(%u,%u) %s\n", index, keyset->blocknum, keyset->offset, dm res->rb_count = 0; res->rb_alloc = 10; rollback = res->rollback = malloc(sizeof(Rollback) * res->rb_alloc); + if (!rollback) + { + res->rb_alloc = res->rb_count = 0; + return; + } } else { @@ -2027,7 +2032,10 @@ inolog("ReplaceCachedRows %p num_fields=%d num_rows=%d\n", otuple, num_fields, n otuple->value = strdup(ituple->value); inolog("[%d,%d] %s copied\n", i / num_fields, i % num_fields, otuple->value); } - otuple->len = ituple->len; + if (otuple->value) + otuple->len = ituple->len; + else + otuple->len = -1; } return i; } @@ -2881,6 +2889,11 @@ inolog("%s bestitem=%s bestqual=%s\n", func, SAFE_NAME(ti->bestitem), SAFE_NAME( else len += 20; selstr = malloc(len); + if (!selstr) + { + SC_set_error(stmt,STMT_NO_MEMORY_ERROR, "Could not allocate memory for query", func); + goto cleanup; + } if (tidval) { if (latest) @@ -3401,17 +3414,6 @@ QR_get_rowstart_in_cache(res), SC_get_rowset_start(stmt), stmt->options.cursor_t else tuple_size = res->count_backend_allocated * 2; QR_REALLOC_return_with_error(res->backend_tuples, TupleField, res->num_fields * sizeof(TupleField) * tuple_size, res, "SC_pos_newload failed", SQL_ERROR); - /* - res->backend_tuples = (TupleField *) realloc( - res->backend_tuples, - res->num_fields * sizeof(TupleField) * tuple_size); - if (!res->backend_tuples) - { - SC_set_error(stmt, QR_set_rstatus(res, PORES_FATAL_ERROR), "Out of memory while reading tuples.", func); - QR_Destructor(qres); - return SQL_ERROR; - } - */ res->count_backend_allocated = tuple_size; } tuple_old = res->backend_tuples + res->num_fields * num_cached_rows; @@ -3706,6 +3708,11 @@ SC_pos_update(StatementClass *stmt, if (ret == SQL_NEED_DATA) { pup_cdata *cbdata = (pup_cdata *) malloc(sizeof(pup_cdata)); + if (!cbdata) + { + SC_set_error(s.stmt, STMT_NO_MEMORY_ERROR, "Could not allocate memory for cbdata", func); + return SQL_ERROR; + } memcpy(cbdata, &s, sizeof(pup_cdata)); if (0 == enqueueNeedDataCallback(s.stmt, pos_update_callback, cbdata)) ret = SQL_ERROR; @@ -4122,6 +4129,12 @@ SC_pos_add(StatementClass *stmt, if (ret == SQL_NEED_DATA) { padd_cdata *cbdata = (padd_cdata *) malloc(sizeof(padd_cdata)); + if (!cbdata) + { + SC_set_error(s.stmt, STMT_NO_MEMORY_ERROR, "Could not allocate memory for cbdata", func); + ret = SQL_ERROR; + goto cleanup; + } memcpy(cbdata, &s, sizeof(padd_cdata)); if (0 == enqueueNeedDataCallback(s.stmt, pos_add_callback, cbdata)) ret = SQL_ERROR; @@ -4296,6 +4309,11 @@ RETCODE spos_callback(RETCODE retcode, void *para) if (SQL_NEED_DATA == ret) { spos_cdata *cbdata = (spos_cdata *) malloc(sizeof(spos_cdata)); + if (!cbdata) + { + SC_set_error(s->stmt, STMT_NO_MEMORY_ERROR, "Could not allocate memory for cbdata", func); + return SQL_ERROR; + } memcpy(cbdata, s, sizeof(spos_cdata)); cbdata->need_data_callback = TRUE; diff --git a/setup.c b/setup.c index 77b38d3..e70d3be 100644 --- a/setup.c +++ b/setup.c @@ -486,12 +486,18 @@ cleanup: tlen = strlen(emsg); wermsg = (SQLWCHAR *) malloc(sizeof(SQLWCHAR) * (tlen + 1)); - ulen = utf8_to_ucs2_lf(emsg, SQL_NTS, FALSE, wermsg, tlen + 1, TRUE); + if (wermsg) + ulen = utf8_to_ucs2_lf(emsg, SQL_NTS, FALSE, wermsg, tlen + 1, TRUE); + else + ulen = (SQLULEN) -1; if (ulen != (SQLULEN) -1) { allocstr = malloc(4 * tlen + 1); - (void) wstrtomsg(wermsg, (int) tlen, allocstr, (int) (4 * tlen + 1)); - emsg = allocstr; + if (allocstr) + { + (void) wstrtomsg(wermsg, (int) tlen, allocstr, (int) (4 * tlen + 1)); + emsg = allocstr; + } } #endif /* UNICODE_SUPPORT */ diff --git a/statement.c b/statement.c index e86b3cd..fe11dc9 100644 --- a/statement.c +++ b/statement.c @@ -1320,6 +1320,7 @@ SC_create_errorinfo(const StatementClass *self) ermsg = msg; } pgerror = ER_Constructor(self->__error_number, ermsg); + if (!pgerror) return NULL; if (sqlstate) strcpy(pgerror->sqlstate, sqlstate); else if (conn) @@ -1505,7 +1506,7 @@ inolog("SC_full_error_copy %p->%p\n", from ,self); else if (!allres) return; pgerror = SC_create_errorinfo(from); - if (!pgerror->__error_message[0]) + if (!pgerror || !pgerror->__error_message[0]) { ER_Destructor(pgerror); return; @@ -2755,6 +2756,11 @@ ParseAndDescribeWithLibpq(StatementClass *stmt, const char *plan_name, if (!res) res = QR_Constructor(); + if (!res) + { + SC_set_error(stmt, STMT_NO_MEMORY_ERROR, "Couldn't allocate memory for query", func); + return NULL; + } /* * We need to do Prepare + Describe as two different round-trips to the diff --git a/statement.h b/statement.h index 7c4e85d..09dc0e6 100644 --- a/statement.h +++ b/statement.h @@ -370,6 +370,17 @@ do { \ } \ t = tmp; \ } while (0) +#define SC_REALLOC_gexit_with_error(t, tp, s, a, m, r) \ +do { \ + tp *tmp; \ + if (tmp = (tp *) realloc(t, s), NULL == tmp) \ + { \ + SC_set_error(a, STMT_NO_MEMORY_ERROR, m, __FUNCTION__); \ + r; \ + goto cleanup; \ + } \ + t = tmp; \ +} while (0) /* options for SC_free_params() */ #define STMT_FREE_PARAMS_ALL 0 diff --git a/tuple.c b/tuple.c index 90cefdb..7c2f53f 100644 --- a/tuple.c +++ b/tuple.c @@ -37,10 +37,9 @@ set_tuplefield_string(TupleField *tuple_field, const char *string) if (string) { tuple_field->len = (Int4) strlen(string); /* PG restriction */ - tuple_field->value = malloc(strlen(string) + 1); - strcpy(tuple_field->value, string); + tuple_field->value = strdup(string); } - else + if (!tuple_field->value) set_tuplefield_null(tuple_field); } -- 2.39.5