[PATCH 1/2] msado15: Prevent Multiple Open/Close of a _Recordset.

Alistair Leslie-Hughes leslie_alistair at hotmail.com
Thu Dec 12 19:18:14 CST 2019


Currently closing twice or Close/Release would cause a crash.

Signed-off-by: Alistair Leslie-Hughes <leslie_alistair at hotmail.com>
---
 dlls/msado15/recordset.c     | 15 +++++++++++----
 dlls/msado15/tests/msado15.c |  3 +++
 2 files changed, 14 insertions(+), 4 deletions(-)

diff --git a/dlls/msado15/recordset.c b/dlls/msado15/recordset.c
index e854b3e824..f0bb1591aa 100644
--- a/dlls/msado15/recordset.c
+++ b/dlls/msado15/recordset.c
@@ -658,9 +658,12 @@ static void close_recordset( struct recordset *recordset )
 {
     ULONG row, col, col_count = get_column_count( recordset );
 
-    recordset->fields->recordset = NULL;
-    Fields_Release( &recordset->fields->Fields_iface );
-    recordset->fields = NULL;
+    if (recordset->fields)
+    {
+        recordset->fields->recordset = NULL;
+        Fields_Release( &recordset->fields->Fields_iface );
+        recordset->fields = NULL;
+    }
 
     for (row = 0; row < recordset->count; row++)
         for (col = 0; col < col_count; col++) VariantClear( &recordset->data[row * col_count + col] );
@@ -668,6 +671,7 @@ static void close_recordset( struct recordset *recordset )
     recordset->count = recordset->allocated = recordset->index = 0;
     heap_free( recordset->data );
     recordset->data = NULL;
+    recordset->state = adStateClosed;
 }
 
 static ULONG WINAPI recordset_Release( _Recordset *iface )
@@ -905,8 +909,9 @@ static HRESULT WINAPI recordset_Close( _Recordset *iface )
 
     TRACE( "%p\n", recordset );
 
+    if (recordset->state == adStateClosed) return MAKE_ADO_HRESULT( adErrObjectClosed );
+
     close_recordset( recordset );
-    recordset->state = adStateClosed;
     return S_OK;
 }
 
@@ -960,6 +965,8 @@ static HRESULT WINAPI recordset_Open( _Recordset *iface, VARIANT source, VARIANT
     FIXME( "%p, %s, %s, %d, %d, %d\n", recordset, debugstr_variant(&source), debugstr_variant(&active_connection),
            cursor_type, lock_type, options );
 
+    if (recordset->state == adStateOpen) return MAKE_ADO_HRESULT( adErrObjectOpen );
+
     recordset->state = adStateOpen;
     return S_OK;
 }
diff --git a/dlls/msado15/tests/msado15.c b/dlls/msado15/tests/msado15.c
index f9a5377c50..494f1be463 100644
--- a/dlls/msado15/tests/msado15.c
+++ b/dlls/msado15/tests/msado15.c
@@ -86,6 +86,9 @@ static void test_Recordset(void)
     ok( hr == S_OK, "got %08x\n", hr );
     ok( !count, "got %d\n", count );
 
+    hr = _Recordset_Close( recordset );
+    ok( hr == MAKE_ADO_HRESULT( adErrObjectClosed ), "got %08x\n", hr );
+    
     refs = _Recordset_Release( recordset );
     ok( !refs, "got %d\n", refs );
 
-- 
2.17.1




More information about the wine-devel mailing list