mirror of
https://github.com/mirkobrombin/raven.git
synced 2026-10-26 21:17:40 +00:00
83 lines
3.5 KiB
C
83 lines
3.5 KiB
C
#define WIN32_LEAN_AND_MEAN
|
|
#include <windows.h>
|
|
#include <stdint.h>
|
|
#ifdef CONVERSION_DUMP
|
|
#include <stdio.h>
|
|
#else
|
|
#include "multibyte_reference.h"
|
|
#endif
|
|
|
|
static uint64_t digest=0xcbf29ce484222325ULL;
|
|
static unsigned calls;
|
|
__declspec(dllexport) uint64_t conversion_rows[900][3];
|
|
|
|
static void add(uint32_t value)
|
|
{
|
|
for (unsigned i=0;i<4;++i) { digest^=(BYTE)(value>>(i*8));digest*=0x100000001b3ULL; }
|
|
}
|
|
|
|
static void convert(UINT code_page,DWORD flags,const char *input,int length,int capacity)
|
|
{
|
|
WCHAR output[520];for(unsigned i=0;i<520;++i)output[i]=0x7777;
|
|
SetLastError(71);int result=MultiByteToWideChar(code_page,flags,input,length,output,capacity);DWORD error=GetLastError();
|
|
add(result);add(error);uint64_t row=0xcbf29ce484222325ULL;
|
|
for(unsigned i=0;i<520;++i) { add(output[i]);for(unsigned j=0;j<4;++j) { row^=(BYTE)((uint32_t)output[i]>>(j*8));row*=0x100000001b3ULL; } }
|
|
conversion_rows[calls][0]=(uint32_t)result;conversion_rows[calls][1]=error;conversion_rows[calls][2]=row;
|
|
#ifdef CONVERSION_DUMP
|
|
printf("row=%u result=%d error=%lu digest=%016llx\n",calls,result,error,(unsigned long long)row);
|
|
#endif
|
|
++calls;
|
|
}
|
|
|
|
static void scenarios(void)
|
|
{
|
|
char bytes[256];for(unsigned i=0;i<256;++i)bytes[i]=(char)i;
|
|
const UINT pages[]={CP_ACP,CP_THREAD_ACP,1252};
|
|
for(unsigned page=0;page<3;++page)
|
|
for(DWORD flags=0;flags<16;++flags) {
|
|
convert(pages[page],flags,bytes,256,0);
|
|
convert(pages[page],flags,bytes,256,520);
|
|
convert(pages[page],flags,bytes,256,1);
|
|
convert(pages[page],flags,bytes,256,255);
|
|
}
|
|
const char *vectors[]={"A","\xc2\xa2","\xe4\xb8\xad","\xf0\x9f\x99\x82","a\xf0\x9f\x99\x82","\xf0\x9f\x99\x82" "a",
|
|
"\xc0\xaf","a\xc0\xaf","\xe1\x80","\xe1\x80" "a","\xed\xa0\x80","\xe0\x80\x80","\xf4\x90\x80\x80","\xf5\x80\x80\x80","\x80",""};
|
|
for(unsigned i=0;i<sizeof(vectors)/sizeof(vectors[0]);++i)
|
|
for(DWORD flags=0;flags<=8;flags+=8)
|
|
for(int capacity=0;capacity<=8;++capacity) {
|
|
int length=0;while(vectors[i][length])++length;
|
|
convert(CP_UTF8,flags,vectors[i],-1,capacity);
|
|
convert(CP_UTF8,flags,vectors[i],length,capacity);
|
|
}
|
|
const int lengths[]={0,-1,-2,-99,1,2,3};
|
|
for(DWORD flags=0;flags<32;++flags) {
|
|
convert(CP_UTF8,flags,"\xc3\xa9",2,8);
|
|
convert(CP_UTF8,flags,"\xc3\xa9",2,0);
|
|
}
|
|
for(unsigned i=0;i<sizeof(lengths)/sizeof(lengths[0]);++i)convert(1252,0,"ab",lengths[i],8);
|
|
convert(1252,0,NULL,1,8);convert(1252,0,"a",1,-1);convert(CP_UTF8,1,"a",1,8);convert(1252,16,"a",1,8);
|
|
SetLastError(71);add(MultiByteToWideChar(1252,0,"a",1,NULL,1));add(GetLastError());++calls;
|
|
SetLastError(71);add(MultiByteToWideChar(1252,0,"a",1,(WCHAR *)(UINT_PTR)0x12345678,0));add(GetLastError());++calls;
|
|
WCHAR same[8]={0x6261,0};SetLastError(71);add(MultiByteToWideChar(1252,0,(const char *)same,-1,same,0));add(GetLastError());++calls;
|
|
}
|
|
|
|
#ifdef CONVERSION_DUMP
|
|
int main(void)
|
|
{
|
|
scenarios();printf("calls=%u digest=%016llx\n",calls,(unsigned long long)digest);return 0;
|
|
}
|
|
#else
|
|
int raven_entry(void)
|
|
{
|
|
scenarios();if(calls!=conversion_calls || digest!=conversion_digest)return 1;
|
|
#ifdef CONVERSION_BOUNDARY
|
|
WCHAR same[8]={0x6261,0};
|
|
SetLastError(71);if(MultiByteToWideChar(1252,0,(const char *)same,-1,same,8) || GetLastError()!=ERROR_INVALID_PARAMETER || same[0]!=0x6261)return 4;
|
|
WCHAR output=0x7777;
|
|
SetLastError(71);if(MultiByteToWideChar(1,0,"a",1,&output,1) || GetLastError()!=ERROR_CALL_NOT_IMPLEMENTED || output!=0x7777)return 2;
|
|
SetLastError(71);if(MultiByteToWideChar(1252,0,"a",0x100001,&output,1) || GetLastError()!=ERROR_CALL_NOT_IMPLEMENTED || output!=0x7777)return 3;
|
|
#endif
|
|
return 0;
|
|
}
|
|
#endif
|