From: Jefferson Carpenter Subject: [PATCH resend 4/4] msxml3/tests: Test for methods that break lock with writer domdoc dest. Message-Id: Date: Mon, 31 May 2021 20:07:07 +0000 I actually don't like 4/4 as much since the 2 helper methods I added `begin_writing_to_domdoc` and `check_domdoc_lock_broken` pretty much arbitrarily factor out code. Nevertheless, I would be fine maintaining this test, so please let me know what you think. thanks, Jefferson From cf52d1f38240b41af9643e4c99935e8d13888db8 Mon Sep 17 00:00:00 2001 From: Jefferson Carpenter Date: Mon, 31 May 2021 20:08:25 +0000 Subject: [PATCH 4/4] msxml3/tests: Test for methods that break lock with writer domdoc dest. Signed-off-by: Jefferson Carpenter --- dlls/msxml3/tests/saxreader.c | 170 ++++++++++++++++++++++++++++++++++ 1 file changed, 170 insertions(+) diff --git a/dlls/msxml3/tests/saxreader.c b/dlls/msxml3/tests/saxreader.c index 2a82a81da02..7a1dca7ec70 100644 --- a/dlls/msxml3/tests/saxreader.c +++ b/dlls/msxml3/tests/saxreader.c @@ -5479,6 +5479,175 @@ static void test_mxwriter_domdoc_startDocument_disables_domdoc_methods(void) IMXWriter_Release(writer); free_bstrs(); } + + +static void write_to_file(const char *name, const char *data) +{ + DWORD written; + HANDLE hfile; + BOOL ret; + + hfile = CreateFileA(name, GENERIC_WRITE|GENERIC_READ, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL ); + ok(hfile != INVALID_HANDLE_VALUE, "failed to create test file: %s\n", name); + + ret = WriteFile(hfile, data, strlen(data), &written, NULL); + ok(ret, "WriteFile failed: %s, %d\n", name, GetLastError()); + + CloseHandle(hfile); +} + +static void begin_writing_to_domdoc(ISAXContentHandler *content, IXMLDOMDocument *domdoc) +{ + HRESULT hr; + IXMLDOMElement *document_element; + BSTR bstr; + + document_element = NULL; + hr = IXMLDOMDocument_get_documentElement(domdoc, &document_element); + ok(SUCCEEDED(hr), "Unexpected hr %#x.\n", hr); + if (document_element != NULL) { + IXMLDOMDocument_removeChild(domdoc, (IXMLDOMNode*)document_element, NULL); + IXMLDOMElement_Release(document_element); + } + + hr = ISAXContentHandler_startDocument(content); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + + hr = IXMLDOMDocument_get_documentElement(domdoc, &document_element); + ok(hr == S_FALSE, "Unexpected hr %#x.\n", hr); + + hr = ISAXContentHandler_startElement(content, L"", 0, L"", 0, L"Accounts", 8, NULL); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + + document_element = NULL; + hr = IXMLDOMDocument_get_documentElement(domdoc, &document_element); + todo_wine ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + + if (document_element) { + hr = IXMLDOMElement_get_tagName(document_element, &bstr); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + ok(!lstrcmpW(bstr, L"Accounts"), "Incorrect tag name: %s.\n", wine_dbgstr_w(bstr)); + SysFreeString(bstr); + + IXMLDOMElement_Release(document_element); + } +} + +static void check_domdoc_lock_broken(ISAXContentHandler *content, IXMLDOMDocument *domdoc) +{ + HRESULT hr; + IXMLDOMElement *element; + + /* After lock is broken, e.g. createElement returns S_OK. */ + hr = IXMLDOMDocument_createElement(domdoc, _bstr_("SomeTagName"), &element); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + IXMLDOMElement_Release(element); + + /* However, mxwriter still behaves as if it is writing to the document. */ + hr = ISAXContentHandler_startElement(content, L"", 0, L"", 0, L"BankAccount", 11, NULL); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + + hr = ISAXContentHandler_endElement(content, L"", 0, L"", 0, L"BankAccount", 11); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + + /* "mistake" endDocument before endElement(..., "Accounts") returns E_FAIL. */ + hr = ISAXContentHandler_endDocument(content); + todo_wine ok(hr == E_FAIL, "Unexpected hr %#x.\n", hr); +} + +static void test_mxwriter_domdoc_break_lock(void) +{ + HRESULT hr; + VARIANT variant; + VARIANT_BOOL variant_bool; + BSTR tag_name; + IMXWriter *writer; + ISAXContentHandler *content; + IXMLDOMDocument *domdoc; + IXMLDOMElement *element; + char path[MAX_PATH]; + static const char xml_string[] = ""; + + hr = CoCreateInstance(&CLSID_MXXMLWriter60, NULL, CLSCTX_INPROC_SERVER, &IID_IMXWriter, (void**)&writer); + ok(hr == S_OK, "Failed to create a writer, hr %#x.\n", hr); + + hr = IMXWriter_QueryInterface(writer, &IID_ISAXContentHandler, (void**)&content); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + + hr = CoCreateInstance(&CLSID_DOMDocument60, NULL, CLSCTX_INPROC_SERVER, &IID_IXMLDOMDocument, (void **)&domdoc); + ok(hr == S_OK, "Failed to create a document, hr %#x.\n", hr); + + V_VT(&variant) = VT_DISPATCH; + V_DISPATCH(&variant) = (IDispatch *)domdoc; + + hr = IMXWriter_put_output(writer, variant); + todo_wine ok(hr == S_OK, "Failed to set writer output, hr %#x.\n", hr); + + + /* abort() cancels lock, and deletes created document node. */ + + begin_writing_to_domdoc(content, domdoc); + + hr = IXMLDOMDocument_abort(domdoc); + todo_wine ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + + check_domdoc_lock_broken(content, domdoc); + + hr = IXMLDOMDocument_get_documentElement(domdoc, &element); + ok(hr == S_FALSE, "Unexpected hr %#x.\n", hr); + + + /* load() breaks lock, and replaces created document node with + loaded content. */ + + begin_writing_to_domdoc(content, domdoc); + + GetTempPathA(MAX_PATH, path); + strcat(path, "winetest.xml"); + write_to_file(path, xml_string); + V_VT(&variant) = VT_BSTR; + V_BSTR(&variant) = _bstr_(path); + hr = IXMLDOMDocument_load(domdoc, variant, &variant_bool); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + ok(variant_bool == VARIANT_TRUE, "Got %d, expected %d.\n", variant_bool, VARIANT_TRUE); + + check_domdoc_lock_broken(content, domdoc); + + hr = IXMLDOMDocument_get_documentElement(domdoc, &element); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + + hr = IXMLDOMElement_get_tagName(element, &tag_name); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + ok(!lstrcmpW(tag_name, L"tag"), "Incorrect tag name: %s.\n", wine_dbgstr_w(tag_name)); + SysFreeString(tag_name); + IXMLDOMElement_Release(element); + + + /* loadXML() like load(). */ + + begin_writing_to_domdoc(content, domdoc); + + hr = IXMLDOMDocument_loadXML(domdoc, _bstr_(xml_string), &variant_bool); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + ok(variant_bool == VARIANT_TRUE, "Got %d, expected %d.\n", variant_bool, VARIANT_TRUE); + + check_domdoc_lock_broken(content, domdoc); + + hr = IXMLDOMDocument_get_documentElement(domdoc, &element); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + + hr = IXMLDOMElement_get_tagName(element, &tag_name); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + ok(!lstrcmpW(tag_name, L"tag"), "Incorrect tag name: %s.\n", wine_dbgstr_w(tag_name)); + SysFreeString(tag_name); + IXMLDOMElement_Release(element); + + + IXMLDOMDocument_Release(domdoc); + ISAXContentHandler_Release(content); + IMXWriter_Release(writer); +} + static void test_mxwriter_domdoc(void) { ISAXContentHandler *content; @@ -7074,6 +7243,7 @@ START_TEST(saxreader) test_mxwriter_flush(); test_mxwriter_stream(); test_mxwriter_domdoc_startDocument_disables_domdoc_methods(); + test_mxwriter_domdoc_break_lock(); test_mxwriter_domdoc(); test_mxwriter_encoding(); test_mxwriter_dispex(); -- 2.26.2