Skip to content

Commit

Permalink
CPLSetErrorHandler(): avoid later crashes when passing a null callback.
Browse files Browse the repository at this point in the history
Fixes #298 (but in a different way that the PR itself)

git-svn-id: https://svn.osgeo.org/gdal/trunk@41428 f0d54148-0727-0410-94bb-9a71ac55c965
  • Loading branch information
rouault committed Feb 7, 2018
1 parent 955b9dd commit e647e14
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 18 deletions.
9 changes: 9 additions & 0 deletions autotest/cpp/test_cpl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -924,6 +924,15 @@ namespace tut
CPLPopErrorHandler();

CPLSetConfigOption("CPL_DEBUG", oldVal.size() ? oldVal.c_str() : nullptr);

oldHandler = CPLSetErrorHandler(nullptr);
CPLDebug("TEST", "Test");
CPLError(CE_Failure, CPLE_AppDefined, "test");
CPLErrorHandler newOldHandler = CPLSetErrorHandler(nullptr);
ensure_equals(newOldHandler, static_cast<CPLErrorHandler>(nullptr));
CPLDebug("TEST", "Test");
CPLError(CE_Failure, CPLE_AppDefined, "test");
CPLSetErrorHandler(oldHandler);
}

/************************************************************************/
Expand Down
33 changes: 15 additions & 18 deletions gdal/port/cpl_error.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -651,10 +651,12 @@ void CPLDebug( const char * pszCategory,
/* -------------------------------------------------------------------- */
/* Invoke the current error handler. */
/* -------------------------------------------------------------------- */
bool bDebugProcessed = false;
if( psCtx->psHandlerStack != nullptr )
{
if( psCtx->psHandlerStack->bCatchDebug )
{
bDebugProcessed = true;
psCtx->psHandlerStack->pfnHandler( CE_Debug, CPLE_None,
pszMessage );
}
Expand All @@ -665,30 +667,28 @@ void CPLDebug( const char * pszCategory,
{
if( psNode->bCatchDebug )
{
bDebugProcessed = true;
psNode->pfnHandler( CE_Debug, CPLE_None, pszMessage );
break;
}
psNode = psNode->psNext;
}
if( psNode == nullptr )
{
CPLMutexHolderD( &hErrorMutex );
if( gbCatchDebug )
pfnErrorHandler( CE_Debug, CPLE_None, pszMessage );
else
CPLDefaultErrorHandler( CE_Debug, CPLE_None, pszMessage );
}
}
}
else

if( !bDebugProcessed )
{
CPLMutexHolderD( &hErrorMutex );
if( pfnErrorHandler != nullptr )
if( gbCatchDebug )
{
if( gbCatchDebug )
if( pfnErrorHandler != nullptr )
{
pfnErrorHandler( CE_Debug, CPLE_None, pszMessage );
else
CPLDefaultErrorHandler( CE_Debug, CPLE_None, pszMessage );
}
}
else
{
CPLDefaultErrorHandler( CE_Debug, CPLE_None, pszMessage );
}
}

Expand Down Expand Up @@ -1091,10 +1091,7 @@ CPLSetErrorHandlerEx( CPLErrorHandler pfnErrorHandlerNew, void* pUserData )

pfnOldHandler = pfnErrorHandler;

if( pfnErrorHandler == nullptr )
pfnErrorHandler = CPLDefaultErrorHandler;
else
pfnErrorHandler = pfnErrorHandlerNew;
pfnErrorHandler = pfnErrorHandlerNew;

pErrorHandlerUserData = pUserData;
}
Expand Down Expand Up @@ -1255,7 +1252,7 @@ void CPL_STDCALL CPLPopErrorHandler()
* debug messages. In some cases, this might not be desirable and the user
* would prefer that the previous installed handler (or the default one if no
* previous installed handler exists in the stack) deal with it. In which
* case, this function should be called with bCatchDebug.
* case, this function should be called with bCatchDebug = FALSE.
*
* @param bCatchDebug FALSE if the current error handler should not intercept
* debug messages
Expand Down

0 comments on commit e647e14

Please sign in to comment.