ReactOS  0.4.14-dev-599-g2d4d3f5
codepage.c File Reference
#include <stdarg.h>
#include <stdio.h>
#include <limits.h>
#include "wine/test.h"
#include "windef.h"
#include "winbase.h"
#include "winnls.h"
Include dependency graph for codepage.c:

Go to the source code of this file.

Macros

#define LONGBUFLEN   100000
 

Functions

static void test_destination_buffer (void)
 
static void test_null_source (void)
 
static void test_negative_source_length (void)
 
static void test_negative_dest_length (void)
 
static void test_other_invalid_parameters (void)
 
static void test_overlapped_buffers (void)
 
static void test_string_conversion (LPBOOL bUsedDefaultChar)
 
static void test_utf7_encoding (void)
 
static void test_utf7_decoding (void)
 
static void test_undefined_byte_char (void)
 
static void test_threadcp (void)
 
static void test_dbcs_to_widechar (void)
 
 START_TEST (codepage)
 

Variables

static const char foobarA [] = "foobar"
 
static const WCHAR foobarW [] = {'f','o','o','b','a','r',0}
 

Macro Definition Documentation

◆ LONGBUFLEN

#define LONGBUFLEN   100000

Definition at line 144 of file codepage.c.

Function Documentation

◆ START_TEST()

START_TEST ( codepage  )

Definition at line 1293 of file codepage.c.

1294 {
1295  BOOL bUsedDefaultChar;
1296 
1298  test_null_source();
1303 
1304  /* WideCharToMultiByte has two code paths, test both here */
1306  test_string_conversion(&bUsedDefaultChar);
1307 
1310 
1312  test_threadcp();
1313 
1315 }
static void test_null_source(void)
Definition: codepage.c:96
static void test_string_conversion(LPBOOL bUsedDefaultChar)
Definition: codepage.c:325
static void test_destination_buffer(void)
Definition: codepage.c:34
static void test_utf7_decoding(void)
Definition: codepage.c:715
unsigned int BOOL
Definition: ntddk_ex.h:94
static void test_utf7_encoding(void)
Definition: codepage.c:472
static void test_threadcp(void)
Definition: codepage.c:1037
smooth NULL
Definition: ftsmooth.c:416
static void test_dbcs_to_widechar(void)
Definition: codepage.c:1178
static void test_overlapped_buffers(void)
Definition: codepage.c:310
static void test_undefined_byte_char(void)
Definition: codepage.c:987
static void test_negative_source_length(void)
Definition: codepage.c:116
static void test_negative_dest_length(void)
Definition: codepage.c:145
static void test_other_invalid_parameters(void)
Definition: codepage.c:203

◆ test_dbcs_to_widechar()

static void test_dbcs_to_widechar ( void  )
static

Definition at line 1178 of file codepage.c.

1179 {
1180  int i, count, count2;
1181  WCHAR wbuf[5];
1182  unsigned char buf[] = {0xbf, 0xb4, 0xc7, '\0', 'x'};
1183  static const DWORD flags[] = {
1185  MB_COMPOSITE,
1186 
1189 
1192 
1195  };
1196 
1197  for (i = 0; i < sizeof(flags)/sizeof(DWORD); ++i)
1198  {
1199  memset(wbuf, 0xff, sizeof(wbuf));
1200  count = MultiByteToWideChar(936, flags[i], (char*)&buf[0], 2, NULL, 0);
1201  count2 = MultiByteToWideChar(936, flags[i], (char*)&buf[0], 2, wbuf, count);
1202 
1203  ok(count == 1, "%04x: returned %d (expected 1)\n", flags[i], count);
1204  ok(count2 == 1, "%04x: returned %d (expected 1)\n", flags[i], count2);
1205  ok(wbuf[0] == 0x770b, "%04x: returned %04x (expected 770b)\n", flags[i], wbuf[0]);
1206  ok(wbuf[1] == 0xffff, "%04x: returned %04x (expected ffff)\n", flags[i], wbuf[1]);
1207  }
1208 
1209  for (i = 0; i < sizeof(flags)/sizeof(DWORD); ++i)
1210  {
1211  memset(wbuf, 0xff, sizeof(wbuf));
1212  count = MultiByteToWideChar(936, flags[i], (char*)&buf[0], 3, NULL, 0);
1213  SetLastError( 0xdeadbeef );
1214  count2 = MultiByteToWideChar(936, flags[i], (char*)&buf[0], 3, wbuf, count);
1215 
1216  if (flags[i] & MB_ERR_INVALID_CHARS)
1217  {
1218  ok(count == 0, "%04x: returned %d (expected 0)\n", flags[i], count);
1219  ok(count2 == 0, "%04x: returned %d (expected 0)\n", flags[i], count2);
1220  ok(GetLastError() == ERROR_NO_UNICODE_TRANSLATION, "%04x: returned %d (expected %d)\n",
1222  }
1223  else
1224  {
1225  ok(count == 2, "%04x: returned %d (expected 2)\n", flags[i], count);
1226  ok(count2 == 2, "%04x: returned %d (expected 2)\n", flags[i], count2);
1227  ok(wbuf[0] == 0x770b, "%04x: returned %04x (expected 770b)\n", flags[i], wbuf[0]);
1228  ok(wbuf[1] == 0x003f || broken(wbuf[1] == 0), /*windows xp*/
1229  "%04x: wrong wide char: %04x\n", flags[i], wbuf[1]);
1230  ok(wbuf[2] == 0xffff, "%04x: returned %04x (expected ffff)\n", flags[i], wbuf[2]);
1231  }
1232  }
1233 
1234  /* src ends with null character */
1235  for (i = 0; i < sizeof(flags)/sizeof(DWORD); ++i)
1236  {
1237  memset(wbuf, 0xff, sizeof(wbuf));
1238  count = MultiByteToWideChar(936, flags[i], (char*)&buf[0], 4, NULL, 0);
1239  SetLastError( 0xdeadbeef );
1240  count2 = MultiByteToWideChar(936, flags[i], (char*)&buf[0], 4, wbuf, count);
1241  ok(count == count2, "%04x: returned %d (expected %d)\n", flags[i], count2, count);
1242 
1243  if (flags[i] & MB_ERR_INVALID_CHARS)
1244  {
1245  ok(count == 0, "%04x: returned %d (expected 0)\n", flags[i], count);
1246  ok(GetLastError() == ERROR_NO_UNICODE_TRANSLATION, "%04x: returned %d (expected %d)\n",
1248  }
1249  else
1250  {
1251  WCHAR wbuf_ok[] = { 0x770b, 0x003f, '\0', 0xffff };
1252  WCHAR wbuf_broken[] = { 0x770b, '\0', 0xffff, 0xffff };
1253  ok(count == 3 || broken(count == 2 /*windows xp*/),
1254  "%04x: returned %d (expected 3)\n", flags[i], count);
1255  ok(!memcmp(wbuf, wbuf_ok, sizeof(wbuf_ok))
1256  || broken(!memcmp(wbuf, wbuf_broken, sizeof(wbuf_broken))),
1257  "%04x: returned %04x %04x %04x %04x (expected %04x %04x %04x %04x)\n",
1258  flags[i], wbuf[0], wbuf[1], wbuf[2], wbuf[3],
1259  wbuf_ok[0], wbuf_ok[1], wbuf_ok[2], wbuf_ok[3]);
1260  }
1261  }
1262 
1263  /* src has null character, but not ends with it */
1264  for (i = 0; i < sizeof(flags)/sizeof(DWORD); ++i)
1265  {
1266  memset(wbuf, 0xff, sizeof(wbuf));
1267  count = MultiByteToWideChar(936, flags[i], (char*)&buf[0], 5, NULL, 0);
1268  SetLastError( 0xdeadbeef );
1269  count2 = MultiByteToWideChar(936, flags[i], (char*)&buf[0], 5, wbuf, count);
1270  ok(count == count2, "%04x: returned %d (expected %d)\n", flags[i], count2, count);
1271 
1272  if (flags[i] & MB_ERR_INVALID_CHARS)
1273  {
1274  ok(count == 0, "%04x: returned %d (expected 0)\n", flags[i], count);
1275  ok(GetLastError() == ERROR_NO_UNICODE_TRANSLATION, "%04x: returned %d (expected %d)\n",
1277  }
1278  else
1279  {
1280  WCHAR wbuf_ok[] = { 0x770b, 0x003f, '\0', 'x', 0xffff };
1281  WCHAR wbuf_broken[] = { 0x770b, '\0', 'x', 0xffff, 0xffff };
1282  ok(count == 4 || broken(count == 3),
1283  "%04x: returned %d (expected 4)\n", flags[i], count);
1284  ok(!memcmp(wbuf, wbuf_ok, sizeof(wbuf_ok))
1285  || broken(!memcmp(wbuf, wbuf_broken, sizeof(wbuf_broken))),
1286  "%04x: returned %04x %04x %04x %04x %04x (expected %04x %04x %04x %04x %04x)\n",
1287  flags[i], wbuf[0], wbuf[1], wbuf[2], wbuf[3], wbuf[4],
1288  wbuf_ok[0], wbuf_ok[1], wbuf_ok[2], wbuf_ok[3], wbuf_ok[4]);
1289  }
1290  }
1291 }
#define MB_ERR_INVALID_CHARS
Definition: unicode.h:41
int memcmp(void *Buffer1, void *Buffer2, ACPI_SIZE Count)
Definition: utclib.c:112
#define MB_USEGLYPHCHARS
Definition: unicode.h:42
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
GLuint GLuint GLsizei count
Definition: gl.h:1545
#define MB_PRECOMPOSED
Definition: winnls.h:278
#define MB_COMPOSITE
Definition: unicode.h:40
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1059
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
smooth NULL
Definition: ftsmooth.c:416
__wchar_t WCHAR
Definition: xmlstorage.h:180
unsigned long DWORD
Definition: ntddk_ex.h:95
#define SetLastError(x)
Definition: compat.h:417
GLbitfield flags
Definition: glext.h:7161
#define ERROR_NO_UNICODE_TRANSLATION
Definition: winerror.h:649
#define broken(x)
Definition: _sntprintf.h:21
#define ok(value,...)
Definition: atltest.h:57
#define MultiByteToWideChar
Definition: compat.h:100
#define memset(x, y, z)
Definition: compat.h:39

Referenced by START_TEST().

◆ test_destination_buffer()

static void test_destination_buffer ( void  )
static

Definition at line 34 of file codepage.c.

35 {
36  LPSTR buffer;
37  INT maxsize;
38  INT needed;
39  INT len;
40 
41  SetLastError(0xdeadbeef);
42  needed = WideCharToMultiByte(CP_ACP, 0, foobarW, -1, NULL, 0, NULL, NULL);
43  ok( (needed > 0), "returned %d with %u (expected '> 0')\n",
44  needed, GetLastError());
45 
46  maxsize = needed*2;
47  buffer = HeapAlloc(GetProcessHeap(), 0, maxsize);
48  if (buffer == NULL) return;
49 
50  maxsize--;
51  memset(buffer, 'x', maxsize);
52  buffer[maxsize] = '\0';
53  SetLastError(0xdeadbeef);
54  len = WideCharToMultiByte(CP_ACP, 0, foobarW, -1, buffer, needed+1, NULL, NULL);
55  ok( (len > 0), "returned %d with %u and '%s' (expected '> 0')\n",
56  len, GetLastError(), buffer);
57 
58  memset(buffer, 'x', maxsize);
59  buffer[maxsize] = '\0';
60  SetLastError(0xdeadbeef);
61  len = WideCharToMultiByte(CP_ACP, 0, foobarW, -1, buffer, needed, NULL, NULL);
62  ok( (len > 0), "returned %d with %u and '%s' (expected '> 0')\n",
63  len, GetLastError(), buffer);
64 
65  memset(buffer, 'x', maxsize);
66  buffer[maxsize] = '\0';
67  SetLastError(0xdeadbeef);
68  len = WideCharToMultiByte(CP_ACP, 0, foobarW, -1, buffer, needed-1, NULL, NULL);
70  "returned %d with %u and '%s' (expected '0' with "
71  "ERROR_INSUFFICIENT_BUFFER)\n", len, GetLastError(), buffer);
72 
73  memset(buffer, 'x', maxsize);
74  buffer[maxsize] = '\0';
75  SetLastError(0xdeadbeef);
78  "returned %d with %u and '%s' (expected '0' with "
79  "ERROR_INSUFFICIENT_BUFFER)\n", len, GetLastError(), buffer);
80 
81  SetLastError(0xdeadbeef);
83  ok( (len > 0), "returned %d with %u (expected '> 0')\n",
84  len, GetLastError());
85 
86  SetLastError(0xdeadbeef);
87  len = WideCharToMultiByte(CP_ACP, 0, foobarW, -1, NULL, needed, NULL, NULL);
89  "returned %d with %u (expected '0' with "
90  "ERROR_INVALID_PARAMETER)\n", len, GetLastError());
91 
93 }
#define ERROR_INVALID_PARAMETER
Definition: compat.h:91
#define WideCharToMultiByte
Definition: compat.h:101
#define CP_ACP
Definition: compat.h:99
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1059
GLuint buffer
Definition: glext.h:5915
char * LPSTR
Definition: xmlstorage.h:182
int32_t INT
Definition: typedefs.h:56
smooth NULL
Definition: ftsmooth.c:416
#define GetProcessHeap()
Definition: compat.h:403
PVOID WINAPI HeapAlloc(HANDLE, DWORD, SIZE_T)
static const WCHAR foobarW[]
Definition: codepage.c:32
#define SetLastError(x)
Definition: compat.h:417
GLenum GLsizei len
Definition: glext.h:6722
#define ok(value,...)
Definition: atltest.h:57
#define memset(x, y, z)
Definition: compat.h:39
#define HeapFree(x, y, z)
Definition: compat.h:402
#define ERROR_INSUFFICIENT_BUFFER
Definition: dderror.h:10

Referenced by START_TEST().

◆ test_negative_dest_length()

static void test_negative_dest_length ( void  )
static

Definition at line 145 of file codepage.c.

146 {
147  int len, i;
148  static WCHAR bufW[LONGBUFLEN];
149  static char bufA[LONGBUFLEN];
150  static WCHAR originalW[LONGBUFLEN];
151  static char originalA[LONGBUFLEN];
152  DWORD theError;
153 
154  /* Test return on -1 dest length */
155  SetLastError( 0xdeadbeef );
156  memset(bufA,'x',sizeof(bufA));
157  len = WideCharToMultiByte(CP_ACP, 0, foobarW, -1, bufA, -1, NULL, NULL);
159  "WideCharToMultiByte(destlen -1): len=%d error=%x\n", len, GetLastError());
160 
161  SetLastError( 0xdeadbeef );
162  memset(bufW,'x',sizeof(bufW));
163  len = MultiByteToWideChar(CP_ACP, 0, foobarA, -1, bufW, -1);
165  "MultiByteToWideChar(destlen -1): len=%d error=%x\n", len, GetLastError());
166 
167  /* Test return on -1000 dest length */
168  SetLastError( 0xdeadbeef );
169  memset(bufA,'x',sizeof(bufA));
170  len = WideCharToMultiByte(CP_ACP, 0, foobarW, -1, bufA, -1000, NULL, NULL);
172  "WideCharToMultiByte(destlen -1000): len=%d error=%x\n", len, GetLastError());
173 
174  SetLastError( 0xdeadbeef );
175  memset(bufW,'x',sizeof(bufW));
176  len = MultiByteToWideChar(CP_ACP, 0, foobarA, -1000, bufW, -1);
178  "MultiByteToWideChar(destlen -1000): len=%d error=%x\n", len, GetLastError());
179 
180  /* Test return on INT_MAX dest length */
181  SetLastError( 0xdeadbeef );
182  memset(bufA,'x',sizeof(bufA));
183  len = WideCharToMultiByte(CP_ACP, 0, foobarW, -1, bufA, INT_MAX, NULL, NULL);
184  ok(len == 7 && !lstrcmpA(bufA, "foobar") && GetLastError() == 0xdeadbeef,
185  "WideCharToMultiByte(destlen INT_MAX): len=%d error=%x\n", len, GetLastError());
186 
187  /* Test return on INT_MAX dest length and very long input */
188  SetLastError( 0xdeadbeef );
189  memset(bufA,'x',sizeof(bufA));
190  for (i=0; i < LONGBUFLEN - 1; i++) {
191  originalW[i] = 'Q';
192  originalA[i] = 'Q';
193  }
194  originalW[LONGBUFLEN-1] = 0;
195  originalA[LONGBUFLEN-1] = 0;
196  len = WideCharToMultiByte(CP_ACP, 0, originalW, -1, bufA, INT_MAX, NULL, NULL);
197  theError = GetLastError();
198  ok(len == LONGBUFLEN && !lstrcmpA(bufA, originalA) && theError == 0xdeadbeef,
199  "WideCharToMultiByte(srclen %d, destlen INT_MAX): len %d error=%x\n", LONGBUFLEN, len, theError);
200 
201 }
#define ERROR_INVALID_PARAMETER
Definition: compat.h:91
#define WideCharToMultiByte
Definition: compat.h:101
#define INT_MAX
Definition: limits.h:40
#define CP_ACP
Definition: compat.h:99
int WINAPI lstrcmpA(LPCSTR lpString1, LPCSTR lpString2)
Definition: lstring.c:18
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1059
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
static const char foobarA[]
Definition: codepage.c:31
smooth NULL
Definition: ftsmooth.c:416
#define LONGBUFLEN
Definition: codepage.c:144
__wchar_t WCHAR
Definition: xmlstorage.h:180
static const WCHAR foobarW[]
Definition: codepage.c:32
unsigned long DWORD
Definition: ntddk_ex.h:95
#define SetLastError(x)
Definition: compat.h:417
GLenum GLsizei len
Definition: glext.h:6722
#define ok(value,...)
Definition: atltest.h:57
#define MultiByteToWideChar
Definition: compat.h:100
#define memset(x, y, z)
Definition: compat.h:39

Referenced by START_TEST().

◆ test_negative_source_length()

static void test_negative_source_length ( void  )
static

Definition at line 116 of file codepage.c.

117 {
118  int len;
119  char buf[10];
120  WCHAR bufW[10];
121 
122  /* Test, whether any negative source length works as strlen() + 1 */
123  SetLastError( 0xdeadbeef );
124  memset(buf,'x',sizeof(buf));
125  len = WideCharToMultiByte(CP_ACP, 0, foobarW, -2002, buf, 10, NULL, NULL);
126  ok(len == 7 && GetLastError() == 0xdeadbeef,
127  "WideCharToMultiByte(-2002): len=%d error=%u\n", len, GetLastError());
128  ok(!lstrcmpA(buf, "foobar"),
129  "WideCharToMultiByte(-2002): expected \"foobar\" got \"%s\"\n", buf);
130 
131  SetLastError( 0xdeadbeef );
132  memset(bufW,'x',sizeof(bufW));
133  len = MultiByteToWideChar(CP_ACP, 0, "foobar", -2002, bufW, 10);
134  ok(len == 7 && !lstrcmpW(bufW, foobarW) && GetLastError() == 0xdeadbeef,
135  "MultiByteToWideChar(-2002): len=%d error=%u\n", len, GetLastError());
136 
137  SetLastError(0xdeadbeef);
138  memset(bufW, 'x', sizeof(bufW));
139  len = MultiByteToWideChar(CP_ACP, 0, "foobar", -1, bufW, 6);
141  "MultiByteToWideChar(-1): len=%d error=%u\n", len, GetLastError());
142 }
#define WideCharToMultiByte
Definition: compat.h:101
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
#define CP_ACP
Definition: compat.h:99
int WINAPI lstrcmpW(LPCWSTR lpString1, LPCWSTR lpString2)
Definition: lstring.c:170
int WINAPI lstrcmpA(LPCSTR lpString1, LPCSTR lpString2)
Definition: lstring.c:18
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1059
smooth NULL
Definition: ftsmooth.c:416
__wchar_t WCHAR
Definition: xmlstorage.h:180
static const WCHAR foobarW[]
Definition: codepage.c:32
#define SetLastError(x)
Definition: compat.h:417
GLenum GLsizei len
Definition: glext.h:6722
#define ok(value,...)
Definition: atltest.h:57
#define MultiByteToWideChar
Definition: compat.h:100
#define memset(x, y, z)
Definition: compat.h:39
#define ERROR_INSUFFICIENT_BUFFER
Definition: dderror.h:10

Referenced by START_TEST().

◆ test_null_source()

static void test_null_source ( void  )
static

Definition at line 96 of file codepage.c.

97 {
98  int len;
99  DWORD GLE;
100 
101  SetLastError(0);
102  len = WideCharToMultiByte(CP_ACP, 0, NULL, 0, NULL, 0, NULL, NULL);
103  GLE = GetLastError();
105  "WideCharToMultiByte returned %d with GLE=%u (expected 0 with ERROR_INVALID_PARAMETER)\n",
106  len, GLE);
107 
108  SetLastError(0);
109  len = WideCharToMultiByte(CP_ACP, 0, NULL, -1, NULL, 0, NULL, NULL);
110  GLE = GetLastError();
112  "WideCharToMultiByte returned %d with GLE=%u (expected 0 with ERROR_INVALID_PARAMETER)\n",
113  len, GLE);
114 }
#define ERROR_INVALID_PARAMETER
Definition: compat.h:91
#define WideCharToMultiByte
Definition: compat.h:101
#define CP_ACP
Definition: compat.h:99
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1059
smooth NULL
Definition: ftsmooth.c:416
unsigned long DWORD
Definition: ntddk_ex.h:95
#define SetLastError(x)
Definition: compat.h:417
GLenum GLsizei len
Definition: glext.h:6722
#define ok(value,...)
Definition: atltest.h:57
static DWORD GLE
Definition: registry.c:38

Referenced by START_TEST().

◆ test_other_invalid_parameters()

static void test_other_invalid_parameters ( void  )
static

Definition at line 203 of file codepage.c.

204 {
205  char c_string[] = "Hello World";
206  size_t c_string_len = sizeof(c_string);
207  WCHAR w_string[] = {'H','e','l','l','o',' ','W','o','r','l','d',0};
208  size_t w_string_len = sizeof(w_string) / sizeof(WCHAR);
209  BOOL used;
210  INT len;
211 
212  /* Unrecognized flag => ERROR_INVALID_FLAGS */
213  SetLastError(0xdeadbeef);
214  len = WideCharToMultiByte(CP_ACP, 0x100, w_string, -1, c_string, c_string_len, NULL, NULL);
215  ok(len == 0 && GetLastError() == ERROR_INVALID_FLAGS, "len=%d error=%x\n", len, GetLastError());
216 
217  SetLastError(0xdeadbeef);
218  len = WideCharToMultiByte(CP_ACP, 0x800, w_string, -1, c_string, c_string_len, NULL, NULL);
219  ok(len == 0 && GetLastError() == ERROR_INVALID_FLAGS, "len=%d error=%x\n", len, GetLastError());
220 
221  SetLastError(0xdeadbeef);
222  len = MultiByteToWideChar(CP_ACP, 0x10, c_string, -1, w_string, w_string_len);
223  ok(len == 0 && GetLastError() == ERROR_INVALID_FLAGS, "len=%d error=%x\n", len, GetLastError());
224 
225 
226  /* Unrecognized flag and invalid codepage => ERROR_INVALID_PARAMETER */
227  SetLastError(0xdeadbeef);
228  len = WideCharToMultiByte(0xdeadbeef, 0x100, w_string, w_string_len, c_string, c_string_len, NULL, NULL);
229  ok(len == 0 && GetLastError() == ERROR_INVALID_PARAMETER, "len=%d error=%x\n", len, GetLastError());
230 
231  SetLastError(0xdeadbeef);
232  len = MultiByteToWideChar(0xdeadbeef, 0x10, c_string, c_string_len, w_string, w_string_len);
233  ok(len == 0 && GetLastError() == ERROR_INVALID_PARAMETER, "len=%d error=%x\n", len, GetLastError());
234 
235 
236  /* Unrecognized flag and src is NULL => ERROR_INVALID_PARAMETER */
237  SetLastError(0xdeadbeef);
238  len = WideCharToMultiByte(CP_ACP, 0x100, NULL, -1, c_string, c_string_len, NULL, NULL);
239  ok(len == 0 && GetLastError() == ERROR_INVALID_PARAMETER, "len=%d error=%x\n", len, GetLastError());
240 
241  SetLastError(0xdeadbeef);
242  len = MultiByteToWideChar(CP_ACP, 0x10, NULL, -1, w_string, w_string_len);
243  ok(len == 0 && GetLastError() == ERROR_INVALID_PARAMETER, "len=%d error=%x\n", len, GetLastError());
244 
245 
246  /* srclen=0 => ERROR_INVALID_PARAMETER */
247  SetLastError(0xdeadbeef);
248  len = WideCharToMultiByte(CP_ACP, 0, w_string, 0, c_string, c_string_len, NULL, NULL);
249  ok(len == 0 && GetLastError() == ERROR_INVALID_PARAMETER, "len=%d error=%x\n", len, GetLastError());
250 
251  SetLastError(0xdeadbeef);
252  len = MultiByteToWideChar(CP_ACP, 0, c_string, 0, w_string, w_string_len);
253  ok(len == 0 && GetLastError() == ERROR_INVALID_PARAMETER, "len=%d error=%x\n", len, GetLastError());
254 
255 
256  /* dst=NULL but dstlen not 0 => ERROR_INVALID_PARAMETER */
257  SetLastError(0xdeadbeef);
258  len = WideCharToMultiByte(CP_ACP, 0, w_string, w_string_len, NULL, c_string_len, NULL, NULL);
259  ok(len == 0 && GetLastError() == ERROR_INVALID_PARAMETER, "len=%d error=%x\n", len, GetLastError());
260 
261  SetLastError(0xdeadbeef);
262  len = MultiByteToWideChar(CP_ACP, 0, c_string, c_string_len, NULL, w_string_len);
263  ok(len == 0 && GetLastError() == ERROR_INVALID_PARAMETER, "len=%d error=%x\n", len, GetLastError());
264 
265 
266  /* CP_UTF7, CP_UTF8, or CP_SYMBOL and defchar not NULL => ERROR_INVALID_PARAMETER */
267  /* CP_SYMBOL's behavior here is undocumented */
268  SetLastError(0xdeadbeef);
269  len = WideCharToMultiByte(CP_UTF7, 0, w_string, w_string_len, c_string, c_string_len, c_string, NULL);
270  ok(len == 0 && GetLastError() == ERROR_INVALID_PARAMETER, "len=%d error=%x\n", len, GetLastError());
271 
272  SetLastError(0xdeadbeef);
273  len = WideCharToMultiByte(CP_UTF8, 0, w_string, w_string_len, c_string, c_string_len, c_string, NULL);
274  ok(len == 0 && GetLastError() == ERROR_INVALID_PARAMETER, "len=%d error=%x\n", len, GetLastError());
275 
276  SetLastError(0xdeadbeef);
277  len = WideCharToMultiByte(CP_SYMBOL, 0, w_string, w_string_len, c_string, c_string_len, c_string, NULL);
278  ok(len == 0 && GetLastError() == ERROR_INVALID_PARAMETER, "len=%d error=%x\n", len, GetLastError());
279 
280 
281  /* CP_UTF7, CP_UTF8, or CP_SYMBOL and used not NULL => ERROR_INVALID_PARAMETER */
282  /* CP_SYMBOL's behavior here is undocumented */
283  SetLastError(0xdeadbeef);
284  len = WideCharToMultiByte(CP_UTF7, 0, w_string, w_string_len, c_string, c_string_len, NULL, &used);
285  ok(len == 0 && GetLastError() == ERROR_INVALID_PARAMETER, "len=%d error=%x\n", len, GetLastError());
286 
287  SetLastError(0xdeadbeef);
288  len = WideCharToMultiByte(CP_UTF8, 0, w_string, w_string_len, c_string, c_string_len, NULL, &used);
289  ok(len == 0 && GetLastError() == ERROR_INVALID_PARAMETER, "len=%d error=%x\n", len, GetLastError());
290 
291  SetLastError(0xdeadbeef);
292  len = WideCharToMultiByte(CP_SYMBOL, 0, w_string, w_string_len, c_string, c_string_len, NULL, &used);
293  ok(len == 0 && GetLastError() == ERROR_INVALID_PARAMETER, "len=%d error=%x\n", len, GetLastError());
294 
295 
296  /* CP_UTF7, flags not 0 and used not NULL => ERROR_INVALID_PARAMETER */
297  /* (tests precedence of ERROR_INVALID_PARAMETER over ERROR_INVALID_FLAGS) */
298  /* The same test with CP_SYMBOL instead of CP_UTF7 gives ERROR_INVALID_FLAGS
299  instead except on Windows NT4 */
300  SetLastError(0xdeadbeef);
301  len = WideCharToMultiByte(CP_UTF7, 1, w_string, w_string_len, c_string, c_string_len, NULL, &used);
302  ok(len == 0 && GetLastError() == ERROR_INVALID_PARAMETER, "len=%d error=%x\n", len, GetLastError());
303 
304  /* CP_UTF8, unrecognized flag and used not NULL => ERROR_INVALID_PARAMETER */
305  SetLastError(0xdeadbeef);
306  len = WideCharToMultiByte(CP_UTF8, 0x100, w_string, w_string_len, c_string, c_string_len, NULL, &used);
307  ok(len == 0 && GetLastError() == ERROR_INVALID_PARAMETER, "len=%d error=%x\n", len, GetLastError());
308 }
#define ERROR_INVALID_PARAMETER
Definition: compat.h:91
#define WideCharToMultiByte
Definition: compat.h:101
#define CP_UTF7
Definition: winnls.h:232
#define CP_ACP
Definition: compat.h:99
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1059
#define CP_SYMBOL
Definition: winnls.h:231
int32_t INT
Definition: typedefs.h:56
#define CP_UTF8
Definition: nls.h:20
unsigned int BOOL
Definition: ntddk_ex.h:94
smooth NULL
Definition: ftsmooth.c:416
c used
Definition: write.c:2877
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define SetLastError(x)
Definition: compat.h:417
GLenum GLsizei len
Definition: glext.h:6722
#define ok(value,...)
Definition: atltest.h:57
#define MultiByteToWideChar
Definition: compat.h:100
#define ERROR_INVALID_FLAGS
Definition: winerror.h:583

Referenced by START_TEST().

◆ test_overlapped_buffers()

static void test_overlapped_buffers ( void  )
static

Definition at line 310 of file codepage.c.

311 {
312  static const WCHAR strW[] = {'j','u','s','t',' ','a',' ','t','e','s','t',0};
313  static const char strA[] = "just a test";
314  char buf[256];
315  int ret;
316 
317  SetLastError(0xdeadbeef);
318  memcpy(buf + 1, strW, sizeof(strW));
319  ret = WideCharToMultiByte(CP_ACP, 0, (WCHAR *)(buf + 1), -1, buf, sizeof(buf), NULL, NULL);
320  ok(ret == sizeof(strA), "unexpected ret %d\n", ret);
321  ok(!memcmp(buf, strA, sizeof(strA)), "conversion failed: %s\n", buf);
322  ok(GetLastError() == 0xdeadbeef, "GetLastError() is %u\n", GetLastError());
323 }
char strA[12]
Definition: clipboard.c:2028
int memcmp(void *Buffer1, void *Buffer2, ACPI_SIZE Count)
Definition: utclib.c:112
#define WideCharToMultiByte
Definition: compat.h:101
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
#define CP_ACP
Definition: compat.h:99
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1059
WCHAR strW[12]
Definition: clipboard.c:2029
smooth NULL
Definition: ftsmooth.c:416
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define SetLastError(x)
Definition: compat.h:417
int ret
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
#define ok(value,...)
Definition: atltest.h:57

Referenced by START_TEST().

◆ test_string_conversion()

static void test_string_conversion ( LPBOOL  bUsedDefaultChar)
static

Definition at line 325 of file codepage.c.

326 {
327  char mbc;
328  char mbs[15];
329  int ret;
330  WCHAR wc1 = 228; /* Western Windows-1252 character */
331  WCHAR wc2 = 1088; /* Russian Windows-1251 character not displayable for Windows-1252 */
332  static const WCHAR wcs[] = {'T', 'h', 1088, 'i', 0}; /* String with ASCII characters and a Russian character */
333  static const WCHAR dbwcs[] = {28953, 25152, 0}; /* String with Chinese (codepage 950) characters */
334  static const WCHAR dbwcs2[] = {0x7bb8, 0x3d, 0xc813, 0xac00, 0xb77d, 0};
335  static const char default_char[] = {0xa3, 0xbf, 0};
336 
337  SetLastError(0xdeadbeef);
338  ret = WideCharToMultiByte(1252, 0, &wc1, 1, &mbc, 1, NULL, bUsedDefaultChar);
339  ok(ret == 1, "ret is %d\n", ret);
340  ok(mbc == '\xe4', "mbc is %d\n", mbc);
341  if(bUsedDefaultChar) ok(*bUsedDefaultChar == FALSE, "bUsedDefaultChar is %d\n", *bUsedDefaultChar);
342  ok(GetLastError() == 0xdeadbeef, "GetLastError() is %u\n", GetLastError());
343 
344  SetLastError(0xdeadbeef);
345  ret = WideCharToMultiByte(1252, 0, &wc2, 1, &mbc, 1, NULL, bUsedDefaultChar);
346  ok(ret == 1, "ret is %d\n", ret);
347  ok(mbc == 63, "mbc is %d\n", mbc);
348  if(bUsedDefaultChar) ok(*bUsedDefaultChar == TRUE, "bUsedDefaultChar is %d\n", *bUsedDefaultChar);
349  ok(GetLastError() == 0xdeadbeef, "GetLastError() is %u\n", GetLastError());
350 
351  if (IsValidCodePage(1251))
352  {
353  SetLastError(0xdeadbeef);
354  ret = WideCharToMultiByte(1251, 0, &wc2, 1, &mbc, 1, NULL, bUsedDefaultChar);
355  ok(ret == 1, "ret is %d\n", ret);
356  ok(mbc == '\xf0', "mbc is %d\n", mbc);
357  if(bUsedDefaultChar) ok(*bUsedDefaultChar == FALSE, "bUsedDefaultChar is %d\n", *bUsedDefaultChar);
358  ok(GetLastError() == 0xdeadbeef ||
359  broken(GetLastError() == 0), /* win95 */
360  "GetLastError() is %u\n", GetLastError());
361 
362  SetLastError(0xdeadbeef);
363  ret = WideCharToMultiByte(1251, 0, &wc1, 1, &mbc, 1, NULL, bUsedDefaultChar);
364  ok(ret == 1, "ret is %d\n", ret);
365  ok(mbc == 97, "mbc is %d\n", mbc);
366  if(bUsedDefaultChar) ok(*bUsedDefaultChar == FALSE, "bUsedDefaultChar is %d\n", *bUsedDefaultChar);
367  ok(GetLastError() == 0xdeadbeef, "GetLastError() is %u\n", GetLastError());
368  }
369  else
370  skip("Codepage 1251 not available\n");
371 
372  /* This call triggers the last Win32 error */
373  SetLastError(0xdeadbeef);
374  ret = WideCharToMultiByte(1252, 0, wcs, -1, &mbc, 1, NULL, bUsedDefaultChar);
375  ok(ret == 0, "ret is %d\n", ret);
376  ok(mbc == 84, "mbc is %d\n", mbc);
377  if(bUsedDefaultChar) ok(*bUsedDefaultChar == FALSE, "bUsedDefaultChar is %d\n", *bUsedDefaultChar);
378  ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "GetLastError() is %u\n", GetLastError());
379 
380  SetLastError(0xdeadbeef);
381  ret = WideCharToMultiByte(1252, 0, wcs, -1, mbs, sizeof(mbs), NULL, bUsedDefaultChar);
382  ok(ret == 5, "ret is %d\n", ret);
383  ok(!strcmp(mbs, "Th?i"), "mbs is %s\n", mbs);
384  if(bUsedDefaultChar) ok(*bUsedDefaultChar == TRUE, "bUsedDefaultChar is %d\n", *bUsedDefaultChar);
385  ok(GetLastError() == 0xdeadbeef, "GetLastError() is %u\n", GetLastError());
386  mbs[0] = 0;
387 
388  /* WideCharToMultiByte mustn't add any null character automatically.
389  So in this case, we should get the same string again, even if we only copied the first three bytes. */
390  SetLastError(0xdeadbeef);
391  ret = WideCharToMultiByte(1252, 0, wcs, 3, mbs, sizeof(mbs), NULL, bUsedDefaultChar);
392  ok(ret == 3, "ret is %d\n", ret);
393  ok(!strcmp(mbs, "Th?i"), "mbs is %s\n", mbs);
394  if(bUsedDefaultChar) ok(*bUsedDefaultChar == TRUE, "bUsedDefaultChar is %d\n", *bUsedDefaultChar);
395  ok(GetLastError() == 0xdeadbeef, "GetLastError() is %u\n", GetLastError());
396  ZeroMemory(mbs, 5);
397 
398  /* Now this shouldn't be the case like above as we zeroed the complete string buffer. */
399  SetLastError(0xdeadbeef);
400  ret = WideCharToMultiByte(1252, 0, wcs, 3, mbs, sizeof(mbs), NULL, bUsedDefaultChar);
401  ok(ret == 3, "ret is %d\n", ret);
402  ok(!strcmp(mbs, "Th?"), "mbs is %s\n", mbs);
403  if(bUsedDefaultChar) ok(*bUsedDefaultChar == TRUE, "bUsedDefaultChar is %d\n", *bUsedDefaultChar);
404  ok(GetLastError() == 0xdeadbeef, "GetLastError() is %u\n", GetLastError());
405 
406  /* Double-byte tests */
407  ret = WideCharToMultiByte(1252, 0, dbwcs, 3, mbs, sizeof(mbs), NULL, bUsedDefaultChar);
408  ok(ret == 3, "ret is %d\n", ret);
409  ok(!strcmp(mbs, "??"), "mbs is %s\n", mbs);
410  if(bUsedDefaultChar) ok(*bUsedDefaultChar == TRUE, "bUsedDefaultChar is %d\n", *bUsedDefaultChar);
411 
412  ret = WideCharToMultiByte(936, WC_COMPOSITECHECK, dbwcs2, -1, mbs, sizeof(mbs), (const char *)default_char, bUsedDefaultChar);
413  ok(ret == 10, "ret is %d\n", ret);
414  ok(!strcmp(mbs, "\xf3\xe7\x3d\xa3\xbf\xa3\xbf\xa3\xbf"), "mbs is %s\n", mbs);
415  if(bUsedDefaultChar) ok(*bUsedDefaultChar == TRUE, "bUsedDefaultChar is %d\n", *bUsedDefaultChar);
416 
417  /* Length-only tests */
418  SetLastError(0xdeadbeef);
419  ret = WideCharToMultiByte(1252, 0, &wc2, 1, NULL, 0, NULL, bUsedDefaultChar);
420  ok(ret == 1, "ret is %d\n", ret);
421  if(bUsedDefaultChar) ok(*bUsedDefaultChar == TRUE, "bUsedDefaultChar is %d\n", *bUsedDefaultChar);
422  ok(GetLastError() == 0xdeadbeef, "GetLastError() is %u\n", GetLastError());
423 
424  SetLastError(0xdeadbeef);
425  ret = WideCharToMultiByte(1252, 0, wcs, -1, NULL, 0, NULL, bUsedDefaultChar);
426  ok(ret == 5, "ret is %d\n", ret);
427  if(bUsedDefaultChar) ok(*bUsedDefaultChar == TRUE, "bUsedDefaultChar is %d\n", *bUsedDefaultChar);
428  ok(GetLastError() == 0xdeadbeef, "GetLastError() is %u\n", GetLastError());
429 
430  if (!IsValidCodePage(950))
431  {
432  skip("Codepage 950 not available\n");
433  return;
434  }
435 
436  /* Double-byte tests */
437  SetLastError(0xdeadbeef);
438  ret = WideCharToMultiByte(950, 0, dbwcs, -1, mbs, sizeof(mbs), NULL, bUsedDefaultChar);
439  ok(ret == 5, "ret is %d\n", ret);
440  ok(!strcmp(mbs, "\xb5H\xa9\xd2"), "mbs is %s\n", mbs);
441  if(bUsedDefaultChar) ok(*bUsedDefaultChar == FALSE, "bUsedDefaultChar is %d\n", *bUsedDefaultChar);
442  ok(GetLastError() == 0xdeadbeef, "GetLastError() is %u\n", GetLastError());
443 
444  SetLastError(0xdeadbeef);
445  ret = WideCharToMultiByte(950, 0, dbwcs, 1, &mbc, 1, NULL, bUsedDefaultChar);
446  ok(ret == 0, "ret is %d\n", ret);
447  if(bUsedDefaultChar) ok(*bUsedDefaultChar == FALSE, "bUsedDefaultChar is %d\n", *bUsedDefaultChar);
448  ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "GetLastError() is %u\n", GetLastError());
449  ZeroMemory(mbs, 5);
450 
451  SetLastError(0xdeadbeef);
452  ret = WideCharToMultiByte(950, 0, dbwcs, 1, mbs, sizeof(mbs), NULL, bUsedDefaultChar);
453  ok(ret == 2, "ret is %d\n", ret);
454  ok(!strcmp(mbs, "\xb5H"), "mbs is %s\n", mbs);
455  if(bUsedDefaultChar) ok(*bUsedDefaultChar == FALSE, "bUsedDefaultChar is %d\n", *bUsedDefaultChar);
456  ok(GetLastError() == 0xdeadbeef, "GetLastError() is %u\n", GetLastError());
457 
458  /* Length-only tests */
459  SetLastError(0xdeadbeef);
460  ret = WideCharToMultiByte(950, 0, dbwcs, 1, NULL, 0, NULL, bUsedDefaultChar);
461  ok(ret == 2, "ret is %d\n", ret);
462  if(bUsedDefaultChar) ok(*bUsedDefaultChar == FALSE, "bUsedDefaultChar is %d\n", *bUsedDefaultChar);
463  ok(GetLastError() == 0xdeadbeef, "GetLastError() is %u\n", GetLastError());
464 
465  SetLastError(0xdeadbeef);
466  ret = WideCharToMultiByte(950, 0, dbwcs, -1, NULL, 0, NULL, bUsedDefaultChar);
467  ok(ret == 5, "ret is %d\n", ret);
468  if(bUsedDefaultChar) ok(*bUsedDefaultChar == FALSE, "bUsedDefaultChar is %d\n", *bUsedDefaultChar);
469  ok(GetLastError() == 0xdeadbeef, "GetLastError() is %u\n", GetLastError());
470 }
#define TRUE
Definition: types.h:120
wchar_t wc2
#define WideCharToMultiByte
Definition: compat.h:101
wchar_t wcs[5]
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1059
#define ZeroMemory
Definition: winbase.h:1642
smooth NULL
Definition: ftsmooth.c:416
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define SetLastError(x)
Definition: compat.h:417
int ret
#define broken(x)
Definition: _sntprintf.h:21
BOOL WINAPI IsValidCodePage(UINT CodePage)
Definition: nls.c:1479
#define WC_COMPOSITECHECK
Definition: unicode.h:43
#define ok(value,...)
Definition: atltest.h:57
wchar_t dbwcs[3]
char mbc
#define skip(...)
Definition: atltest.h:64
wchar_t wc1
int strcmp(const char *String1, const char *String2)
Definition: utclib.c:469
char mbs[5]
#define ERROR_INSUFFICIENT_BUFFER
Definition: dderror.h:10

Referenced by START_TEST().

◆ test_threadcp()

static void test_threadcp ( void  )
static

Definition at line 1037 of file codepage.c.

1038 {
1045 
1046  BOOL islead, islead_acp;
1047  CPINFOEXA cpi;
1048  UINT cp, acp;
1049  int i, num;
1050  LCID last;
1051  BOOL ret;
1052 
1053  struct test {
1054  LCID lcid;
1055  UINT threadcp;
1056  } lcids[] = {
1057  { HINDI, 0 },
1058  { GEORGIAN, 0 },
1059  { ENGLISH, 1252 },
1060  { RUSSIAN, 1251 },
1061  { JAPANESE, 932 },
1062  { CHINESE, 936 }
1063  };
1064 
1065  struct test_islead_nocp {
1066  LCID lcid;
1067  BYTE testchar;
1068  } isleads_nocp[] = {
1069  { HINDI, 0x00 },
1070  { HINDI, 0x81 },
1071  { HINDI, 0xa0 },
1072  { HINDI, 0xe0 },
1073 
1074  { GEORGIAN, 0x00 },
1075  { GEORGIAN, 0x81 },
1076  { GEORGIAN, 0xa0 },
1077  { GEORGIAN, 0xe0 },
1078  };
1079 
1080  struct test_islead {
1081  LCID lcid;
1082  BYTE testchar;
1083  BOOL islead;
1084  } isleads[] = {
1085  { ENGLISH, 0x00, FALSE },
1086  { ENGLISH, 0x81, FALSE },
1087  { ENGLISH, 0xa0, FALSE },
1088  { ENGLISH, 0xe0, FALSE },
1089 
1090  { RUSSIAN, 0x00, FALSE },
1091  { RUSSIAN, 0x81, FALSE },
1092  { RUSSIAN, 0xa0, FALSE },
1093  { RUSSIAN, 0xe0, FALSE },
1094 
1095  { JAPANESE, 0x00, FALSE },
1096  { JAPANESE, 0x81, TRUE },
1097  { JAPANESE, 0xa0, FALSE },
1098  { JAPANESE, 0xe0, TRUE },
1099 
1100  { CHINESE, 0x00, FALSE },
1101  { CHINESE, 0x81, TRUE },
1102  { CHINESE, 0xa0, TRUE },
1103  { CHINESE, 0xe0, TRUE },
1104  };
1105 
1106  last = GetThreadLocale();
1107  acp = GetACP();
1108 
1109  for (i = 0; i < sizeof(lcids)/sizeof(lcids[0]); i++)
1110  {
1111  SetThreadLocale(lcids[i].lcid);
1112 
1113  cp = 0xdeadbeef;
1114  GetLocaleInfoA(lcids[i].lcid, LOCALE_IDEFAULTANSICODEPAGE|LOCALE_RETURN_NUMBER, (LPSTR)&cp, sizeof(cp));
1115  ok(cp == lcids[i].threadcp, "wrong codepage %u for lcid %04x, should be %u\n", cp, lcids[i].threadcp, cp);
1116 
1117  /* GetCPInfoEx/GetCPInfo - CP_ACP */
1118  SetLastError(0xdeadbeef);
1119  memset(&cpi, 0, sizeof(cpi));
1120  ret = GetCPInfoExA(CP_ACP, 0, &cpi);
1121  ok(ret, "GetCPInfoExA failed for lcid %04x, error %d\n", lcids[i].lcid, GetLastError());
1122  ok(cpi.CodePage == acp, "wrong codepage %u for lcid %04x, should be %u\n", cpi.CodePage, lcids[i].lcid, acp);
1123 
1124  /* WideCharToMultiByte - CP_ACP */
1125  num = WideCharToMultiByte(CP_ACP, 0, foobarW, -1, NULL, 0, NULL, NULL);
1126  ok(num == 7, "ret is %d (%04x)\n", num, lcids[i].lcid);
1127 
1128  /* MultiByteToWideChar - CP_ACP */
1129  num = MultiByteToWideChar(CP_ACP, 0, "foobar", -1, NULL, 0);
1130  ok(num == 7, "ret is %d (%04x)\n", num, lcids[i].lcid);
1131 
1132  /* GetCPInfoEx/GetCPInfo - CP_THREAD_ACP */
1133  SetLastError(0xdeadbeef);
1134  memset(&cpi, 0, sizeof(cpi));
1135  ret = GetCPInfoExA(CP_THREAD_ACP, 0, &cpi);
1136  ok(ret, "GetCPInfoExA failed for lcid %04x, error %d\n", lcids[i].lcid, GetLastError());
1137  if (lcids[i].threadcp)
1138  ok(cpi.CodePage == lcids[i].threadcp, "wrong codepage %u for lcid %04x, should be %u\n",
1139  cpi.CodePage, lcids[i].lcid, lcids[i].threadcp);
1140  else
1141  ok(cpi.CodePage == acp, "wrong codepage %u for lcid %04x, should be %u\n",
1142  cpi.CodePage, lcids[i].lcid, acp);
1143 
1144  /* WideCharToMultiByte - CP_THREAD_ACP */
1146  ok(num == 7, "ret is %d (%04x)\n", num, lcids[i].lcid);
1147 
1148  /* MultiByteToWideChar - CP_THREAD_ACP */
1149  num = MultiByteToWideChar(CP_THREAD_ACP, 0, "foobar", -1, NULL, 0);
1150  ok(num == 7, "ret is %d (%04x)\n", num, lcids[i].lcid);
1151  }
1152 
1153  /* IsDBCSLeadByteEx - locales without codepage */
1154  for (i = 0; i < sizeof(isleads_nocp)/sizeof(isleads_nocp[0]); i++)
1155  {
1156  SetThreadLocale(isleads_nocp[i].lcid);
1157 
1158  islead_acp = IsDBCSLeadByteEx(CP_ACP, isleads_nocp[i].testchar);
1159  islead = IsDBCSLeadByteEx(CP_THREAD_ACP, isleads_nocp[i].testchar);
1160 
1161  ok(islead == islead_acp, "wrong islead %i for test char %x in lcid %04x. should be %i\n",
1162  islead, isleads_nocp[i].testchar, isleads_nocp[i].lcid, islead_acp);
1163  }
1164 
1165  /* IsDBCSLeadByteEx - locales with codepage */
1166  for (i = 0; i < sizeof(isleads)/sizeof(isleads[0]); i++)
1167  {
1168  SetThreadLocale(isleads[i].lcid);
1169 
1170  islead = IsDBCSLeadByteEx(CP_THREAD_ACP, isleads[i].testchar);
1171  ok(islead == isleads[i].islead, "wrong islead %i for test char %x in lcid %04x. should be %i\n",
1172  islead, isleads[i].testchar, isleads[i].lcid, isleads[i].islead);
1173  }
1174 
1176 }
#define LOCALE_IDEFAULTANSICODEPAGE
Definition: winnls.h:38
#define MAKELCID(lgid, srtid)
#define TRUE
Definition: types.h:120
UINT CodePage
Definition: winnls.h:587
#define SUBLANG_RUSSIAN_RUSSIA
Definition: nls.h:315
#define WideCharToMultiByte
Definition: compat.h:101
POINT last
Definition: font.c:46
#define SUBLANG_GEORGIAN_GEORGIA
Definition: nls.h:250
#define LANG_HINDI
Definition: nls.h:68
#define CP_ACP
Definition: compat.h:99
INT WINAPI GetLocaleInfoA(LCID lcid, LCTYPE lctype, LPSTR buffer, INT len)
Definition: lang.c:1018
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1059
#define test
Definition: rosglue.h:37
DWORD LCID
Definition: nls.h:13
#define SUBLANG_JAPANESE_JAPAN
Definition: nls.h:271
char * LPSTR
Definition: xmlstorage.h:182
#define SUBLANG_ENGLISH_US
Definition: nls.h:222
BOOL WINAPI IsDBCSLeadByteEx(UINT CodePage, BYTE TestByte)
Definition: nls.c:2210
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
BOOL WINAPI SetThreadLocale(LCID lcid)
Definition: lang.c:1468
#define LANG_JAPANESE
Definition: nls.h:76
unsigned int BOOL
Definition: ntddk_ex.h:94
smooth NULL
Definition: ftsmooth.c:416
UINT WINAPI GetACP(VOID)
Definition: nls.c:2180
#define SORT_DEFAULT
static const WCHAR foobarW[]
Definition: codepage.c:32
GLuint GLuint num
Definition: glext.h:9618
#define SetLastError(x)
Definition: compat.h:417
#define LANG_RUSSIAN
Definition: nls.h:113
#define LANG_ENGLISH
Definition: nls.h:52
int ret
unsigned char BYTE
Definition: mem.h:68
#define SUBLANG_CHINESE_SIMPLIFIED
Definition: nls.h:209
BOOL WINAPI GetCPInfoExA(UINT CodePage, DWORD dwFlags, LPCPINFOEXA lpCPInfoEx)
Definition: nls.c:2025
#define ok(value,...)
Definition: atltest.h:57
unsigned int UINT
Definition: ndis.h:50
#define MultiByteToWideChar
Definition: compat.h:100
#define SUBLANG_HINDI_INDIA
Definition: nls.h:261
POINT cp
Definition: magnifier.c:59
#define LANG_CHINESE
Definition: nls.h:42
#define MAKELANGID(p, s)
Definition: nls.h:15
#define LANG_GEORGIAN
Definition: nls.h:61
#define CP_THREAD_ACP
Definition: winnls.h:230
#define memset(x, y, z)
Definition: compat.h:39
LCID WINAPI GetThreadLocale(void)
Definition: lang.c:1449

Referenced by START_TEST().

◆ test_undefined_byte_char()

static void test_undefined_byte_char ( void  )
static

Definition at line 987 of file codepage.c.

988 {
989  static const struct tag_testset {
990  INT codepage;
991  LPCSTR str;
992  BOOL is_error;
993  } testset[] = {
994  { 874, "\xdd", TRUE },
995  { 932, "\xfe", TRUE },
996  { 932, "\x80", FALSE },
997  { 936, "\xff", TRUE },
998  { 949, "\xff", TRUE },
999  { 950, "\xff", TRUE },
1000  { 1252, "\x90", FALSE },
1001  { 1253, "\xaa", TRUE },
1002  { 1255, "\xff", TRUE },
1003  { 1257, "\xa5", TRUE },
1004  };
1005  INT i, ret;
1006 
1007  for (i = 0; i < (sizeof(testset) / sizeof(testset[0])); i++) {
1008  if (! IsValidCodePage(testset[i].codepage))
1009  {
1010  skip("Codepage %d not available\n", testset[i].codepage);
1011  continue;
1012  }
1013 
1014  SetLastError(0xdeadbeef);
1016  testset[i].str, -1, NULL, 0);
1017  if (testset[i].is_error) {
1019  "ret is %d, GetLastError is %u (cp %d)\n",
1020  ret, GetLastError(), testset[i].codepage);
1021  }
1022  else {
1023  ok(ret == strlen(testset[i].str)+1 && GetLastError() == 0xdeadbeef,
1024  "ret is %d, GetLastError is %u (cp %d)\n",
1025  ret, GetLastError(), testset[i].codepage);
1026  }
1027 
1028  SetLastError(0xdeadbeef);
1029  ret = MultiByteToWideChar(testset[i].codepage, 0,
1030  testset[i].str, -1, NULL, 0);
1031  ok(ret == strlen(testset[i].str)+1 && GetLastError() == 0xdeadbeef,
1032  "ret is %d, GetLastError is %u (cp %d)\n",
1033  ret, GetLastError(), testset[i].codepage);
1034  }
1035 }
#define TRUE
Definition: types.h:120
#define MB_ERR_INVALID_CHARS
Definition: unicode.h:41
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1059
int32_t INT
Definition: typedefs.h:56
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
unsigned int BOOL
Definition: ntddk_ex.h:94
int codepage
Definition: win_iconv.c:156
const WCHAR * str
smooth NULL
Definition: ftsmooth.c:416
const char * LPCSTR
Definition: xmlstorage.h:183
#define SetLastError(x)
Definition: compat.h:417
#define ERROR_NO_UNICODE_TRANSLATION
Definition: winerror.h:649
int ret
BOOL WINAPI IsValidCodePage(UINT CodePage)
Definition: nls.c:1479
#define ok(value,...)
Definition: atltest.h:57
#define MultiByteToWideChar
Definition: compat.h:100
#define skip(...)
Definition: atltest.h:64

Referenced by START_TEST().

◆ test_utf7_decoding()

static void test_utf7_decoding ( void  )
static

Definition at line 715 of file codepage.c.

716 {
717  char input[32];
718  WCHAR output[32], expected[32];
719  int i, len, expected_len;
720 
721  static const signed char base64_decoding_table[] =
722  {
723  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 0x00-0x0F */
724  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 0x10-0x1F */
725  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63, /* 0x20-0x2F */
726  52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1, /* 0x30-0x3F */
727  -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, /* 0x40-0x4F */
728  15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1, /* 0x50-0x5F */
729  -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, /* 0x60-0x6F */
730  41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1 /* 0x70-0x7F */
731  };
732 
733  struct
734  {
735  /* inputs */
736  char src[32];
737  int srclen;
738  WCHAR *dst;
739  int dstlen;
740  /* expected outputs */
741  WCHAR expected_dst[32];
742  int chars_written;
743  int len;
744  }
745  tests[] =
746  {
747  /* tests string conversion with srclen=-1 */
748  {
749  "+T2BZfQ-", -1, output, sizeof(output) / sizeof(WCHAR) - 1,
750  {0x4F60,0x597D,0}, 3, 3
751  },
752  /* tests string conversion with srclen=-2 */
753  {
754  "+T2BZfQ-", -2, output, sizeof(output) / sizeof(WCHAR) - 1,
755  {0x4F60,0x597D,0}, 3, 3
756  },
757  /* tests string conversion with dstlen=strlen(expected_dst) */
758  {
759  "+T2BZfQ-", -1, output, 2,
760  {0x4F60,0x597D}, 2, 0
761  },
762  /* tests string conversion with dstlen=strlen(expected_dst)+1 */
763  {
764  "+T2BZfQ-", -1, output, 3,
765  {0x4F60,0x597D,0}, 3, 3
766  },
767  /* tests string conversion with dstlen=strlen(expected_dst)+2 */
768  {
769  "+T2BZfQ-", -1, output, 4,
770  {0x4F60,0x597D,0}, 3, 3
771  },
772  /* tests dry run with dst=NULL and dstlen=0 */
773  {
774  "+T2BZfQ-", -1, NULL, 0,
775  {0}, 0, 3
776  },
777  /* tests dry run with dst!=NULL and dstlen=0 */
778  {
779  "+T2BZfQ-", -1, output, 0,
780  {0}, 0, 3
781  },
782  /* tests ill-formed UTF-7: 6 bits, not enough for a byte pair */
783  {
784  "+T-+T-+T-hello", -1, output, sizeof(output) / sizeof(WCHAR) - 1,
785  {'h','e','l','l','o',0}, 6, 6
786  },
787  /* tests ill-formed UTF-7: 12 bits, not enough for a byte pair */
788  {
789  "+T2-+T2-+T2-hello", -1, output, sizeof(output) / sizeof(WCHAR) - 1,
790  {'h','e','l','l','o',0}, 6, 6
791  },
792  /* tests ill-formed UTF-7: 18 bits, not a multiple of 16 and the last bit is a 1 */
793  {
794  "+T2B-+T2B-+T2B-hello", -1, output, sizeof(output) / sizeof(WCHAR) - 1,
795  {0x4F60,0x4F60,0x4F60,'h','e','l','l','o',0}, 9, 9
796  },
797  /* tests ill-formed UTF-7: 24 bits, a multiple of 8 but not a multiple of 16 */
798  {
799  "+T2BZ-+T2BZ-+T2BZ-hello", -1, output, sizeof(output) / sizeof(WCHAR) - 1,
800  {0x4F60,0x4F60,0x4F60,'h','e','l','l','o',0}, 9, 9
801  },
802  /* tests UTF-7 followed by characters that should be encoded but aren't */
803  {
804  "+T2BZ-\x82\xFE", -1, output, sizeof(output) / sizeof(WCHAR) - 1,
805  {0x4F60,0x0082,0x00FE,0}, 4, 4
806  },
807  /* tests srclen > strlen(src) */
808  {
809  "a\0b", 4, output, sizeof(output) / sizeof(WCHAR) - 1,
810  {'a',0,'b',0}, 4, 4
811  },
812  /* tests srclen < strlen(src) outside of a UTF-7 sequence */
813  {
814  "hello", 2, output, sizeof(output) / sizeof(WCHAR) - 1,
815  {'h','e'}, 2, 2
816  },
817  /* tests srclen < strlen(src) inside of a UTF-7 sequence */
818  {
819  "+T2BZfQ-", 4, output, sizeof(output) / sizeof(WCHAR) - 1,
820  {0x4F60}, 1, 1
821  },
822  /* tests srclen < strlen(src) right at the beginning of a UTF-7 sequence */
823  {
824  "hi+T2A-", 3, output, sizeof(output) / sizeof(WCHAR) - 1,
825  {'h','i'}, 2, 2
826  },
827  /* tests srclen < strlen(src) right at the end of a UTF-7 sequence */
828  {
829  "+T2A-hi", 5, output, sizeof(output) / sizeof(WCHAR) - 1,
830  {0x4F60}, 1, 1
831  },
832  /* tests srclen < strlen(src) at the beginning of an escaped + sign */
833  {
834  "hi+-", 3, output, sizeof(output) / sizeof(WCHAR) - 1,
835  {'h','i'}, 2, 2
836  },
837  /* tests srclen < strlen(src) at the end of an escaped + sign */
838  {
839  "+-hi", 2, output, sizeof(output) / sizeof(WCHAR) - 1,
840  {'+'}, 1, 1
841  },
842  /* tests len=0 but no error */
843  {
844  "+", 1, output, sizeof(output) / sizeof(WCHAR) - 1,
845  {0}, 0, 0
846  },
847  /* tests a single null char */
848  {
849  "", -1, output, sizeof(output) / sizeof(WCHAR) - 1,
850  {0}, 1, 1
851  },
852  /* tests a buffer that runs out while not decoding a UTF-7 sequence */
853  {
854  "hello", -1, output, 2,
855  {'h','e'}, 2, 0
856  },
857  /* tests a buffer that runs out in the middle of decoding a UTF-7 sequence */
858  {
859  "+T2BZfQ-", -1, output, 1,
860  {0x4F60}, 1, 0
861  }
862  };
863 
864  /* test which one-byte characters remove stray + signs */
865  for (i = 0; i < 256; i++)
866  {
867  sprintf(input, "+%c+AAA", i);
868 
869  memset(output, 0x23, sizeof(output) - sizeof(WCHAR));
870  output[sizeof(output) / sizeof(WCHAR) - 1] = 0;
871 
872  len = MultiByteToWideChar(CP_UTF7, 0, input, 7, output, sizeof(output) / sizeof(WCHAR) - 1);
873 
874  if (i == '-')
875  {
876  /* removes the - sign */
877  expected_len = 3;
878  expected[0] = 0x002B;
879  expected[1] = 0;
880  expected[2] = 0;
881  }
882  else if (i <= 0x7F && base64_decoding_table[i] != -1)
883  {
884  /* absorbs the character into the base64 sequence */
885  expected_len = 2;
886  expected[0] = (base64_decoding_table[i] << 10) | 0x03E0;
887  expected[1] = 0;
888  }
889  else
890  {
891  /* removes the + sign */
892  expected_len = 3;
893  expected[0] = i;
894  expected[1] = 0;
895  expected[2] = 0;
896  }
897  expected[expected_len] = 0x2323;
898 
899  ok(len == expected_len, "i=0x%02x: expected len=%i, got len=%i\n", i, expected_len, len);
900  ok(memcmp(output, expected, (expected_len + 1) * sizeof(WCHAR)) == 0,
901  "i=0x%02x: expected output=%s, got output=%s\n",
902  i, wine_dbgstr_wn(expected, expected_len + 1), wine_dbgstr_wn(output, expected_len + 1));
903  }
904 
905  /* test which one-byte characters terminate a sequence
906  * also test whether the unfinished byte pair is discarded or not */
907  for (i = 0; i < 256; i++)
908  {
909  sprintf(input, "+B%c+AAA", i);
910 
911  memset(output, 0x23, sizeof(output) - sizeof(WCHAR));
912  output[sizeof(output) / sizeof(WCHAR) - 1] = 0;
913 
914  len = MultiByteToWideChar(CP_UTF7, 0, input, 8, output, sizeof(output) / sizeof(WCHAR) - 1);
915 
916  if (i == '-')
917  {
918  /* explicitly terminates */
919  expected_len = 2;
920  expected[0] = 0;
921  expected[1] = 0;
922  }
923  else if (i <= 0x7F)
924  {
925  if (base64_decoding_table[i] != -1)
926  {
927  /* absorbs the character into the base64 sequence */
928  expected_len = 3;
929  expected[0] = 0x0400 | (base64_decoding_table[i] << 4) | 0x000F;
930  expected[1] = 0x8000;
931  expected[2] = 0;
932  }
933  else
934  {
935  /* implicitly terminates and discards the unfinished byte pair */
936  expected_len = 3;
937  expected[0] = i;
938  expected[1] = 0;
939  expected[2] = 0;
940  }
941  }
942  else
943  {
944  /* implicitly terminates but does not the discard unfinished byte pair */
945  expected_len = 3;
946  expected[0] = i;
947  expected[1] = 0x0400;
948  expected[2] = 0;
949  }
950  expected[expected_len] = 0x2323;
951 
952  ok(len == expected_len, "i=0x%02x: expected len=%i, got len=%i\n", i, expected_len, len);
953  ok(memcmp(output, expected, (expected_len + 1) * sizeof(WCHAR)) == 0,
954  "i=0x%02x: expected output=%s, got output=%s\n",
955  i, wine_dbgstr_wn(expected, expected_len + 1), wine_dbgstr_wn(output, expected_len + 1));
956  }
957 
958  for (i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
959  {
960  memset(output, 0x23, sizeof(output) - sizeof(WCHAR));
961  output[sizeof(output) / sizeof(WCHAR) - 1] = 0;
962  SetLastError(0xdeadbeef);
963 
965  tests[i].dst, tests[i].dstlen);
966 
967  tests[i].expected_dst[tests[i].chars_written] = 0x2323;
968 
969  if (!tests[i].len && tests[i].chars_written)
970  {
972  "tests[%i]: expected error=0x%x, got error=0x%x\n",
974  }
975  ok(len == tests[i].len, "tests[%i]: expected len=%i, got len=%i\n", i, tests[i].len, len);
976 
977  if (tests[i].dst)
978  {
979  ok(memcmp(tests[i].dst, tests[i].expected_dst, (tests[i].chars_written + 1) * sizeof(WCHAR)) == 0,
980  "tests[%i]: expected dst=%s, got dst=%s\n",
981  i, wine_dbgstr_wn(tests[i].expected_dst, tests[i].chars_written + 1),
982  wine_dbgstr_wn(tests[i].dst, tests[i].chars_written + 1));
983  }
984  }
985 }
struct param_test tests[]
static UCHAR ULONG UCHAR ULONG UCHAR * output
Definition: bcrypt.c:29
int memcmp(void *Buffer1, void *Buffer2, ACPI_SIZE Count)
Definition: utclib.c:112
#define CP_UTF7
Definition: winnls.h:232
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1059
#define sprintf(buf, format,...)
Definition: sprintf.c:55
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
smooth NULL
Definition: ftsmooth.c:416
__wchar_t WCHAR
Definition: xmlstorage.h:180
static DWORD LPDWORD LPCSTR DWORD srclen
Definition: directory.c:51
#define SetLastError(x)
Definition: compat.h:417
GLenum GLsizei len
Definition: glext.h:6722
const char * wine_dbgstr_wn(const WCHAR *str, int n)
Definition: compat.c:342
GLenum src
Definition: glext.h:6340
static DWORD dstlen
Definition: directory.c:51
GLenum GLenum GLenum input
Definition: glext.h:9031
#define ok(value,...)
Definition: atltest.h:57
GLenum GLenum dst
Definition: glext.h:6340
#define MultiByteToWideChar
Definition: compat.h:100
#define memset(x, y, z)
Definition: compat.h:39
BOOL expected
Definition: store.c:2063
#define ERROR_INSUFFICIENT_BUFFER
Definition: dderror.h:10

Referenced by START_TEST().

◆ test_utf7_encoding()

static void test_utf7_encoding ( void  )
static

Definition at line 472 of file codepage.c.

473 {
474  WCHAR input[16];
475  char output[16], expected[16];
476  int i, len, expected_len;
477 
478  static const BOOL directly_encodable_table[] =
479  {
480  1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, /* 0x00 - 0x0F */
481  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x10 - 0x1F */
482  1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, /* 0x20 - 0x2F */
483  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, /* 0x30 - 0x3F */
484  0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x40 - 0x4F */
485  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, /* 0x50 - 0x5F */
486  0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x60 - 0x6F */
487  1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0 /* 0x70 - 0x7F */
488  };
489  static const char base64_encoding_table[] =
490  "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
491 
492  const struct
493  {
494  /* inputs */
495  WCHAR src[16];
496  int srclen;
497  char *dst;
498  int dstlen;
499  /* expected outputs */
500  char expected_dst[16];
501  int chars_written;
502  int len;
503  }
504  tests[] =
505  {
506  /* tests string conversion with srclen=-1 */
507  {
508  {0x4F60,0x597D,0x5417,0}, -1, output, sizeof(output) - 1,
509  "+T2BZfVQX-", 11, 11
510  },
511  /* tests string conversion with srclen=-2 */
512  {
513  {0x4F60,0x597D,0x5417,0}, -2, output, sizeof(output) - 1,
514  "+T2BZfVQX-", 11, 11
515  },
516  /* tests string conversion with dstlen=strlen(expected_dst) */
517  {
518  {0x4F60,0x597D,0x5417,0}, -1, output, 10,
519  "+T2BZfVQX-", 10, 0
520  },
521  /* tests string conversion with dstlen=strlen(expected_dst)+1 */
522  {
523  {0x4F60,0x597D,0x5417,0}, -1, output, 11,
524  "+T2BZfVQX-", 11, 11
525  },
526  /* tests string conversion with dstlen=strlen(expected_dst)+2 */
527  {
528  {0x4F60,0x597D,0x5417,0}, -1, output, 12,
529  "+T2BZfVQX-", 11, 11
530  },
531  /* tests dry run with dst=NULL and dstlen=0 */
532  {
533  {0x4F60,0x597D,0x5417,0}, -1, NULL, 0,
534  {0}, 0, 11
535  },
536  /* tests dry run with dst!=NULL and dstlen=0 */
537  {
538  {0x4F60,0x597D,0x5417,0}, -1, output, 0,
539  {0}, 0, 11
540  },
541  /* tests srclen < strlenW(src) with directly encodable chars */
542  {
543  {'h','e','l','l','o',0}, 2, output, sizeof(output) - 1,
544  "he", 2, 2
545  },
546  /* tests srclen < strlenW(src) with non-directly encodable chars */
547  {
548  {0x4F60,0x597D,0x5417,0}, 2, output, sizeof(output) - 1,
549  "+T2BZfQ-", 8, 8
550  },
551  /* tests a single null char */
552  {
553  {0}, -1, output, sizeof(output) - 1,
554  "", 1, 1
555  },
556  /* tests a buffer that runs out while not encoding a UTF-7 sequence */
557  {
558  {'h','e','l','l','o',0}, -1, output, 2,
559  "he", 2, 0
560  },
561  /* tests a buffer that runs out after writing 1 base64 character */
562  {
563  {0x4F60,0x0001,0}, -1, output, 2,
564  "+T", 2, 0
565  },
566  /* tests a buffer that runs out after writing 2 base64 characters */
567  {
568  {0x4F60,0x0001,0}, -1, output, 3,
569  "+T2", 3, 0
570  },
571  /* tests a buffer that runs out after writing 3 base64 characters */
572  {
573  {0x4F60,0x0001,0}, -1, output, 4,
574  "+T2A", 4, 0
575  },
576  /* tests a buffer that runs out just after writing the + sign */
577  {
578  {0x4F60,0}, -1, output, 1,
579  "+", 1, 0
580  },
581  /* tests a buffer that runs out just before writing the - sign
582  * the number of bits to encode here is evenly divisible by 6 */
583  {
584  {0x4F60,0x597D,0x5417,0}, -1, output, 9,
585  "+T2BZfVQX", 9, 0
586  },
587  /* tests a buffer that runs out just before writing the - sign
588  * the number of bits to encode here is NOT evenly divisible by 6 */
589  {
590  {0x4F60,0}, -1, output, 4,
591  "+T2", 3, 0
592  },
593  /* tests a buffer that runs out in the middle of escaping a + sign */
594  {
595  {'+',0}, -1, output, 1,
596  "+", 1, 0
597  }
598  };
599 
600  /* test which characters are encoded if surrounded by non-encoded characters */
601  for (i = 0; i <= 0xFFFF; i++)
602  {
603  input[0] = ' ';
604  input[1] = i;
605  input[2] = ' ';
606  input[3] = 0;
607 
608  memset(output, '#', sizeof(output) - 1);
609  output[sizeof(output) - 1] = 0;
610 
611  len = WideCharToMultiByte(CP_UTF7, 0, input, 4, output, sizeof(output) - 1, NULL, NULL);
612 
613  if (i == '+')
614  {
615  /* '+' is a special case and is encoded as "+-" */
616  expected_len = 5;
617  strcpy(expected, " +- ");
618  }
619  else if (i <= 0x7F && directly_encodable_table[i])
620  {
621  /* encodes directly */
622  expected_len = 4;
623  sprintf(expected, " %c ", i);
624  }
625  else
626  {
627  /* base64-encodes */
628  expected_len = 8;
629  sprintf(expected, " +%c%c%c- ",
630  base64_encoding_table[(i & 0xFC00) >> 10],
631  base64_encoding_table[(i & 0x03F0) >> 4],
632  base64_encoding_table[(i & 0x000F) << 2]);
633  }
634 
635  ok(len == expected_len, "i=0x%04x: expected len=%i, got len=%i\n", i, expected_len, len);
636  ok(memcmp(output, expected, expected_len) == 0,
637  "i=0x%04x: expected output='%s', got output='%s'\n", i, expected, output);
638  ok(output[expected_len] == '#', "i=0x%04x: expected output[%i]='#', got output[%i]=%i\n",
639  i, expected_len, expected_len, output[expected_len]);
640  }
641 
642  /* test which one-byte characters are absorbed into surrounding base64 blocks
643  * (Windows always ends the base64 block when it encounters a directly encodable character) */
644  for (i = 0; i <= 0xFFFF; i++)
645  {
646  input[0] = 0x2672;
647  input[1] = i;
648  input[2] = 0x2672;
649  input[3] = 0;
650 
651  memset(output, '#', sizeof(output) - 1);
652  output[sizeof(output) - 1] = 0;
653 
654  len = WideCharToMultiByte(CP_UTF7, 0, input, 4, output, sizeof(output) - 1, NULL, NULL);
655 
656  if (i == '+')
657  {
658  /* '+' is a special case and is encoded as "+-" */
659  expected_len = 13;
660  strcpy(expected, "+JnI-+-+JnI-");
661  }
662  else if (i <= 0x7F && directly_encodable_table[i])
663  {
664  /* encodes directly */
665  expected_len = 12;
666  sprintf(expected, "+JnI-%c+JnI-", i);
667  }
668  else
669  {
670  /* base64-encodes */
671  expected_len = 11;
672  sprintf(expected, "+Jn%c%c%c%cZy-",
673  base64_encoding_table[8 | ((i & 0xC000) >> 14)],
674  base64_encoding_table[(i & 0x3F00) >> 8],
675  base64_encoding_table[(i & 0x00FC) >> 2],
676  base64_encoding_table[((i & 0x0003) << 4) | 2]);
677  }
678 
679  ok(len == expected_len, "i=0x%04x: expected len=%i, got len=%i\n", i, expected_len, len);
680  ok(memcmp(output, expected, expected_len) == 0,
681  "i=0x%04x: expected output='%s', got output='%s'\n", i, expected, output);
682  ok(output[expected_len] == '#', "i=0x%04x: expected output[%i]='#', got output[%i]=%i\n",
683  i, expected_len, expected_len, output[expected_len]);
684  }
685 
686  for (i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
687  {
688  memset(output, '#', sizeof(output) - 1);
689  output[sizeof(output) - 1] = 0;
690  SetLastError(0xdeadbeef);
691 
693  tests[i].dst, tests[i].dstlen, NULL, NULL);
694 
695  if (!tests[i].len)
696  {
698  "tests[%i]: expected error=0x%x, got error=0x%x\n",
700  }
701  ok(len == tests[i].len, "tests[%i]: expected len=%i, got len=%i\n", i, tests[i].len, len);
702 
703  if (tests[i].dst)
704  {
705  ok(memcmp(tests[i].dst, tests[i].expected_dst, tests[i].chars_written) == 0,
706  "tests[%i]: expected dst='%s', got dst='%s'\n",
707  i, tests[i].expected_dst, tests[i].dst);
708  ok(tests[i].dst[tests[i].chars_written] == '#',
709  "tests[%i]: expected dst[%i]='#', got dst[%i]=%i\n",
710  i, tests[i].chars_written, tests[i].chars_written, tests[i].dst[tests[i].chars_written]);
711  }
712  }
713 }
struct param_test tests[]
static UCHAR ULONG UCHAR ULONG UCHAR * output
Definition: bcrypt.c:29
int memcmp(void *Buffer1, void *Buffer2, ACPI_SIZE Count)
Definition: utclib.c:112
#define WideCharToMultiByte
Definition: compat.h:101
#define CP_UTF7
Definition: winnls.h:232
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1059
#define sprintf(buf, format,...)
Definition: sprintf.c:55
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
unsigned int BOOL
Definition: ntddk_ex.h:94
smooth NULL
Definition: ftsmooth.c:416
__wchar_t WCHAR
Definition: xmlstorage.h:180
static DWORD LPDWORD LPCSTR DWORD srclen
Definition: directory.c:51
#define SetLastError(x)
Definition: compat.h:417
GLenum GLsizei len
Definition: glext.h:6722
GLenum src
Definition: glext.h:6340
static DWORD dstlen
Definition: directory.c:51
GLenum GLenum GLenum input
Definition: glext.h:9031
#define ok(value,...)
Definition: atltest.h:57
GLenum GLenum dst
Definition: glext.h:6340
char * strcpy(char *DstString, const char *SrcString)
Definition: utclib.c:388
#define memset(x, y, z)
Definition: compat.h:39
BOOL expected
Definition: store.c:2063
#define ERROR_INSUFFICIENT_BUFFER
Definition: dderror.h:10

Referenced by START_TEST().

Variable Documentation

◆ foobarA

const char foobarA[] = "foobar"
static

Definition at line 31 of file codepage.c.

Referenced by test_negative_dest_length().

◆ foobarW

const WCHAR foobarW[] = {'f','o','o','b','a','r',0}
static