From: Alistair Leslie-Hughes Subject: [PATCH 1/2] msado15: Prevent Multiple Open/Close of a _Recordset. Message-Id: Date: Fri, 13 Dec 2019 01:18:14 +0000 Currently closing twice or Close/Release would cause a crash. Signed-off-by: Alistair Leslie-Hughes --- 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