Skip to content

Commit ec2e608

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 replaces each single `catch (std::exception &ex)` with the idiomatic two-handler form: catch (SQLException &ex) { ... } catch (std::exception &ex) { ... } C++ exception-matching picks the most-derived handler at runtime, so the SQLException catch sees only true SQLException objects and the std::exception catch sees only non-SQLException objects -- no dynamic_cast or helper required. A companion postError(state, std::exception&) overload pairs with the existing postError(state, SQLException&); each catch dispatches the right one statically based on the type of `ex`. All 64 occurrences of the broken pattern across OdbcConnection / OdbcStatement / OdbcDesc / OdbcEnv and the Windows OdbcJdbcSetup tree are converted to this form. OdbcConnection::connect gets a small rollbackPartialConnect lambda so its two catch bodies stay short, plus a NULL guard around connection->close() -- if createConnection() throws before assignment, the previous code dereferenced a NULL pointer during cleanup.
1 parent 3f822ce commit ec2e608

14 files changed

Lines changed: 560 additions & 215 deletions

OdbcConnection.cpp

Lines changed: 71 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1026,10 +1026,14 @@ SQLRETURN OdbcConnection::sqlNativeSql( SQLCHAR * inStatementText, SQLINTEGER te
10261026
outText = (const char *)tempNative;
10271027

10281028
}
1029-
catch ( std::exception &ex )
1029+
catch (SQLException &ex)
10301030
{
1031-
SQLException &exception = (SQLException&)ex;
1032-
postError( "HY000", exception );
1031+
postError( "HY000", ex );
1032+
return SQL_ERROR;
1033+
}
1034+
catch (std::exception &ex)
1035+
{
1036+
postError( "HY000", ex );
10331037
return SQL_ERROR;
10341038
}
10351039

@@ -1132,10 +1136,16 @@ SQLRETURN OdbcConnection::sqlDisconnect()
11321136
connection = NULL;
11331137
connected = false;
11341138
}
1135-
catch ( std::exception &ex )
1139+
catch (SQLException &ex)
11361140
{
1137-
SQLException &exception = (SQLException&)ex;
1138-
postError ("01002", exception);
1141+
postError ("01002", ex);
1142+
connection = NULL;
1143+
connected = false;
1144+
return SQL_SUCCESS_WITH_INFO;
1145+
}
1146+
catch (std::exception &ex)
1147+
{
1148+
postError ("01002", ex);
11391149
connection = NULL;
11401150
connected = false;
11411151
return SQL_SUCCESS_WITH_INFO;
@@ -1632,6 +1642,21 @@ SQLRETURN OdbcConnection::connect(const char *sharedLibrary, const char * databa
16321642
{
16331643
Properties *properties = NULL;
16341644

1645+
// Shared rollback for both catch handlers below. `connection` may be
1646+
// NULL if createConnection() itself threw before assignment, so it has
1647+
// to be checked before close().
1648+
auto rollbackPartialConnect = [&]() {
1649+
if ( env->envShare )
1650+
env->envShare = NULL;
1651+
if ( properties )
1652+
properties->release();
1653+
if ( connection )
1654+
{
1655+
connection->close();
1656+
connection = NULL;
1657+
}
1658+
};
1659+
16351660
try
16361661
{
16371662
connection = createConnection();
@@ -1709,19 +1734,15 @@ SQLRETURN OdbcConnection::connect(const char *sharedLibrary, const char * databa
17091734
WcsToMbs = connection->getConnectionWcsToMbs();
17101735
MbsToWcs = connection->getConnectionMbsToWcs();
17111736
}
1712-
catch ( std::exception &ex )
1737+
catch (SQLException &ex)
17131738
{
1714-
SQLException &exception = (SQLException&)ex;
1715-
if ( env->envShare )
1716-
env->envShare = NULL;
1717-
1718-
if ( properties )
1719-
properties->release();
1720-
1721-
connection->close();
1722-
connection = NULL;
1723-
1724-
return sqlReturn( SQL_ERROR, "08004", exception.getText(), exception.getSqlcode() );
1739+
rollbackPartialConnect();
1740+
return sqlReturn( SQL_ERROR, "08004", ex.getText(), ex.getSqlcode() );
1741+
}
1742+
catch (std::exception &ex)
1743+
{
1744+
rollbackPartialConnect();
1745+
return sqlReturn( SQL_ERROR, "08004", ex.what(), 0 );
17251746
}
17261747

17271748
connected = true;
@@ -1746,10 +1767,14 @@ SQLRETURN OdbcConnection::sqlEndTran(int operation)
17461767
connection->rollbackAuto();
17471768
}
17481769
}
1749-
catch ( std::exception &ex )
1770+
catch (SQLException &ex)
1771+
{
1772+
postError ("S1000", ex);
1773+
return SQL_ERROR;
1774+
}
1775+
catch (std::exception &ex)
17501776
{
1751-
SQLException &exception = (SQLException&)ex;
1752-
postError ("S1000", exception);
1777+
postError ("S1000", ex);
17531778
return SQL_ERROR;
17541779
}
17551780

@@ -1764,10 +1789,14 @@ SQLRETURN OdbcConnection::sqlExecuteCreateDatabase(const char * sqlString)
17641789
{
17651790
connection->sqlExecuteCreateDatabase( sqlString );
17661791
}
1767-
catch ( std::exception &ex )
1792+
catch (SQLException &ex)
17681793
{
1769-
SQLException &exception = (SQLException&)ex;
1770-
postError( "HY000", exception );
1794+
postError( "HY000", ex );
1795+
return SQL_ERROR;
1796+
}
1797+
catch (std::exception &ex)
1798+
{
1799+
postError( "HY000", ex );
17711800
return SQL_ERROR;
17721801
}
17731802

@@ -2178,10 +2207,13 @@ void OdbcConnection::initUserEvents( PODBC_EVENTS_BLOCK_INFO infoEvents )
21782207
userEventsInterfase->events = infoEvents->events;
21792208
userEventsInterfase->count = infoEvents->count;
21802209
}
2181-
catch ( std::exception &ex )
2210+
catch (SQLException &ex)
2211+
{
2212+
postError( "HY000", ex );
2213+
}
2214+
catch (std::exception &ex)
21822215
{
2183-
SQLException &exception = (SQLException&)ex;
2184-
postError( "HY000", exception );
2216+
postError( "HY000", ex );
21852217
}
21862218
}
21872219

@@ -2199,10 +2231,13 @@ void OdbcConnection::updateResultEvents( char *updated )
21992231
nextNameEvent->changed = userEvents->isChanged( i );
22002232
}
22012233
}
2202-
catch ( std::exception &ex )
2234+
catch (SQLException &ex)
2235+
{
2236+
postError( "HY000", ex );
2237+
}
2238+
catch (std::exception &ex)
22032239
{
2204-
SQLException &exception = (SQLException&)ex;
2205-
postError( "HY000", exception );
2240+
postError( "HY000", ex );
22062241
}
22072242
}
22082243

@@ -2212,10 +2247,13 @@ void OdbcConnection::requeueEvents()
22122247
{
22132248
userEvents->queEvents( userEventsInterfase );
22142249
}
2215-
catch ( std::exception &ex )
2250+
catch (SQLException &ex)
2251+
{
2252+
postError( "HY000", ex );
2253+
}
2254+
catch (std::exception &ex)
22162255
{
2217-
SQLException &exception = (SQLException&)ex;
2218-
postError( "HY000", exception );
2256+
postError( "HY000", ex );
22192257
}
22202258
}
22212259

OdbcDesc.cpp

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -805,10 +805,14 @@ SQLRETURN OdbcDesc::sqlGetDescField(int recNumber, int fieldId, SQLPOINTER ptr,
805805
return returnStringInfo (ptr, bufferLength, lengthPtr, (char*)string);
806806

807807
}
808-
catch ( std::exception &ex )
808+
catch (SQLException &ex)
809809
{
810-
SQLException &exception = (SQLException&)ex;
811-
postError ("HY000", exception);
810+
postError ("HY000", ex);
811+
return SQL_ERROR;
812+
}
813+
catch (std::exception &ex)
814+
{
815+
postError ("HY000", ex);
812816
return SQL_ERROR;
813817
}
814818

@@ -1216,10 +1220,14 @@ SQLRETURN OdbcDesc::sqlGetDescRec( SQLSMALLINT recNumber,
12161220
*scalePtr = record->scale;
12171221
*nullablePtr = record->nullable;
12181222
}
1219-
catch ( std::exception &ex )
1223+
catch (SQLException &ex)
12201224
{
1221-
SQLException &exception = (SQLException&)ex;
1222-
postError ("HY000", exception);
1225+
postError ("HY000", ex);
1226+
return SQL_ERROR;
1227+
}
1228+
catch (std::exception &ex)
1229+
{
1230+
postError ("HY000", ex);
12231231
return SQL_ERROR;
12241232
}
12251233

@@ -1264,10 +1272,14 @@ SQLRETURN OdbcDesc::sqlSetDescRec( SQLSMALLINT recNumber,
12641272
record->octetLengthPtr = stringLengthPtr;
12651273
record->indicatorPtr = indicatorPtr;
12661274
}
1267-
catch ( std::exception &ex )
1275+
catch (SQLException &ex)
1276+
{
1277+
postError ("HY000", ex);
1278+
return SQL_ERROR;
1279+
}
1280+
catch (std::exception &ex)
12681281
{
1269-
SQLException &exception = (SQLException&)ex;
1270-
postError ("HY000", exception);
1282+
postError ("HY000", ex);
12711283
return SQL_ERROR;
12721284
}
12731285

OdbcEnv.cpp

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -132,10 +132,14 @@ SQLRETURN OdbcEnv::sqlEndTran(int operation)
132132
{
133133
envShare->sqlEndTran (operation);
134134
}
135-
catch ( std::exception &ex )
135+
catch (SQLException &ex)
136136
{
137-
SQLException &exception = (SQLException&)ex;
138-
postError ("HY000", exception);
137+
postError ("HY000", ex);
138+
return SQL_ERROR;
139+
}
140+
catch (std::exception &ex)
141+
{
142+
postError ("HY000", ex);
139143
return SQL_ERROR;
140144
}
141145

@@ -192,10 +196,14 @@ SQLRETURN OdbcEnv::sqlGetEnvAttr(int attribute, SQLPOINTER ptr, int bufferLength
192196
if (lengthPtr)
193197
*lengthPtr = sizeof (int);
194198
}
195-
catch ( std::exception &ex )
199+
catch (SQLException &ex)
196200
{
197-
SQLException &exception = (SQLException&)ex;
198-
postError ("HY000", exception);
201+
postError ("HY000", ex);
202+
return SQL_ERROR;
203+
}
204+
catch (std::exception &ex)
205+
{
206+
postError ("HY000", ex);
199207
return SQL_ERROR;
200208
}
201209

@@ -222,10 +230,14 @@ SQLRETURN OdbcEnv::sqlSetEnvAttr(int attribute, SQLPOINTER value, int length)
222230
return sqlReturn (SQL_ERROR, "HYC00", "Optional feature not implemented");
223231
}
224232
}
225-
catch ( std::exception &ex )
233+
catch (SQLException &ex)
234+
{
235+
postError ("HY000", ex);
236+
return SQL_ERROR;
237+
}
238+
catch (std::exception &ex)
226239
{
227-
SQLException &exception = (SQLException&)ex;
228-
postError ("HY000", exception);
240+
postError ("HY000", ex);
229241
return SQL_ERROR;
230242
}
231243

OdbcJdbcSetup/DsnDialog.cpp

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -789,11 +789,20 @@ void CDsnDialog::OnTestConnection( HWND hDlg )
789789

790790
MessageBox( hDlg, _TR( IDS_MESSAGE_01, "Connection successful!" ), TEXT( strHeadDlg ), MB_ICONINFORMATION | MB_OK );
791791
}
792-
catch ( std::exception &ex )
792+
catch (SQLException &ex)
793793
{
794-
SQLException &exception = (SQLException&)ex;
795794
char buffer[2048];
796-
JString text = exception.getText();
795+
JString text = ex.getText();
796+
797+
sprintf( buffer, "%s\n%s", _TR( IDS_MESSAGE_02, "Connection failed!" ), (const char*)text );
798+
removeNameFileDBfromMessage ( buffer );
799+
800+
MessageBox( hDlg, TEXT( buffer ), TEXT( strHeadDlg ), MB_ICONERROR | MB_OK );
801+
}
802+
catch (std::exception &ex)
803+
{
804+
char buffer[2048];
805+
JString text = ex.what();
797806

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

OdbcJdbcSetup/ServiceClient.cpp

Lines changed: 35 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -84,10 +84,20 @@ bool CServiceClient::initServices( const char *sharedLibrary )
8484
if ( !properties )
8585
return false;
8686
}
87-
catch ( std::exception &ex )
87+
catch (SQLException &ex)
8888
{
89-
SQLException &exception = (SQLException&)ex;
90-
JString text = exception.getText();
89+
JString text = ex.getText();
90+
91+
if ( services )
92+
{
93+
services->release();
94+
services = NULL;
95+
return false;
96+
}
97+
}
98+
catch (std::exception &ex)
99+
{
100+
JString text = ex.what();
91101

92102
if ( services )
93103
{
@@ -143,10 +153,18 @@ bool CServiceClient::createDatabase()
143153
properties );
144154
connection->close();
145155
}
146-
catch ( std::exception &ex )
156+
catch (SQLException &ex)
147157
{
148-
SQLException &exception = (SQLException&)ex;
149-
JString text = exception.getText();
158+
JString text = ex.getText();
159+
160+
if ( connection )
161+
connection->close();
162+
163+
return false;
164+
}
165+
catch (std::exception &ex)
166+
{
167+
JString text = ex.what();
150168

151169
if ( connection )
152170
connection->close();
@@ -187,10 +205,18 @@ bool CServiceClient::dropDatabase()
187205
properties );
188206
connection->close();
189207
}
190-
catch ( std::exception &ex )
208+
catch (SQLException &ex)
209+
{
210+
JString text = ex.getText();
211+
212+
if ( connection )
213+
connection->close();
214+
215+
return false;
216+
}
217+
catch (std::exception &ex)
191218
{
192-
SQLException &exception = (SQLException&)ex;
193-
JString text = exception.getText();
219+
JString text = ex.what();
194220

195221
if ( connection )
196222
connection->close();

0 commit comments

Comments
 (0)