Nikolay Sivov (@nsivov) commented about dlls/xmllite/writer.c:
+ case XmlWriterState_Initial: + return E_UNEXPECTED; + case XmlWriterState_InvalidEncoding: + return MX_E_ENCODING; + case XmlWriterState_ElemStarted: + writer_close_starttag(This); + break; + case XmlWriterState_DocClosed: + return WR_E_INVALIDACTION; + default: + ; + } + + codepoint = ((wchHigh - 0xd800) * 0x400) + (wchLow - 0xdc00) + 0x10000; + swprintf(bufW, ARRAY_SIZE(bufW), L"%X;", codepoint); + write_output_buffer(This->output, bufW, -1); What happens if you pass two surrogate halves to WriteString/WriteChars/WriteRawChars? Or even something like WriteChars(0xab, 1). It's possible they all share same hex escaping, and WriteSurrogateCharEntity() is not unique in that. Also, checking explicitly ranges here could as well be misplaced. I suspect WriteString() could validate that as well.
-- https://gitlab.winehq.org/wine/wine/-/merge_requests/1199#note_12656