Skip to content

Commit c7922bb

Browse files
committed
Fix garbled diagnostic record on failed SQLDriverConnect
Every catch block that handled std::exception followed the same broken pattern: catch ( std::exception &ex ) { SQLException &exception = (SQLException&)ex; // virtual calls on `exception`... } The C-style cast is a reinterpret_cast. When the caught object was not in fact a SQLException -- e.g. a std::bad_alloc, a raw FbException that bypassed the IscDbc rewrap, or anything else that propagated out of the IscDbc layer -- the subsequent virtual dispatch through `exception` read through whatever bytes lay where SQLException's vtable pointer would have been. On Linux that produced a diagnostic record with an empty SQLSTATE, a non-deterministic native code, and a one-byte message ('[') whose reported length disagreed with its strlen. This commit introduces a type-safe ExceptionInfo helper and a postError(state, std::exception&) overload that route every catch through dynamic_cast, falling back to std::exception::what() when the caught object is not a SQLException. All 64 occurrences of the broken pattern across OdbcConnection / OdbcStatement / OdbcDesc / OdbcEnv and the Windows OdbcJdbcSetup tree are converted to the safe path. The catch block in OdbcConnection::connect also gains a NULL guard around connection->close(): if createConnection() throws before the assignment, the previous code dereferenced a NULL pointer during cleanup.
1 parent 3f822ce commit c7922bb

15 files changed

Lines changed: 131 additions & 144 deletions

IscDbc/SQLException.h

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,26 @@ class DllExport SQLException : public std::exception
4848
virtual const char *getTrace() = 0;
4949
};
5050

51+
// Type-safe extraction of error information from any std::exception caught
52+
// across an SQLException-aware boundary. Returns the SQLException's codes and
53+
// text if the caught exception really is one; otherwise sqlcode/fbcode are 0
54+
// and text comes from std::exception::what(). Replaces unchecked C-style
55+
// reinterpret-casts (`SQLException &e = (SQLException&)ex;`) which produced
56+
// garbled diagnostic records when a non-SQLException reached the catch block.
57+
struct ExceptionInfo
58+
{
59+
int sqlcode;
60+
int fbcode;
61+
const char *text;
62+
};
63+
64+
inline ExceptionInfo extractExceptionInfo(std::exception &ex)
65+
{
66+
if (SQLException *sqlEx = dynamic_cast<SQLException*>(&ex))
67+
return { sqlEx->getSqlcode(), sqlEx->getFbcode(), sqlEx->getText() };
68+
return { 0, 0, ex.what() };
69+
}
70+
5171
}; // end namespace IscDbcLibrary
5272

5373
#endif

OdbcConnection.cpp

Lines changed: 15 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1028,8 +1028,7 @@ SQLRETURN OdbcConnection::sqlNativeSql( SQLCHAR * inStatementText, SQLINTEGER te
10281028
}
10291029
catch ( std::exception &ex )
10301030
{
1031-
SQLException &exception = (SQLException&)ex;
1032-
postError( "HY000", exception );
1031+
postError( "HY000", ex );
10331032
return SQL_ERROR;
10341033
}
10351034

@@ -1134,8 +1133,7 @@ SQLRETURN OdbcConnection::sqlDisconnect()
11341133
}
11351134
catch ( std::exception &ex )
11361135
{
1137-
SQLException &exception = (SQLException&)ex;
1138-
postError ("01002", exception);
1136+
postError ("01002", ex);
11391137
connection = NULL;
11401138
connected = false;
11411139
return SQL_SUCCESS_WITH_INFO;
@@ -1711,17 +1709,21 @@ SQLRETURN OdbcConnection::connect(const char *sharedLibrary, const char * databa
17111709
}
17121710
catch ( std::exception &ex )
17131711
{
1714-
SQLException &exception = (SQLException&)ex;
1712+
ExceptionInfo info = extractExceptionInfo(ex);
1713+
17151714
if ( env->envShare )
17161715
env->envShare = NULL;
17171716

17181717
if ( properties )
17191718
properties->release();
17201719

1721-
connection->close();
1722-
connection = NULL;
1720+
if ( connection )
1721+
{
1722+
connection->close();
1723+
connection = NULL;
1724+
}
17231725

1724-
return sqlReturn( SQL_ERROR, "08004", exception.getText(), exception.getSqlcode() );
1726+
return sqlReturn( SQL_ERROR, "08004", info.text, info.sqlcode );
17251727
}
17261728

17271729
connected = true;
@@ -1748,8 +1750,7 @@ SQLRETURN OdbcConnection::sqlEndTran(int operation)
17481750
}
17491751
catch ( std::exception &ex )
17501752
{
1751-
SQLException &exception = (SQLException&)ex;
1752-
postError ("S1000", exception);
1753+
postError ("S1000", ex);
17531754
return SQL_ERROR;
17541755
}
17551756

@@ -1766,8 +1767,7 @@ SQLRETURN OdbcConnection::sqlExecuteCreateDatabase(const char * sqlString)
17661767
}
17671768
catch ( std::exception &ex )
17681769
{
1769-
SQLException &exception = (SQLException&)ex;
1770-
postError( "HY000", exception );
1770+
postError( "HY000", ex );
17711771
return SQL_ERROR;
17721772
}
17731773

@@ -2180,8 +2180,7 @@ void OdbcConnection::initUserEvents( PODBC_EVENTS_BLOCK_INFO infoEvents )
21802180
}
21812181
catch ( std::exception &ex )
21822182
{
2183-
SQLException &exception = (SQLException&)ex;
2184-
postError( "HY000", exception );
2183+
postError( "HY000", ex );
21852184
}
21862185
}
21872186

@@ -2201,8 +2200,7 @@ void OdbcConnection::updateResultEvents( char *updated )
22012200
}
22022201
catch ( std::exception &ex )
22032202
{
2204-
SQLException &exception = (SQLException&)ex;
2205-
postError( "HY000", exception );
2203+
postError( "HY000", ex );
22062204
}
22072205
}
22082206

@@ -2214,8 +2212,7 @@ void OdbcConnection::requeueEvents()
22142212
}
22152213
catch ( std::exception &ex )
22162214
{
2217-
SQLException &exception = (SQLException&)ex;
2218-
postError( "HY000", exception );
2215+
postError( "HY000", ex );
22192216
}
22202217
}
22212218

OdbcDesc.cpp

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -807,8 +807,7 @@ SQLRETURN OdbcDesc::sqlGetDescField(int recNumber, int fieldId, SQLPOINTER ptr,
807807
}
808808
catch ( std::exception &ex )
809809
{
810-
SQLException &exception = (SQLException&)ex;
811-
postError ("HY000", exception);
810+
postError ("HY000", ex);
812811
return SQL_ERROR;
813812
}
814813

@@ -1218,8 +1217,7 @@ SQLRETURN OdbcDesc::sqlGetDescRec( SQLSMALLINT recNumber,
12181217
}
12191218
catch ( std::exception &ex )
12201219
{
1221-
SQLException &exception = (SQLException&)ex;
1222-
postError ("HY000", exception);
1220+
postError ("HY000", ex);
12231221
return SQL_ERROR;
12241222
}
12251223

@@ -1266,8 +1264,7 @@ SQLRETURN OdbcDesc::sqlSetDescRec( SQLSMALLINT recNumber,
12661264
}
12671265
catch ( std::exception &ex )
12681266
{
1269-
SQLException &exception = (SQLException&)ex;
1270-
postError ("HY000", exception);
1267+
postError ("HY000", ex);
12711268
return SQL_ERROR;
12721269
}
12731270

OdbcEnv.cpp

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -134,8 +134,7 @@ SQLRETURN OdbcEnv::sqlEndTran(int operation)
134134
}
135135
catch ( std::exception &ex )
136136
{
137-
SQLException &exception = (SQLException&)ex;
138-
postError ("HY000", exception);
137+
postError ("HY000", ex);
139138
return SQL_ERROR;
140139
}
141140

@@ -194,8 +193,7 @@ SQLRETURN OdbcEnv::sqlGetEnvAttr(int attribute, SQLPOINTER ptr, int bufferLength
194193
}
195194
catch ( std::exception &ex )
196195
{
197-
SQLException &exception = (SQLException&)ex;
198-
postError ("HY000", exception);
196+
postError ("HY000", ex);
199197
return SQL_ERROR;
200198
}
201199

@@ -224,8 +222,7 @@ SQLRETURN OdbcEnv::sqlSetEnvAttr(int attribute, SQLPOINTER value, int length)
224222
}
225223
catch ( std::exception &ex )
226224
{
227-
SQLException &exception = (SQLException&)ex;
228-
postError ("HY000", exception);
225+
postError ("HY000", ex);
229226
return SQL_ERROR;
230227
}
231228

OdbcJdbcSetup/DsnDialog.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -791,9 +791,9 @@ void CDsnDialog::OnTestConnection( HWND hDlg )
791791
}
792792
catch ( std::exception &ex )
793793
{
794-
SQLException &exception = (SQLException&)ex;
794+
ExceptionInfo info = extractExceptionInfo(ex);
795795
char buffer[2048];
796-
JString text = exception.getText();
796+
JString text = info.text;
797797

798798
sprintf( buffer, "%s\n%s", _TR( IDS_MESSAGE_02, "Connection failed!" ), (const char*)text );
799799
removeNameFileDBfromMessage ( buffer );

OdbcJdbcSetup/ServiceClient.cpp

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -86,8 +86,8 @@ bool CServiceClient::initServices( const char *sharedLibrary )
8686
}
8787
catch ( std::exception &ex )
8888
{
89-
SQLException &exception = (SQLException&)ex;
90-
JString text = exception.getText();
89+
ExceptionInfo info = extractExceptionInfo(ex);
90+
JString text = info.text;
9191

9292
if ( services )
9393
{
@@ -145,8 +145,8 @@ bool CServiceClient::createDatabase()
145145
}
146146
catch ( std::exception &ex )
147147
{
148-
SQLException &exception = (SQLException&)ex;
149-
JString text = exception.getText();
148+
ExceptionInfo info = extractExceptionInfo(ex);
149+
JString text = info.text;
150150

151151
if ( connection )
152152
connection->close();
@@ -189,8 +189,8 @@ bool CServiceClient::dropDatabase()
189189
}
190190
catch ( std::exception &ex )
191191
{
192-
SQLException &exception = (SQLException&)ex;
193-
JString text = exception.getText();
192+
ExceptionInfo info = extractExceptionInfo(ex);
193+
JString text = info.text;
194194

195195
if ( connection )
196196
connection->close();

OdbcJdbcSetup/ServiceTabBackup.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -236,14 +236,14 @@ void CServiceTabBackup::onStartBackup()
236236
}
237237
catch ( std::exception &ex )
238238
{
239+
ExceptionInfo info = extractExceptionInfo(ex);
239240
writeFooterToLogFile();
240241
EnableWindow( GetDlgItem( hDlg, IDOK ), TRUE );
241242
EnableWindow( GetDlgItem( hDlg, IDC_BUTTON_VIEW_LOG ), !logPathFile.IsEmpty() );
242243

243244
char buffer[1024];
244-
SQLException &exception = (SQLException&)ex;
245-
JString text = exception.getText();
246-
sprintf(buffer, "sqlcode %d, fbcode %d - %s", exception.getSqlcode(), exception.getFbcode(), (const char*)text );
245+
JString text = info.text;
246+
sprintf(buffer, "sqlcode %d, fbcode %d - %s", info.sqlcode, info.fbcode, (const char*)text );
247247
MessageBox( NULL, buffer, TEXT( "Error!" ), MB_ICONERROR | MB_OK );
248248
}
249249

OdbcJdbcSetup/ServiceTabRepair.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -303,14 +303,14 @@ void CServiceTabRepair::startRepairDatabase()
303303
}
304304
catch ( std::exception &ex )
305305
{
306+
ExceptionInfo info = extractExceptionInfo(ex);
306307
writeFooterToLogFile();
307308
EnableWindow( GetDlgItem( hDlg, IDOK ), TRUE );
308309
EnableWindow( GetDlgItem( hDlg, IDC_BUTTON_VIEW_LOG ), !logPathFile.IsEmpty() );
309310

310311
char buffer[1024];
311-
SQLException &exception = (SQLException&)ex;
312-
JString text = exception.getText();
313-
sprintf(buffer, "sqlcode %d, fbcode %d - %s", exception.getSqlcode(), exception.getFbcode(), (const char*)text );
312+
JString text = info.text;
313+
sprintf(buffer, "sqlcode %d, fbcode %d - %s", info.sqlcode, info.fbcode, (const char*)text );
314314
MessageBox( NULL, buffer, TEXT( "Error!" ), MB_ICONERROR | MB_OK );
315315
}
316316

OdbcJdbcSetup/ServiceTabRestore.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -265,14 +265,14 @@ void CServiceTabRestore::onStartRestore()
265265
}
266266
catch ( std::exception &ex )
267267
{
268+
ExceptionInfo info = extractExceptionInfo(ex);
268269
writeFooterToLogFile();
269270
EnableWindow( GetDlgItem( hDlg, IDOK ), TRUE );
270271
EnableWindow( GetDlgItem( hDlg, IDC_BUTTON_VIEW_LOG ), !logPathFile.IsEmpty() );
271272

272273
char buffer[1024];
273-
SQLException &exception = (SQLException&)ex;
274-
JString text = exception.getText();
275-
sprintf(buffer, "sqlcode %d, fbcode %d - %s", exception.getSqlcode(), exception.getFbcode(), (const char*)text );
274+
JString text = info.text;
275+
sprintf(buffer, "sqlcode %d, fbcode %d - %s", info.sqlcode, info.fbcode, (const char*)text );
276276
MessageBox( NULL, buffer, TEXT( "Error!" ), MB_ICONERROR | MB_OK );
277277
}
278278

OdbcJdbcSetup/ServiceTabStatistics.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -221,14 +221,14 @@ void CServiceTabStatistics::onStartStatistics()
221221
}
222222
catch ( std::exception &ex )
223223
{
224+
ExceptionInfo info = extractExceptionInfo(ex);
224225
writeFooterToLogFile();
225226
EnableWindow( GetDlgItem( hDlg, IDOK ), TRUE );
226227
EnableWindow( GetDlgItem( hDlg, IDC_BUTTON_VIEW_LOG ), !logPathFile.IsEmpty() );
227228

228229
char buffer[1024];
229-
SQLException &exception = (SQLException&)ex;
230-
JString text = exception.getText();
231-
sprintf(buffer, "sqlcode %d, fbcode %d - %s", exception.getSqlcode(), exception.getFbcode(), (const char*)text );
230+
JString text = info.text;
231+
sprintf(buffer, "sqlcode %d, fbcode %d - %s", info.sqlcode, info.fbcode, (const char*)text );
232232
MessageBox( NULL, buffer, TEXT( "Error!" ), MB_ICONERROR | MB_OK );
233233
}
234234

0 commit comments

Comments
 (0)