msi: Avoid pointer truncation in MSI_ViewFetch and MSI_ViewModify.

oldstable
Hans Leidekker 2010-09-10 17:30:05 +02:00 committed by Alexandre Julliard
parent addefe4ce5
commit 7e9d50a122
3 changed files with 52 additions and 2 deletions

View File

@ -103,6 +103,7 @@ typedef struct tagMSIFIELD
union
{
INT iVal;
INT_PTR pVal;
LPWSTR szwVal;
IStream *stream;
} u;
@ -709,11 +710,13 @@ extern UINT MSI_RecordGetIStream( MSIRECORD *, UINT, IStream **);
extern const WCHAR *MSI_RecordGetString( const MSIRECORD *, UINT );
extern MSIRECORD *MSI_CreateRecord( UINT );
extern UINT MSI_RecordSetInteger( MSIRECORD *, UINT, int );
extern UINT MSI_RecordSetIntPtr( MSIRECORD *, UINT, INT_PTR );
extern UINT MSI_RecordSetStringW( MSIRECORD *, UINT, LPCWSTR );
extern BOOL MSI_RecordIsNull( MSIRECORD *, UINT );
extern UINT MSI_RecordGetStringW( MSIRECORD * , UINT, LPWSTR, LPDWORD);
extern UINT MSI_RecordGetStringA( MSIRECORD *, UINT, LPSTR, LPDWORD);
extern int MSI_RecordGetInteger( MSIRECORD *, UINT );
extern INT_PTR MSI_RecordGetIntPtr( MSIRECORD *, UINT );
extern UINT MSI_RecordReadStream( MSIRECORD *, UINT, char *, LPDWORD);
extern UINT MSI_RecordSetStream(MSIRECORD *, UINT, IStream *);
extern UINT MSI_RecordGetFieldCount( const MSIRECORD *rec );

View File

@ -382,7 +382,7 @@ UINT MSI_ViewFetch(MSIQUERY *query, MSIRECORD **prec)
if (r == ERROR_SUCCESS)
{
query->row ++;
MSI_RecordSetInteger(*prec, 0, (int)query);
MSI_RecordSetIntPtr(*prec, 0, (INT_PTR)query);
}
return r;
@ -617,7 +617,7 @@ UINT MSI_ViewModify( MSIQUERY *query, MSIMODIFY mode, MSIRECORD *rec )
if ( !view || !view->ops->modify)
return ERROR_FUNCTION_FAILED;
if ( mode == MSIMODIFY_UPDATE && MSI_RecordGetInteger( rec, 0 ) != (int)query )
if ( mode == MSIMODIFY_UPDATE && MSI_RecordGetIntPtr( rec, 0 ) != (INT_PTR)query )
return ERROR_FUNCTION_FAILED;
r = view->ops->modify( view, mode, rec, query->row );

View File

@ -45,6 +45,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(msidb);
#define MSIFIELD_INT 1
#define MSIFIELD_WSTR 3
#define MSIFIELD_STREAM 4
#define MSIFIELD_INTPTR 5
static void MSI_FreeField( MSIFIELD *field )
{
@ -52,6 +53,7 @@ static void MSI_FreeField( MSIFIELD *field )
{
case MSIFIELD_NULL:
case MSIFIELD_INT:
case MSIFIELD_INTPTR:
break;
case MSIFIELD_WSTR:
msi_free( field->u.szwVal);
@ -177,6 +179,9 @@ UINT MSI_RecordCopyField( MSIRECORD *in_rec, UINT in_n,
case MSIFIELD_INT:
out->u.iVal = in->u.iVal;
break;
case MSIFIELD_INTPTR:
out->u.pVal = in->u.pVal;
break;
case MSIFIELD_WSTR:
str = strdupW( in->u.szwVal );
if ( !str )
@ -200,6 +205,32 @@ UINT MSI_RecordCopyField( MSIRECORD *in_rec, UINT in_n,
return r;
}
INT_PTR MSI_RecordGetIntPtr( MSIRECORD *rec, UINT iField )
{
int ret;
TRACE( "%p %d\n", rec, iField );
if( iField > rec->count )
return MININT_PTR;
switch( rec->fields[iField].type )
{
case MSIFIELD_INT:
return rec->fields[iField].u.iVal;
case MSIFIELD_INTPTR:
return rec->fields[iField].u.pVal;
case MSIFIELD_WSTR:
if( string2intW( rec->fields[iField].u.szwVal, &ret ) )
return ret;
return MININT_PTR;
default:
break;
}
return MININT_PTR;
}
int MSI_RecordGetInteger( MSIRECORD *rec, UINT iField)
{
int ret = 0;
@ -213,6 +244,8 @@ int MSI_RecordGetInteger( MSIRECORD *rec, UINT iField)
{
case MSIFIELD_INT:
return rec->fields[iField].u.iVal;
case MSIFIELD_INTPTR:
return rec->fields[iField].u.pVal;
case MSIFIELD_WSTR:
if( string2intW( rec->fields[iField].u.szwVal, &ret ) )
return ret;
@ -267,6 +300,20 @@ UINT WINAPI MsiRecordClearData( MSIHANDLE handle )
return ERROR_SUCCESS;
}
UINT MSI_RecordSetIntPtr( MSIRECORD *rec, UINT iField, INT_PTR pVal )
{
TRACE("%p %u %ld\n", rec, iField, pVal);
if( iField > rec->count )
return ERROR_INVALID_PARAMETER;
MSI_FreeField( &rec->fields[iField] );
rec->fields[iField].type = MSIFIELD_INTPTR;
rec->fields[iField].u.pVal = pVal;
return ERROR_SUCCESS;
}
UINT MSI_RecordSetInteger( MSIRECORD *rec, UINT iField, int iVal )
{
TRACE("%p %u %d\n", rec, iField, iVal);