v3: Treat standalone == -1 and standalone == -2 same way when saving XML. v4: XML loading code always creates its own XML declaration, so always specify XML_SAVE_NO_DECL when asking libxml2 to generate XML.
Signed-off-by: Dmitry Timoshkov dmitry@baikal.ru --- dlls/msxml3/domdoc.c | 11 ++------ dlls/msxml3/tests/domdoc.c | 53 ++++++++++++++++++++++++++++++++++++-- 2 files changed, 53 insertions(+), 11 deletions(-)
diff --git a/dlls/msxml3/domdoc.c b/dlls/msxml3/domdoc.c index 80c32e9ba99..cf4f0433218 100644 --- a/dlls/msxml3/domdoc.c +++ b/dlls/msxml3/domdoc.c @@ -2534,7 +2534,6 @@ static HRESULT WINAPI domdoc_save( { domdoc *This = impl_from_IXMLDOMDocument3( iface ); xmlSaveCtxtPtr ctx = NULL; - xmlNodePtr xmldecl; HRESULT ret = S_OK;
TRACE("(%p)->(%s)\n", This, debugstr_variant(&destination)); @@ -2567,9 +2566,8 @@ static HRESULT WINAPI domdoc_save( ret = IUnknown_QueryInterface(pUnk, &IID_IStream, (void**)&stream); if(ret == S_OK) { - int options = get_doc(This)->standalone == -1 ? XML_SAVE_NO_DECL : 0; ctx = xmlSaveToIO(domdoc_stream_save_writecallback, - domdoc_stream_save_closecallback, stream, NULL, options); + domdoc_stream_save_closecallback, stream, NULL, XML_SAVE_NO_DECL);
if(!ctx) { @@ -2583,8 +2581,6 @@ static HRESULT WINAPI domdoc_save( case VT_BSTR: case VT_BSTR | VT_BYREF: { - int options = get_doc(This)->standalone == -1 ? XML_SAVE_NO_DECL : 0; - /* save with file path */ HANDLE handle = CreateFileW( (V_VT(&destination) & VT_BYREF)? *V_BSTRREF(&destination) : V_BSTR(&destination), GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL ); @@ -2594,9 +2590,8 @@ static HRESULT WINAPI domdoc_save( return E_FAIL; }
- /* disable top XML declaration */ ctx = xmlSaveToIO(domdoc_save_writecallback, domdoc_save_closecallback, - handle, NULL, options); + handle, NULL, XML_SAVE_NO_DECL); if (!ctx) { CloseHandle(handle); @@ -2610,9 +2605,7 @@ static HRESULT WINAPI domdoc_save( return S_FALSE; }
- xmldecl = xmldoc_unlink_xmldecl(get_doc(This)); if (xmlSaveDoc(ctx, get_doc(This)) == -1) ret = S_FALSE; - xmldoc_link_xmldecl(get_doc(This), xmldecl);
/* will release resources through close callback */ xmlSaveClose(ctx); diff --git a/dlls/msxml3/tests/domdoc.c b/dlls/msxml3/tests/domdoc.c index 5bc2fe1d5c3..6f8e2b44ed3 100644 --- a/dlls/msxml3/tests/domdoc.c +++ b/dlls/msxml3/tests/domdoc.c @@ -8524,6 +8524,9 @@ static void test_createProcessingInstruction(void) { static const WCHAR xml1[] = L"<?xml version=\"1.0\"?>\r\n<test/>\r\n"; static const char xml2[] = "<?xml version=\"1.0\" encoding=\"windows-1252\"?>\r\n<test/>\r\n"; + static const char xml2_wine[] = "<?xml version=\"1.0\" encoding=\"windows-1252\"?>\n<test/>\n"; + static const char xml3[] = "<?xml version=\"1.0\" standalone=\"yes\"?>\r\n<test/>\r\n"; + static const char xml3_wine[] = "<?xml version=\"1.0\" standalone=\"yes\"?>\n<test/>\n"; IXMLDOMProcessingInstruction *pi; IXMLDOMDocument *doc; IXMLDOMNode *node; @@ -8533,6 +8536,8 @@ static void test_createProcessingInstruction(void) VARIANT var; HRESULT hr; IStream *stream; + LARGE_INTEGER off; + VARIANT_BOOL b; HGLOBAL global; char *p;
@@ -8582,11 +8587,55 @@ todo_wine ok(hr == S_OK, "got 0x%08x\n", hr); p = GlobalLock(global); p[GlobalSize(global)] = 0; -todo_wine - ok(!strcmp(p, xml2), "got %s\n", wine_dbgstr_a(p)); + ok(!strcmp(p, xml2) || !strcmp(p, xml2_wine), "got %s\n", wine_dbgstr_a(p)); + GlobalUnlock(global); + + /* Verify the result after load+save */ + off.QuadPart = 0; + hr = IStream_Seek(stream, off, STREAM_SEEK_SET, NULL); + ok(hr == S_OK, "got 0x%08x\n", hr); + + hr = IXMLDOMDocument_load(doc, var, &b); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(b == VARIANT_TRUE, "got %d\n", b); + + off.QuadPart = 0; + hr = IStream_Seek(stream, off, STREAM_SEEK_SET, NULL); + ok(hr == S_OK, "got 0x%08x\n", hr); + + hr = IXMLDOMDocument_save(doc, var); + ok(hr == S_OK, "got 0x%08x\n", hr); + + hr = GetHGlobalFromStream(stream, &global); + ok(hr == S_OK, "got 0x%08x\n", hr); + p = GlobalLock(global); + p[GlobalSize(global)] = 0; + ok(!strcmp(p, xml2) || !strcmp(p, xml2_wine), "got %s\n", wine_dbgstr_a(p)); GlobalUnlock(global); + IStream_Release(stream);
+ hr = IXMLDOMDocument_loadXML(doc, _bstr_("<?xml version=\"1.0\" standalone=\"yes\"?>\r\n<test/>\r\n"), &b); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(b == VARIANT_TRUE, "got %d\n", b); + + hr = CreateStreamOnHGlobal(NULL, TRUE, &stream); + ok(hr == S_OK, "got 0x%08x\n", hr); + + V_VT(&var) = VT_UNKNOWN; + V_UNKNOWN(&var) = (IUnknown*)stream; + hr = IXMLDOMDocument_save(doc, var); + ok(hr == S_OK, "got 0x%08x\n", hr); + + hr = GetHGlobalFromStream(stream, &global); + ok(hr == S_OK, "got 0x%08x\n", hr); + + p = GlobalLock(global); + p[GlobalSize(global)] = 0; + ok(!strcmp(p, xml3) || !strcmp(p, xml3_wine), "got %s\n", wine_dbgstr_a(p)); + GlobalUnlock(global); + + IStream_Release(stream); IXMLDOMDocument_Release(doc); }
Dmitry Timoshkov dmitry@baikal.ru wrote:
v4: XML loading code always creates its own XML declaration, so always specify XML_SAVE_NO_DECL when asking libxml2 to generate XML.
Nikolay, could you please review the assigned patches in a more reasonable time frame? Thanks.