@@ -700,23 +700,19 @@ static void _python_ibm_db_check_sql_errors(SQLHANDLE handle, SQLSMALLINT hType,
700700 snprintf(messageStr, sizeof(messageStr), "handle=%p, hType=%d, rc=%d, cpy_to_global=%d, API=%d, recno=%d",
701701 handle, hType, rc, cpy_to_global, API, recno);
702702 LogMsg(DEBUG, messageStr);
703-
704- memset(errMsg, '\0', DB2_MAX_ERR_MSG_LEN);
705- memset(msg, '\0', SQL_MAX_MESSAGE_LENGTH + 1);
706703 rc1 = SQLGetDiagRec(hType, handle, recno, sqlstate, &sqlcode, msg,
707704 SQL_MAX_MESSAGE_LENGTH + 1, &length);
708- snprintf(messageStr, sizeof(messageStr), "SQLGetDiagRec returned rc1=%d, sqlstate=%s, sqlcode=%d, msg=%s, length=%d",
709- rc1, sqlstate, sqlcode, msg, length);
705+ snprintf(messageStr, sizeof(messageStr), "SQLGetDiagRec returned rc1=%d, sqlstate=%s, sqlcode=%d, length=%d",
706+ rc1, sqlstate, sqlcode, length);
710707 sprintf((char *)errcode, "SQLCODE=%d", (int)sqlcode);
711708 LogMsg(DEBUG, messageStr);
712-
713709 if (rc1 == SQL_SUCCESS)
714710 {
715711 while ((p = strchr((char *)msg, '\n')))
716712 {
717713 *p = '\0';
718714 }
719- sprintf ((char *)errMsg, "%s SQLCODE=%d", (char *)msg, (int)sqlcode);
715+ snprintf ((char *)errMsg, DB2_MAX_ERR_MSG_LEN , "%s SQLCODE=%d", (char *)msg, (int)sqlcode);
720716#ifdef _WIN32
721717 for (i = 0; i < strlen(errMsg); i++)
722718 {
@@ -727,7 +723,8 @@ static void _python_ibm_db_check_sql_errors(SQLHANDLE handle, SQLSMALLINT hType,
727723 }
728724#endif
729725
730- LogMsg(ERROR, errMsg);
726+ snprintf(messageStr, sizeof(messageStr), "Final error message (UTF-8): %s", errMsg);
727+ LogMsg(ERROR, messageStr);
731728 if (cpy_to_global != 0 && rc != 1)
732729 {
733730 PyErr_SetString(PyExc_Exception, (char *)errMsg);
@@ -747,25 +744,30 @@ static void _python_ibm_db_check_sql_errors(SQLHANDLE handle, SQLSMALLINT hType,
747744 "Copying to global: SQL_HANDLE_DBC, sqlstate=%s, errMsg=%s",
748745 sqlstate, errMsg);
749746 LogMsg(DEBUG, messageStr);
750- strncpy(IBM_DB_G(__python_conn_err_state),
751- (char *)sqlstate, SQL_SQLSTATE_SIZE + 1);
752- strncpy(IBM_DB_G(__python_conn_err_msg),
753- (char *)errMsg, DB2_MAX_ERR_MSG_LEN);
754- strncpy(IBM_DB_G(__python_err_code),
755- (char *)errcode, SQL_SQLCODE_SIZE);
747+ strncpy(IBM_DB_G(__python_conn_err_state), (char *)sqlstate, SQL_SQLSTATE_SIZE);
748+ IBM_DB_G(__python_conn_err_state)[SQL_SQLSTATE_SIZE] = '\0';
749+
750+ strncpy(IBM_DB_G(__python_conn_err_msg), (char *)errMsg, DB2_MAX_ERR_MSG_LEN - 1);
751+ IBM_DB_G(__python_conn_err_msg)[DB2_MAX_ERR_MSG_LEN - 1] = '\0';
752+
753+ strncpy(IBM_DB_G(__python_err_code), (char *)errcode, SQL_SQLCODE_SIZE - 1);
754+ IBM_DB_G(__python_err_code)[SQL_SQLCODE_SIZE - 1] = '\0';
755+
756756 break;
757757
758758 case SQL_HANDLE_STMT:
759759 snprintf(messageStr, sizeof(messageStr),
760760 "Copying to global: SQL_HANDLE_STMT, sqlstate=%s, errMsg=%s",
761761 sqlstate, errMsg);
762762 LogMsg(DEBUG, messageStr);
763- strncpy(IBM_DB_G(__python_stmt_err_state),
764- (char *)sqlstate, SQL_SQLSTATE_SIZE + 1);
765- strncpy(IBM_DB_G(__python_stmt_err_msg),
766- (char *)errMsg, DB2_MAX_ERR_MSG_LEN);
767- strncpy(IBM_DB_G(__python_err_code),
768- (char *)errcode, SQL_SQLCODE_SIZE);
763+ strncpy(IBM_DB_G(__python_stmt_err_state), (char *)sqlstate, SQL_SQLSTATE_SIZE);
764+ IBM_DB_G(__python_stmt_err_state)[SQL_SQLSTATE_SIZE] = '\0';
765+
766+ strncpy(IBM_DB_G(__python_stmt_err_msg), (char *)errMsg, DB2_MAX_ERR_MSG_LEN - 1);
767+ IBM_DB_G(__python_stmt_err_msg)[DB2_MAX_ERR_MSG_LEN - 1] = '\0';
768+
769+ strncpy(IBM_DB_G(__python_err_code), (char *)errcode, SQL_SQLCODE_SIZE - 1);
770+ IBM_DB_G(__python_err_code)[SQL_SQLCODE_SIZE - 1] = '\0';
769771
770772 break;
771773 }
@@ -779,15 +781,17 @@ static void _python_ibm_db_check_sql_errors(SQLHANDLE handle, SQLSMALLINT hType,
779781 {
780782 snprintf(messageStr, sizeof(messageStr), "Returning SQLSTATE for DB2_ERR: %s", sqlstate);
781783 LogMsg(DEBUG, messageStr);
782- strncpy(ret_str, (char *)sqlstate, SQL_SQLSTATE_SIZE + 1);
784+ strncpy(ret_str, (char *)sqlstate, SQL_SQLSTATE_SIZE);
785+ ret_str[SQL_SQLSTATE_SIZE] = '\0';
783786 }
784787 return;
785788 case DB2_ERRMSG:
786789 if (ret_str != NULL)
787790 {
788791 snprintf(messageStr, sizeof(messageStr), "Returning error message for DB2_ERRMSG: %s", errMsg);
789792 LogMsg(DEBUG, messageStr);
790- strncpy(ret_str, (char *)errMsg, DB2_MAX_ERR_MSG_LEN);
793+ strncpy(ret_str, (char *)errMsg, DB2_MAX_ERR_MSG_LEN - 1);
794+ ret_str[DB2_MAX_ERR_MSG_LEN - 1] = '\0';
791795 }
792796 return;
793797 default:
@@ -806,21 +810,23 @@ static void _python_ibm_db_check_sql_errors(SQLHANDLE handle, SQLSMALLINT hType,
806810 "Copying warning to global: SQL_HANDLE_DBC, sqlstate=%s, errMsg=%s",
807811 sqlstate, errMsg);
808812 LogMsg(DEBUG, messageStr);
809- strncpy(IBM_DB_G(__python_conn_warn_state),
810- (char *)sqlstate, SQL_SQLSTATE_SIZE + 1);
811- strncpy(IBM_DB_G(__python_conn_warn_msg),
812- (char *)errMsg, DB2_MAX_ERR_MSG_LEN);
813+ strncpy(IBM_DB_G(__python_conn_warn_state), (char *)sqlstate, SQL_SQLSTATE_SIZE);
814+ IBM_DB_G(__python_conn_warn_state)[SQL_SQLSTATE_SIZE] = '\0';
815+
816+ strncpy(IBM_DB_G(__python_conn_warn_msg), (char *)errMsg, DB2_MAX_ERR_MSG_LEN - 1);
817+ IBM_DB_G(__python_conn_warn_msg)[DB2_MAX_ERR_MSG_LEN - 1] = '\0';
813818 break;
814819
815820 case SQL_HANDLE_STMT:
816821 snprintf(messageStr, sizeof(messageStr),
817822 "Copying warning to global: SQL_HANDLE_STMT, sqlstate=%s, errMsg=%s",
818823 sqlstate, errMsg);
819824 LogMsg(DEBUG, messageStr);
820- strncpy(IBM_DB_G(__python_stmt_warn_state),
821- (char *)sqlstate, SQL_SQLSTATE_SIZE + 1);
822- strncpy(IBM_DB_G(__python_stmt_warn_msg),
823- (char *)errMsg, DB2_MAX_ERR_MSG_LEN);
825+ strncpy(IBM_DB_G(__python_stmt_warn_state), (char *)sqlstate, SQL_SQLSTATE_SIZE);
826+ IBM_DB_G(__python_stmt_warn_state)[SQL_SQLSTATE_SIZE] = '\0';
827+
828+ strncpy(IBM_DB_G(__python_stmt_warn_msg), (char *)errMsg, DB2_MAX_ERR_MSG_LEN - 1);
829+ IBM_DB_G(__python_stmt_warn_msg)[DB2_MAX_ERR_MSG_LEN - 1] = '\0';
824830 break;
825831 }
826832 }
@@ -830,7 +836,8 @@ static void _python_ibm_db_check_sql_errors(SQLHANDLE handle, SQLSMALLINT hType,
830836 {
831837 snprintf(messageStr, sizeof(messageStr), "Returning warning message for DB2_WARNMSG: %s", errMsg);
832838 LogMsg(DEBUG, messageStr);
833- strncpy(ret_str, (char *)errMsg, DB2_MAX_ERR_MSG_LEN);
839+ strncpy(ret_str, (char *)errMsg, DB2_MAX_ERR_MSG_LEN - 1);
840+ ret_str[DB2_MAX_ERR_MSG_LEN - 1] = '\0';
834841 }
835842 return;
836843 default:
@@ -9928,11 +9935,20 @@ static PyObject *ibm_db_conn_errormsg(PyObject *self, PyObject *args)
99289935 }
99299936 else
99309937 {
9931- PyObject *defaultErrorMsg = StringOBJ_FromASCII(IBM_DB_G(__python_conn_err_msg));
9932- snprintf(messageStr, sizeof(messageStr), "No connection object provided. Returning default error message: %s", PyUnicode_AsUTF8(defaultErrorMsg));
9938+ PyObject *defaultErrorMsg = PyUnicode_DecodeUTF8(
9939+ (const char *)IBM_DB_G(__python_conn_err_msg),
9940+ strlen((const char *)IBM_DB_G(__python_conn_err_msg)),
9941+ "replace"
9942+ );
9943+ snprintf(messageStr, sizeof(messageStr), "No statement object provided. Returning default error message: %s", PyUnicode_AsUTF8(defaultErrorMsg));
9944+ Py_DECREF(defaultErrorMsg);
99339945 LogMsg(INFO, messageStr);
99349946 LogMsg(INFO, "exit conn_errormsg()");
9935- return StringOBJ_FromASCII(IBM_DB_G(__python_conn_err_msg));
9947+ return PyUnicode_DecodeUTF8(
9948+ (const char *)IBM_DB_G(__python_conn_err_msg),
9949+ strlen((const char *)IBM_DB_G(__python_conn_err_msg)),
9950+ "replace"
9951+ );
99369952 }
99379953}
99389954/*!# ibm_db_conn_warn
@@ -10226,11 +10242,20 @@ static PyObject *ibm_db_stmt_errormsg(PyObject *self, PyObject *args)
1022610242 }
1022710243 else
1022810244 {
10229- PyObject *defaultErrorMsg = StringOBJ_FromASCII(IBM_DB_G(__python_stmt_err_msg));
10245+ PyObject *defaultErrorMsg = PyUnicode_DecodeUTF8(
10246+ (const char *)IBM_DB_G(__python_stmt_err_msg),
10247+ strlen((const char *)IBM_DB_G(__python_stmt_err_msg)),
10248+ "replace"
10249+ );
1023010250 snprintf(messageStr, sizeof(messageStr), "No statement object provided. Returning default error message: %s", PyUnicode_AsUTF8(defaultErrorMsg));
10251+ Py_DECREF(defaultErrorMsg);
1023110252 LogMsg(INFO, messageStr);
1023210253 LogMsg(INFO, "exit stmt_errormsg()");
10233- return StringOBJ_FromStr(IBM_DB_G(__python_stmt_err_msg));
10254+ return PyUnicode_DecodeUTF8(
10255+ (const char *)IBM_DB_G(__python_stmt_err_msg),
10256+ strlen((const char *)IBM_DB_G(__python_stmt_err_msg)),
10257+ "replace"
10258+ );
1023410259 }
1023510260}
1023610261
0 commit comments