Jacek Caban (@jacek) commented about dlls/kernelbase/path.c:
{ INT ih; WCHAR buf[5] = L"0x"; + memcpy(buf + 2, src + 1, 2*sizeof(WCHAR)); buf[4] = 0; StrToIntExW(buf, STIF_SUPPORT_HEX, &ih); - next = (WCHAR) ih; src += 2; /* Advance to end of escape */ + + if (flags & URL_UNESCAPE_AS_UTF8) + { + utf8_buf[utf8_len++] = ih; + utf16_len = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, utf8_buf, utf8_len, NULL, 0); + if (!utf16_len) + continue;
This doesn't seem reliable. For example, if there is non-escaped char between escaped multi-byte values, you will end up combining characters surrounding non-escaped one. See JSGlobal_decodeURI for an example how it can be handled. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/585#note_5938