diff --git a/harbour/ChangeLog b/harbour/ChangeLog index 88c4ec5449..4abb184d54 100644 --- a/harbour/ChangeLog +++ b/harbour/ChangeLog @@ -17,6 +17,24 @@ past entries belonging to author(s): Viktor Szakats. */ +2010-04-23 00:49 UTC+0200 Przemyslaw Czerpak (druzus/at/priv.onet.pl) + * harbour/src/common/hbtrace.c + ! fixed potential GPF due to reused va_list parameter which can be + exploited with some calling conventions + ! fixed potential memory leak due to missing va_end() for va_list + parameter initialized with va_copy() which can be exploited with + some calling conventions + * simplified a little bit the code by eliminating repeated code in + Windows and *nix #if branches. + + * harbour/src/rdd/dbf1.c + ! added protection against GPF when user creates DBF table with + total record size greater then 65535 bytes. + Now RTE CREATE 1021 is generated in such case. + ! added protection against potential GPF when corrupted DBF file + is open and total field length in DBF header file gives more then + 65535. RTE CORRUPT 1012 is generated in such case. + 2010-04-23 01:32 UTC+0300 Mindaugas Kavaliauskas (dbtopas/at/dbtopas.lt) * harbour/contrib/rddads/ads1.c * adjusted empty date fallback condition in putValue method. diff --git a/harbour/src/common/hbtrace.c b/harbour/src/common/hbtrace.c index d1fc90d922..d794148270 100644 --- a/harbour/src/common/hbtrace.c +++ b/harbour/src/common/hbtrace.c @@ -67,6 +67,14 @@ #include #endif +#ifndef va_copy +# ifdef __va_copy +# define va_copy( dst, src ) __va_copy( dst, src ) +# else +# define va_copy( dst, src ) ( (dst) = (src) ) +# endif +#endif + static int s_enabled = 1; static int s_level = -1; static int s_flush = 0; @@ -182,11 +190,6 @@ static void hb_tracelog_( int level, const char * file, int line, const char * p { const char * pszLevel; -#if defined( HB_OS_UNIX ) && ! defined( __WATCOMC__ ) - va_list ap_bak; - va_copy( ap_bak, ap ); -#endif - /* * Clean up the file, so that instead of showing * @@ -207,6 +210,77 @@ static void hb_tracelog_( int level, const char * file, int line, const char * p pszLevel = ( level >= HB_TR_ALWAYS && level <= HB_TR_LAST ) ? s_slevel[ level ] : "(\?\?\?)"; + if( s_sysout ) + { +#if ( defined( HB_OS_WIN ) && ! defined( HB_OS_WIN_CE ) ) || \ + ( defined( HB_OS_UNIX ) && ! defined( __WATCOMC__ ) ) + + char message[ 1024 ]; + + va_list vargs; + va_copy( vargs, ap ); + + /* NOTE: This is protection against recursive call to trace engine when + there is more than 16 parameters in format string */ + if( hb_xtraced() && hb_printf_params( fmt ) > 16 ) + hb_snprintf( message, sizeof( message ), "more then 16 parameters in message '%s'", fmt ); + else + hb_vsnprintf( message, sizeof( message ), fmt, vargs ); + + va_end( vargs ); + +# if defined( HB_OS_WIN ) + { + union + { + char psz[ 1024 ]; + TCHAR lp[ 1024 ]; + } buf; + + + /* We add \n at the end of the buffer to make WinDbg display look readable. */ + if( proc ) + hb_snprintf( buf.psz, sizeof( buf.psz ), "%s:%d:%s() %s %s\n", + file, line, proc, pszLevel, message ); + else + hb_snprintf( buf.psz, sizeof( buf.psz ), "%s:%d: %s %s\n", + file, line, pszLevel, message ); + + #if defined( UNICODE ) + MultiByteToWideChar( CP_ACP, 0, ( LPCSTR ) memcpy( message, buf.psz, sizeof( message ) ), -1, + buf.lp, HB_SIZEOFARRAY( buf.lp ) ); + #endif + OutputDebugString( buf.lp ); + } +# else + { + char psz[ 1024 ]; + int slevel; + + if( proc ) + hb_snprintf( psz, sizeof( psz ), "%s:%d:%s() %s %s", + file, line, proc, pszLevel, message ); + else + hb_snprintf( psz, sizeof( psz ), "%s:%d: %s %s", + file, line, pszLevel, message ); + + switch( level ) + { + case HB_TR_ALWAYS: slevel = LOG_ALERT; break; + case HB_TR_FATAL: slevel = LOG_CRIT; break; + case HB_TR_ERROR: slevel = LOG_ERR; break; + case HB_TR_WARNING: slevel = LOG_WARNING; break; + case HB_TR_INFO: slevel = LOG_INFO; break; + case HB_TR_DEBUG: slevel = LOG_DEBUG; break; + default: slevel = LOG_DEBUG; + } + + syslog( slevel, psz ); + } +# endif +#endif + } + /* * Print file and line. */ @@ -227,73 +301,6 @@ static void hb_tracelog_( int level, const char * file, int line, const char * p if( s_flush ) fflush( s_fp ); - - if( s_sysout ) - { -#if defined( HB_OS_WIN ) && ! defined( HB_OS_WIN_CE ) - - char message[ 1024 ]; - union - { - char psz[ 1024 ]; - TCHAR lp[ 1024 ]; - } buf; - - /* NOTE: This is protection against recursive call to trace engine when - there is more than 16 parameters in format string */ - if( hb_xtraced() && hb_printf_params( fmt ) > 16 ) - hb_snprintf( message, sizeof( message ), "more then 16 parameters in message '%s'", fmt ); - else - hb_vsnprintf( message, sizeof( message ), fmt, ap ); - - /* We add \n at the end of the buffer to make WinDbg display look readable. */ - if( proc ) - hb_snprintf( buf.psz, sizeof( buf.psz ), "%s:%d:%s() %s %s\n", - file, line, proc, pszLevel, message ); - else - hb_snprintf( buf.psz, sizeof( buf.psz ), "%s:%d: %s %s\n", - file, line, pszLevel, message ); - - #if defined( UNICODE ) - MultiByteToWideChar( CP_ACP, 0, ( LPCSTR ) memcpy( message, buf.psz, sizeof( message ) ), -1, - buf.lp, HB_SIZEOFARRAY( buf.lp ) ); - #endif - OutputDebugString( buf.lp ); - -#elif defined( HB_OS_UNIX ) && ! defined( __WATCOMC__ ) - - char message[ 1024 ]; - char psz[ 1024 ]; - int slevel; - - /* NOTE: This is protection against recursive call to trace engine when - there is more than 16 parameters in format string */ - if( hb_xtraced() && hb_printf_params( fmt ) > 16 ) - hb_snprintf( message, sizeof( message ), "more then 16 parameters in message '%s'", fmt ); - else - hb_vsnprintf( message, sizeof( message ), fmt, ap_bak ); - - if( proc ) - hb_snprintf( psz, sizeof( psz ), "%s:%d:%s() %s %s", - file, line, proc, pszLevel, message ); - else - hb_snprintf( psz, sizeof( psz ), "%s:%d: %s %s", - file, line, pszLevel, message ); - - switch( level ) - { - case HB_TR_ALWAYS: slevel = LOG_ALERT; break; - case HB_TR_FATAL: slevel = LOG_CRIT; break; - case HB_TR_ERROR: slevel = LOG_ERR; break; - case HB_TR_WARNING: slevel = LOG_WARNING; break; - case HB_TR_INFO: slevel = LOG_INFO; break; - case HB_TR_DEBUG: slevel = LOG_DEBUG; break; - default: slevel = LOG_DEBUG; - } - - syslog( slevel, psz ); -#endif - } } void hb_tracelog( int level, const char * file, int line, const char * proc, diff --git a/harbour/src/rdd/dbf1.c b/harbour/src/rdd/dbf1.c index 357d895090..d61e89b144 100644 --- a/harbour/src/rdd/dbf1.c +++ b/harbour/src/rdd/dbf1.c @@ -1560,7 +1560,10 @@ static HB_ERRCODE hb_dbfAddField( DBFAREAP pArea, LPDBFIELDINFO pFieldInfo ) /* Update field offset */ pArea->pFieldOffset[ pArea->area.uiFieldCount ] = pArea->uiRecordLen; pArea->uiRecordLen += pFieldInfo->uiLen; - return SUPER_ADDFIELD( ( AREAP ) pArea, pFieldInfo ); + if( pArea->pFieldOffset[ pArea->area.uiFieldCount ] > pArea->uiRecordLen ) + return HB_FAILURE; + else + return SUPER_ADDFIELD( ( AREAP ) pArea, pFieldInfo ); } /* @@ -3047,11 +3050,13 @@ static HB_ERRCODE hb_dbfCreate( DBFAREAP pArea, LPDBOPENINFO pCreateInfo ) default: fError = HB_TRUE; } - if( fError ) + + if( fError || pArea->pFieldOffset[ uiCount ] > pArea->uiRecordLen ) { hb_xfree( pBuffer ); SELF_CLOSE( ( AREAP ) pArea ); - hb_dbfErrorRT( pArea, EG_CREATE, EDBF_DATATYPE, pCreateInfo->abName, 0, 0, NULL ); + hb_dbfErrorRT( pArea, EG_CREATE, fError ? EDBF_DATATYPE : EDBF_DATAWIDTH, + pCreateInfo->abName, 0, 0, NULL ); pArea->lpdbOpenInfo = NULL; return HB_FAILURE; } @@ -4026,7 +4031,8 @@ static HB_ERRCODE hb_dbfOpen( DBFAREAP pArea, LPDBOPENINFO pOpenInfo ) if( memcmp( dbFieldInfo.atomName, "_NullFlags", 10 ) == 0 ) pArea->uiNullOffset = pArea->uiRecordLen; pArea->uiRecordLen += dbFieldInfo.uiLen; - continue; + if( pArea->uiRecordLen >= dbFieldInfo.uiLen ) + continue; } default: