[1/3] msi: Avoid pointer truncation in MSI_ViewFetch and MSI_ViewModify.

Hans Leidekker hans at codeweavers.com
Fri Sep 10 10:30:05 CDT 2010


---
 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);
-- 
1.7.0.4







More information about the wine-patches mailing list