Skip to content

Commit

Permalink
2023-11-15 15:57 UTC+0100 Phil Krylov (phil a t krylov.eu)
Browse files Browse the repository at this point in the history
  * contrib/hbsqlit3/tests/backup.prg
    + Simple change in test to provoke access to dangling pointer saved
      by SQLITE3_TRACE().
  * contrib/hbsqlit3/core.c
    ! Fixed dangling pointer access with SQLITE3_TRACE(), SQLITE3_PROFILE().
  • Loading branch information
tuffnatty committed Nov 15, 2023
1 parent 3939012 commit 4395263
Show file tree
Hide file tree
Showing 3 changed files with 187 additions and 8 deletions.
7 changes: 7 additions & 0 deletions ChangeLog.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,13 @@
Entries may not always be in chronological/commit order.
See license at the end of file. */

2023-11-15 15:57 UTC+0100 Phil Krylov (phil a t krylov.eu)
* contrib/hbsqlit3/tests/backup.prg
+ Simple change in test to provoke access to dangling pointer saved
by SQLITE3_TRACE().
* contrib/hbsqlit3/core.c
! Fixed dangling pointer access with SQLITE3_TRACE(), SQLITE3_PROFILE().

2023-11-14 22:27 UTC+0100 Phil Krylov (phil a t krylov.eu)
* .github/workflows/linux-ci.yml
* On Linux CI workflow, run tests with Valgrind.
Expand Down
182 changes: 175 additions & 7 deletions contrib/hbsqlit3/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,9 @@ static int progress_handler( void * );
static int hook_commit( void * );
static void hook_rollback( void * );
static void func( sqlite3_context *, int, sqlite3_value ** );
#if SQLITE_VERSION_NUMBER >= 3014000
static int trace_handler( unsigned, void *, void *, void * );
#endif

typedef struct
{
Expand All @@ -92,6 +95,12 @@ typedef struct
PHB_ITEM cbHookCommit;
PHB_ITEM cbHookRollback;
PHB_ITEM cbFunc;
#if SQLITE_VERSION_NUMBER >= 3014000
PHB_ITEM cbTraceHandler;
#else
PHB_ITEM sProfileFileName;
PHB_ITEM sTraceFileName;
#endif
} HB_SQLITE3, * PHB_SQLITE3;

typedef struct
Expand Down Expand Up @@ -154,6 +163,25 @@ static HB_GARBAGE_FUNC( hb_sqlite3_destructor )
pStructHolder->hbsqlite3->cbFunc = NULL;
}

#if SQLITE_VERSION_NUMBER >= 3014000
if( pStructHolder->hbsqlite3->cbTraceHandler )
{
hb_itemRelease( pStructHolder->hbsqlite3->cbTraceHandler );
pStructHolder->hbsqlite3->cbTraceHandler = NULL;
}
#else
if( pStructHolder->hbsqlite3->sProfileFileName )
{
hb_itemRelease( pStructHolder->hbsqlite3->sProfileFileName );
pStructHolder->hbsqlite3->sProfileFileName = NULL;
}
if( pStructHolder->hbsqlite3->sTraceFileName )
{
hb_itemRelease( pStructHolder->hbsqlite3->sTraceFileName );
pStructHolder->hbsqlite3->sTraceFileName = NULL;
}
#endif

hb_xfree( pStructHolder->hbsqlite3 );
pStructHolder->hbsqlite3 = NULL;
}
Expand Down Expand Up @@ -182,6 +210,22 @@ static HB_GARBAGE_FUNC( hb_sqlite3_mark )

if( pStructHolder->hbsqlite3->cbFunc )
hb_gcMark( pStructHolder->hbsqlite3->cbFunc );

#if SQLITE_VERSION_NUMBER >= 3014000
if( pStructHolder->hbsqlite3->cbTraceHandler )
{
hb_gcMark( pStructHolder->hbsqlite3->cbTraceHandler );
}
#else
if( pStructHolder->hbsqlite3->sProfileFileName )
{
hb_gcMark( pStructHolder->hbsqlite3->sProfileFileName );
}
if( pStructHolder->hbsqlite3->sTraceFileName )
{
hb_gcMark( pStructHolder->hbsqlite3->sTraceFileName );
}
#endif
}
}

Expand Down Expand Up @@ -1754,14 +1798,107 @@ HB_FUNC( SQLITE3_ENABLE_SHARED_CACHE )
hb_retni( sqlite3_enable_shared_cache( hb_parl( 1 ) ) );
}

/* TODO: implement sqlite3_trace_v2(), that replaces both of these deprecated functions */

/**
Tracing And Profiling Functions
sqlite3_trace( db, lOnOff )
sqlite3_profile( db, lOnOff )
sqlite3_trace_v2( db, nMask, [ bCallback ] ) // Starting with 3.14.0
sqlite3_trace( db, lOnOff, [ filename ] ) // Deprecated in 3.14.0
sqlite3_profile( db, lOnOff, [ filename ] ) // Deprecated in 3.14.0
*/
#if SQLITE_VERSION_NUMBER >= 3014000

static int trace_handler( unsigned uType, void *cbTraceHandler, void * p, void * x )
{
PHB_ITEM pCallback = ( PHB_ITEM ) cbTraceHandler;

if( pCallback && hb_vmRequestReenter() )
{
hb_vmPushEvalSym();
hb_vmPush( pCallback );
hb_vmPushNumInt( uType );
switch( uType )
{
case SQLITE_TRACE_STMT:
hb_vmPushPointer( p );
hb_vmPushString( x );
hb_vmSend( 3 )
break;
case SQLITE_TRACE_PROFILE:
hb_vmPushPointer( p );
hb_vmPushNumInt( *( sqlite3_uint64 * ) x );
hb_vmSend( 3 );
break;
case SQLITE_TRACE_ROW:
{
HB_SYMBOL_UNUSED( x );
hb_vmPushPointer( p );
hb_vmSend( 2 );
break;
}
case SQLITE_TRACE_CLOSE:
{
PHB_ITEM pItem = hb_itemNew( NULL );
hb_sqlite3_itemPut( pItem, p, HB_SQLITE3_DB );
HB_SYMBOL_UNUSED( x );
hb_vmPush( pItem );
hb_vmSend( 2 );
break;
}
}
iRes = hb_parni( -1 );
hb_vmRequestRestore();
return iRes;
}
return 0;
}

HB_FUNC( SQLITE3_EXPANDED_SQL )
{
psqlite3_stmt pStmt = ( psqlite3_stmt ) hb_parptr( 1 );
if( pStmt )
{
char *sql = sqlite3_expanded_sql( pStmt );
hb_retstr_utf8( sql );
sqlite3_free( sql );
}
else
hb_errRT_BASE_SubstR( EG_ARG, 0, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS );
}

HB_FUNC( SQLITE3_TRACE_V2 )
{
HB_SQLITE3 * pHbSqlite3 = ( HB_SQLITE3 * ) hb_sqlite3_param( 1, HB_SQLITE3_DB, HB_TRUE );

if( pHbSqlite3 && pHbSqlite3->db )
{
unsigned uMask = ( unsigned int ) hb_parnint( 2 );

if( pHbSqlite3->cbTraceHandler )
{
hb_itemRelease( pHbSqlite3->cbTraceHandler );
pHbSqlite3->cbTraceHandler = NULL;
}

if( HB_ISEVALITEM( 3 ) )
{
pHbSqlite3->cbTraceHandler = hb_itemNew( hb_param( 3, HB_IT_EVALITEM ) );
hb_gcUnlock( pHbSqlite3->cbTraceHandler );

sqlite3_trace_v2( pHbSqlite3->db, uMask,
uMask ? trace_handler : NULL,
uMask ? ( void * ) pHbSqlite3->cbTraceHandler : NULL );
}
else
sqlite3_trace_v2( pHbSqlite3->db, 0, NULL, NULL );
}
else
hb_errRT_BASE_SubstR( EG_ARG, 0, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS );
}

#else

static void SQL3ProfileLog( void * sFile, const char * sProfileMsg, sqlite3_uint64 uint64 )
{
if( sProfileMsg )
Expand Down Expand Up @@ -1795,8 +1932,22 @@ HB_FUNC( SQLITE3_PROFILE )
HB_SQLITE3 * pHbSqlite3 = ( HB_SQLITE3 * ) hb_sqlite3_param( 1, HB_SQLITE3_DB, HB_TRUE );

if( pHbSqlite3 && pHbSqlite3->db )
sqlite3_profile( pHbSqlite3->db, hb_parl( 2 ) ? SQL3ProfileLog : NULL,
HB_ISCHAR( 3 ) ? HB_UNCONST( hb_parcx( 3 ) ) : NULL );
{
HB_BOOL bFlag = hb_parl( 2 );
if( pHbSqlite3->sProfileFileName )
{
hb_itemRelease( pHbSqlite3->sProfileFileName );
pHbSqlite3->sProfileFileName = NULL;
}
if( bFlag && HB_ISCHAR( 3 ) )
{
pHbSqlite3->sProfileFileName = hb_itemNew( hb_param( 3, HB_IT_STRING ) );
hb_gcUnlock( pHbSqlite3->sProfileFileName );
}

sqlite3_profile( pHbSqlite3->db, bFlag ? SQL3ProfileLog : NULL,
pHbSqlite3->sProfileFileName ? HB_UNCONST( hb_itemGetCPtr( pHbSqlite3->sProfileFileName ) ) : NULL );
}
else
hb_errRT_BASE_SubstR( EG_ARG, 0, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS );
}
Expand All @@ -1806,12 +1957,29 @@ HB_FUNC( SQLITE3_TRACE )
HB_SQLITE3 * pHbSqlite3 = ( HB_SQLITE3 * ) hb_sqlite3_param( 1, HB_SQLITE3_DB, HB_TRUE );

if( pHbSqlite3 && pHbSqlite3->db )
sqlite3_trace( pHbSqlite3->db, hb_parl( 2 ) ? SQL3TraceLog : NULL,
HB_ISCHAR( 3 ) ? HB_UNCONST( hb_parcx( 3 ) ) : NULL );
{
HB_BOOL bFlag = hb_parl( 2 );
if( pHbSqlite3->sTraceFileName )
{
hb_itemRelease( pHbSqlite3->sTraceFileName );
pHbSqlite3->sTraceFileName = NULL;
}
if( bFlag && HB_ISCHAR( 3 ) )
{
pHbSqlite3->sTraceFileName = hb_itemNew( hb_param( 3, HB_IT_STRING ) );
hb_gcUnlock( pHbSqlite3->sTraceFileName );
}

sqlite3_trace( pHbSqlite3->db, bFlag ? SQL3TraceLog : NULL,
pHbSqlite3->sTraceFileName ? HB_UNCONST( hb_itemGetCPtr( pHbSqlite3->sTraceFileName ) ) : NULL );
}
else
hb_errRT_BASE_SubstR( EG_ARG, 0, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS );
}

#endif


/**
BLOB Import/export
*/
Expand Down
6 changes: 5 additions & 1 deletion contrib/hbsqlit3/tests/backup.prg
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,10 @@

#require "hbsqlit3"

PROCEDURE init_trace( pDbDest, cPrefix )
sqlite3_trace( pDbDest, .T., cPrefix + ".log" )
RETURN

PROCEDURE Main()

LOCAL cFileSource := ":memory:", cFileDest := "backup.db", cSQLTEXT
Expand All @@ -85,7 +89,7 @@ PROCEDURE Main()
RETURN
ENDIF

sqlite3_trace( pDbDest, .T., "backup.log" )
init_trace( pDbDest, "backup" )

pBackup := sqlite3_backup_init( pDbDest, "main", pDbSource, "main" )
IF Empty( pBackup )
Expand Down

0 comments on commit 4395263

Please sign in to comment.