Module: wine Branch: master Commit: 7e9d50a122cca40cc1e538fdbf303cc5090f5dc9 URL: http://source.winehq.org/git/wine.git/?a=commit;h=7e9d50a122cca40cc1e538fdbf...
Author: Hans Leidekker hans@codeweavers.com Date: Fri Sep 10 17:30:05 2010 +0200
msi: Avoid pointer truncation in MSI_ViewFetch and MSI_ViewModify.
---
dlls/msi/msipriv.h | 3 +++ dlls/msi/msiquery.c | 4 ++-- dlls/msi/record.c | 47 +++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 52 insertions(+), 2 deletions(-)
diff --git a/dlls/msi/msipriv.h b/dlls/msi/msipriv.h index a5d089e..ebfcae7 100644 --- a/dlls/msi/msipriv.h +++ b/dlls/msi/msipriv.h @@ -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 ); diff --git a/dlls/msi/msiquery.c b/dlls/msi/msiquery.c index c603e6a..cf69593 100644 --- a/dlls/msi/msiquery.c +++ b/dlls/msi/msiquery.c @@ -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 ); diff --git a/dlls/msi/record.c b/dlls/msi/record.c index 45adbac..7bc8281 100644 --- a/dlls/msi/record.c +++ b/dlls/msi/record.c @@ -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);