diff --git a/dlls/msxml3/mxwriter.c b/dlls/msxml3/mxwriter.c index 558582db9c0..3196374ad05 100644 --- a/dlls/msxml3/mxwriter.c +++ b/dlls/msxml3/mxwriter.c @@ -44,6 +44,7 @@ static const WCHAR spaceW[] = {' '}; static const WCHAR quotW[] = {'\"'}; static const WCHAR closetagW[] = {'>','\r','\n'}; static const WCHAR crlfW[] = {'\r','\n'}; +static const WCHAR entityW[] = {'<','!','E','N','T','I','T','Y',' '}; /* should be ordered as encoding names are sorted */ typedef enum @@ -1576,7 +1577,6 @@ static HRESULT WINAPI SAXDeclHandler_internalEntityDecl(ISAXDeclHandler *iface, const WCHAR *name, int n_name, const WCHAR *value, int n_value) { mxwriter *This = impl_from_ISAXDeclHandler( iface ); - static const WCHAR entityW[] = {'<','!','E','N','T','I','T','Y',' '}; TRACE("(%p)->(%s:%d %s:%d)\n", This, debugstr_wn(name, n_name), n_name, debugstr_wn(value, n_value), n_value); @@ -1601,10 +1601,39 @@ static HRESULT WINAPI SAXDeclHandler_externalEntityDecl(ISAXDeclHandler *iface, const WCHAR *name, int n_name, const WCHAR *publicId, int n_publicId, const WCHAR *systemId, int n_systemId) { + static const WCHAR publicW[] = {'P','U','B','L','I','C',' '}; + static const WCHAR systemW[] = {'S','Y','S','T','E','M',' '}; mxwriter *This = impl_from_ISAXDeclHandler( iface ); - FIXME("(%p)->(%s:%d %s:%d %s:%d): stub\n", This, debugstr_wn(name, n_name), n_name, + + TRACE("(%p)->(%s:%d %s:%d %s:%d)\n", This, debugstr_wn(name, n_name), n_name, debugstr_wn(publicId, n_publicId), n_publicId, debugstr_wn(systemId, n_systemId), n_systemId); - return E_NOTIMPL; + + if (!name) return E_INVALIDARG; + if (publicId && !systemId) return E_INVALIDARG; + if (!publicId && !systemId) return E_INVALIDARG; + + write_output_buffer(This->buffer, entityW, sizeof(entityW)/sizeof(WCHAR)); + if (n_name) { + write_output_buffer(This->buffer, name, n_name); + write_output_buffer(This->buffer, spaceW, sizeof(spaceW)/sizeof(WCHAR)); + } + + if (publicId) + { + write_output_buffer(This->buffer, publicW, sizeof(publicW)/sizeof(WCHAR)); + write_output_buffer_quoted(This->buffer, publicId, n_publicId); + write_output_buffer(This->buffer, spaceW, sizeof(spaceW)/sizeof(WCHAR)); + write_output_buffer_quoted(This->buffer, systemId, n_systemId); + } + else + { + write_output_buffer(This->buffer, systemW, sizeof(systemW)/sizeof(WCHAR)); + write_output_buffer_quoted(This->buffer, systemId, n_systemId); + } + + write_output_buffer(This->buffer, closetagW, sizeof(closetagW)/sizeof(WCHAR)); + + return S_OK; } static const ISAXDeclHandlerVtbl SAXDeclHandlerVtbl = { diff --git a/dlls/msxml3/tests/saxreader.c b/dlls/msxml3/tests/saxreader.c index 1eff7f60eda..5c7d0809fb5 100644 --- a/dlls/msxml3/tests/saxreader.c +++ b/dlls/msxml3/tests/saxreader.c @@ -4739,6 +4739,28 @@ static void test_mxwriter_dtd(void) ok(!lstrcmpW(_bstr_("\r\n"), V_BSTR(&dest)), "got wrong content %s\n", wine_dbgstr_w(V_BSTR(&dest))); VariantClear(&dest); + /* external entities */ + V_VT(&dest) = VT_EMPTY; + hr = IMXWriter_put_output(writer, dest); + ok(hr == S_OK, "got 0x%08x\n", hr); + + hr = ISAXDeclHandler_externalEntityDecl(decl, NULL, 0, NULL, 0, NULL, 0); + ok(hr == E_INVALIDARG, "got 0x%08x\n", hr); + + hr = ISAXDeclHandler_externalEntityDecl(decl, _bstr_("name"), -1, NULL, 0, NULL, 0); + ok(hr == E_INVALIDARG, "got 0x%08x\n", hr); + + hr = ISAXDeclHandler_externalEntityDecl(decl, _bstr_("name"), strlen("name"), _bstr_("pubid"), strlen("pubid"), + _bstr_("sysid"), strlen("sysid")); + ok(hr == S_OK, "got 0x%08x\n", hr); + + V_VT(&dest) = VT_EMPTY; + hr = IMXWriter_get_output(writer, &dest); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(V_VT(&dest) == VT_BSTR, "got %d\n", V_VT(&dest)); + ok(!lstrcmpW(_bstr_("\r\n"), V_BSTR(&dest)), "got wrong content %s\n", wine_dbgstr_w(V_BSTR(&dest))); + VariantClear(&dest); + ISAXContentHandler_Release(content); ISAXLexicalHandler_Release(lexical); ISAXDeclHandler_Release(decl);