diff -Naur a/connection.c b/connection.c --- a/connection.c 2016-01-10 22:25:14.000000000 +0900 +++ b/connection.c 2016-01-28 13:26:24.000000000 +0900 @@ -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 @@ self->__error_message = NULL; } self->sqlstate[0] = '\0'; - self->errormsg_created = FALSE; CONNLOCK_RELEASE(self); } @@ -1218,30 +1216,6 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 -Naur a/connection.h b/connection.h --- a/connection.h 2016-01-10 22:25:14.000000000 +0900 +++ b/connection.h 2016-01-27 09:46:51.000000000 +0900 @@ -354,8 +354,6 @@ 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 -Naur a/convert.c b/convert.c --- a/convert.c 2016-01-10 22:25:14.000000000 +0900 +++ b/convert.c 2016-01-27 15:39:09.000000000 +0900 @@ -3046,6 +3046,11 @@ } 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 @@ 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 -Naur a/descriptor.c b/descriptor.c --- a/descriptor.c 2016-01-10 22:25:14.000000000 +0900 +++ b/descriptor.c 2016-01-27 14:41:51.000000000 +0900 @@ -352,7 +352,8 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 -Naur a/dlg_specific.c b/dlg_specific.c --- a/dlg_specific.c 2016-01-10 22:25:14.000000000 +0900 +++ b/dlg_specific.c 2016-01-27 17:04:31.000000000 +0900 @@ -1544,6 +1544,8 @@ return out; } outs = (char *) malloc(ilen + 1); + if (!outs) + return out; for (i = 0; i < ilen; i++) { inc = in[i]; @@ -1687,6 +1689,8 @@ 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 -Naur a/drvconn.c b/drvconn.c --- a/drvconn.c 2016-01-10 22:25:14.000000000 +0900 +++ b/drvconn.c 2016-01-27 11:08:18.000000000 +0900 @@ -47,6 +47,7 @@ if (!str) return NULL; outstr = strdup(str); + if (!outstr) return NULL; if (pwdp = strstr(outstr, "PWD="), !pwdp) pwdp = strstr(outstr, "pwd="); if (pwdp) diff -Naur a/environ.c b/environ.c --- a/environ.c 2016-01-10 22:25:14.000000000 +0900 +++ b/environ.c 2016-01-28 10:31:35.000000000 +0900 @@ -174,7 +174,8 @@ 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 -Naur a/info.c b/info.c --- a/info.c 2016-01-10 22:25:14.000000000 +0900 +++ b/info.c 2016-01-28 13:26:24.000000000 +0900 @@ -1518,6 +1518,7 @@ 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 @@ 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 @@ { 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 @@ 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); @@ -3180,9 +3194,21 @@ column_names = (struct columns_idx *) realloc(column_names, alcount * sizeof(struct columns_idx)); + if (!column_names) + { + SC_set_error(stmt, STMT_NO_MEMORY_ERROR, "Couldn't allocate memory for column names.", func); + result = SQL_ERROR; + goto cleanup; + } } 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 +4034,14 @@ { 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 +5456,11 @@ 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 +5548,12 @@ } 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 -Naur a/misc.c b/misc.c --- a/misc.c 2016-01-10 22:25:14.000000000 +0900 +++ b/misc.c 2016-01-27 12:14:28.000000000 +0900 @@ -182,6 +182,7 @@ if (!str) { str = malloc(length + 1); + if (!str) return NULL; memcpy(str, s, length); str[length] = '\0'; } diff -Naur a/multibyte.c b/multibyte.c --- a/multibyte.c 2016-01-10 22:25:14.000000000 +0900 +++ b/multibyte.c 2016-01-27 14:50:39.000000000 +0900 @@ -189,6 +189,8 @@ 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 -Naur a/odbcapi30w.c b/odbcapi30w.c --- a/odbcapi30w.c 2016-01-10 22:25:14.000000000 +0900 +++ b/odbcapi30w.c 2016-01-27 16:08:06.000000000 +0900 @@ -179,6 +179,11 @@ pcbV = &blen; for (;; bMax = blen + 1, rgbV = realloc(rgbV, bMax)) { + if (!rgbV) + { + ret = SQL_ERROR; + break; + } ret = PGAPI_GetDescField(hdesc, iRecord, iField, rgbV, bMax, pcbV); if (SQL_SUCCESS_WITH_INFO != ret || blen < bMax) break; @@ -304,6 +309,11 @@ rgbL = &blen; for (;; bMax = blen + 1, rgbD = realloc(rgbD, bMax)) { + if (!rgbD) + { + ret = SQL_ERROR; + break; + } ret = PGAPI_ColAttributes(hstmt, iCol, iField, rgbD, bMax, rgbL, pNumAttr); if (SQL_SUCCESS_WITH_INFO != ret || blen < bMax) @@ -368,6 +378,8 @@ rgbL = &blen; for (;; bMax = blen + 1, rgbD = realloc(rgbD, bMax)) { + if (!rgbD) + return SQL_ERROR; ret = PGAPI_GetDiagField(fHandleType, handle, iRecord, fDiagField, rgbD, bMax, rgbL); if (SQL_SUCCESS_WITH_INFO != ret || blen < bMax) diff -Naur a/odbcapiw.c b/odbcapiw.c --- a/odbcapiw.c 2016-01-10 22:25:14.000000000 +0900 +++ b/odbcapiw.c 2016-01-28 13:26:24.000000000 +0900 @@ -141,6 +141,12 @@ { 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 @@ if (pcbConnStrOut) *pcbConnStrOut = (SQLSMALLINT) outlen; } +cleanup: LEAVE_CONN_CS(conn); if (szOut) free(szOut); @@ -200,8 +207,14 @@ 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) { @@ -258,6 +271,12 @@ StartRollbackState(stmt); for (;; buflen = nmlen + 1, clName = realloc(clName, buflen)) { + if (!clName) + { + SC_set_error(stmt, STMT_NO_MEMORY_ERROR, "Could not allocate memory for column name", func); + ret = SQL_ERROR; + break; + } ret = PGAPI_DescribeCol(StatementHandle, ColumnNumber, (SQLCHAR *) clName, buflen, &nmlen, DataType, ColumnSize, @@ -337,6 +356,12 @@ StartRollbackState(stmt); for (;; buflen = clen + 1, crName = realloc(crName, buflen)) { + if (!crName) + { + SC_set_error(stmt, STMT_NO_MEMORY_ERROR, "Could not allocate memory for cursor name", func); + ret = SQL_ERROR; + break; + } ret = PGAPI_GetCursorName(StatementHandle, (SQLCHAR *) crName, buflen, &clen); if (SQL_SUCCESS_WITH_INFO != ret || clen < buflen) break; @@ -709,6 +734,12 @@ szOut = malloc(buflen); for (;; buflen = olen + 1, szOut = realloc(szOut, buflen)) { + if (!szOut) + { + CC_set_error(conn, CONN_NO_MEMORY_ERROR, "Could not allocate memory for output buffer", func); + ret = SQL_ERROR; + break; + } ret = PGAPI_NativeSql(hdbc, (SQLCHAR *) szIn, (SQLINTEGER) slen, (SQLCHAR *) szOut, buflen, &olen); if (SQL_SUCCESS_WITH_INFO != ret || olen < buflen) diff -Naur a/parse.c b/parse.c --- a/parse.c 2016-01-10 22:25:14.000000000 +0900 +++ b/parse.c 2016-01-28 11:32:59.000000000 +0900 @@ -616,6 +616,7 @@ 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 @@ 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 -Naur a/pgapi30.c b/pgapi30.c --- a/pgapi30.c 2016-01-10 22:25:14.000000000 +0900 +++ b/pgapi30.c 2016-01-28 11:43:45.000000000 +0900 @@ -1951,6 +1951,7 @@ 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 @@ 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 -Naur a/psqlodbc.h b/psqlodbc.h --- a/psqlodbc.h 2016-01-10 22:25:14.000000000 +0900 +++ b/psqlodbc.h 2016-01-27 09:33:28.000000000 +0900 @@ -400,8 +400,11 @@ 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 -Naur a/results.c b/results.c --- a/results.c 2016-01-10 22:25:14.000000000 +0900 +++ b/results.c 2016-01-28 10:55:57.000000000 +0900 @@ -1965,6 +1965,11 @@ 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 @@ 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 @@ 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) @@ -3706,6 +3719,11 @@ 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 +4140,12 @@ 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 +4320,11 @@ 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 -Naur a/setup.c b/setup.c --- a/setup.c 2016-01-10 22:25:14.000000000 +0900 +++ b/setup.c 2016-01-27 12:02:24.000000000 +0900 @@ -486,12 +486,18 @@ 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 -Naur a/statement.c b/statement.c --- a/statement.c 2016-01-10 22:25:14.000000000 +0900 +++ b/statement.c 2016-01-28 12:01:08.000000000 +0900 @@ -1320,6 +1320,7 @@ 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 @@ 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 @@ 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 -Naur a/tuple.c b/tuple.c --- a/tuple.c 2016-01-10 22:25:15.000000000 +0900 +++ b/tuple.c 2016-01-27 15:47:13.000000000 +0900 @@ -37,10 +37,9 @@ 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); }