unicode_ut.c 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * Unit tests for Unicode functions
  4. *
  5. * Copyright (c) 2018 Heinrich Schuchardt <xypron.glpk@gmx.de>
  6. */
  7. #include <common.h>
  8. #include <charset.h>
  9. #include <command.h>
  10. #include <efi_loader.h>
  11. #include <errno.h>
  12. #include <log.h>
  13. #include <malloc.h>
  14. #include <test/test.h>
  15. #include <test/suites.h>
  16. #include <test/ut.h>
  17. /* Linker list entry for a Unicode test */
  18. #define UNICODE_TEST(_name) UNIT_TEST(_name, 0, unicode_test)
  19. /* Constants c1-c4 and d1-d4 encode the same letters */
  20. /* Six characters translating to one utf-8 byte each. */
  21. static const u16 c1[] = {0x55, 0x2d, 0x42, 0x6f, 0x6f, 0x74, 0x00};
  22. /* One character translating to two utf-8 bytes */
  23. static const u16 c2[] = {0x6b, 0x61, 0x66, 0x62, 0xe1, 0x74, 0x75, 0x72, 0x00};
  24. /* Three characters translating to three utf-8 bytes each */
  25. static const u16 c3[] = {0x6f5c, 0x6c34, 0x8266, 0x00};
  26. /* Three letters translating to four utf-8 bytes each */
  27. static const u16 c4[] = {0xd801, 0xdc8d, 0xd801, 0xdc96, 0xd801, 0xdc87,
  28. 0x0000};
  29. /* Illegal utf-16 strings */
  30. static const u16 i1[] = {0x69, 0x31, 0xdc87, 0x6c, 0x00};
  31. static const u16 i2[] = {0x69, 0x32, 0xd801, 0xd801, 0x6c, 0x00};
  32. static const u16 i3[] = {0x69, 0x33, 0xd801, 0x00};
  33. /* Six characters translating to one utf-16 word each. */
  34. static const char d1[] = {0x55, 0x2d, 0x42, 0x6f, 0x6f, 0x74, 0x00};
  35. /* Eight characters translating to one utf-16 word each */
  36. static const char d2[] = {0x6b, 0x61, 0x66, 0x62, 0xc3, 0xa1, 0x74, 0x75,
  37. 0x72, 0x00};
  38. /* Three characters translating to one utf-16 word each */
  39. static const char d3[] = {0xe6, 0xbd, 0x9c, 0xe6, 0xb0, 0xb4, 0xe8, 0x89,
  40. 0xa6, 0x00};
  41. /* Three letters translating to two utf-16 word each */
  42. static const char d4[] = {0xf0, 0x90, 0x92, 0x8d, 0xf0, 0x90, 0x92, 0x96,
  43. 0xf0, 0x90, 0x92, 0x87, 0x00};
  44. /* Letter not in code page 437 */
  45. static const char d5[] = {0xCE, 0x92, 0x20, 0x69, 0x73, 0x20, 0x6E, 0x6F,
  46. 0x74, 0x20, 0x42, 0x00};
  47. /* Illegal utf-8 strings */
  48. static const char j1[] = {0x6a, 0x31, 0xa1, 0x6c, 0x00};
  49. static const char j2[] = {0x6a, 0x32, 0xc3, 0xc3, 0x6c, 0x00};
  50. static const char j3[] = {0x6a, 0x33, 0xf0, 0x90, 0xf0, 0x00};
  51. static const char j4[] = {0xa1, 0x00};
  52. static int unicode_test_u16_strlen(struct unit_test_state *uts)
  53. {
  54. ut_asserteq(6, u16_strlen(c1));
  55. ut_asserteq(8, u16_strlen(c2));
  56. ut_asserteq(3, u16_strlen(c3));
  57. ut_asserteq(6, u16_strlen(c4));
  58. return 0;
  59. }
  60. UNICODE_TEST(unicode_test_u16_strlen);
  61. static int unicode_test_u16_strdup(struct unit_test_state *uts)
  62. {
  63. u16 *copy = u16_strdup(c4);
  64. ut_assert(copy != c4);
  65. ut_asserteq_mem(copy, c4, sizeof(c4));
  66. free(copy);
  67. return 0;
  68. }
  69. UNICODE_TEST(unicode_test_u16_strdup);
  70. static int unicode_test_u16_strcpy(struct unit_test_state *uts)
  71. {
  72. u16 *r;
  73. u16 copy[10];
  74. r = u16_strcpy(copy, c1);
  75. ut_assert(r == copy);
  76. ut_asserteq_mem(copy, c1, sizeof(c1));
  77. return 0;
  78. }
  79. UNICODE_TEST(unicode_test_u16_strcpy);
  80. /* U-Boot uses UTF-16 strings in the EFI context only. */
  81. #if CONFIG_IS_ENABLED(EFI_LOADER) && !defined(API_BUILD)
  82. static int unicode_test_string16(struct unit_test_state *uts)
  83. {
  84. char buf[20];
  85. int ret;
  86. /* Test length and precision */
  87. memset(buf, 0xff, sizeof(buf));
  88. sprintf(buf, "%8.6ls", c2);
  89. ut_asserteq(' ', buf[1]);
  90. ut_assert(!strncmp(&buf[2], d2, 7));
  91. ut_assert(!buf[9]);
  92. memset(buf, 0xff, sizeof(buf));
  93. sprintf(buf, "%8.6ls", c4);
  94. ut_asserteq(' ', buf[4]);
  95. ut_assert(!strncmp(&buf[5], d4, 12));
  96. ut_assert(!buf[17]);
  97. memset(buf, 0xff, sizeof(buf));
  98. sprintf(buf, "%-8.2ls", c4);
  99. ut_asserteq(' ', buf[8]);
  100. ut_assert(!strncmp(buf, d4, 8));
  101. ut_assert(!buf[14]);
  102. /* Test handling of illegal utf-16 sequences */
  103. memset(buf, 0xff, sizeof(buf));
  104. sprintf(buf, "%ls", i1);
  105. ut_asserteq_str("i1?l", buf);
  106. memset(buf, 0xff, sizeof(buf));
  107. sprintf(buf, "%ls", i2);
  108. ut_asserteq_str("i2?l", buf);
  109. memset(buf, 0xff, sizeof(buf));
  110. sprintf(buf, "%ls", i3);
  111. ut_asserteq_str("i3?", buf);
  112. memset(buf, 0xff, sizeof(buf));
  113. ret = snprintf(buf, 4, "%ls", c1);
  114. ut_asserteq(6, ret);
  115. ut_asserteq_str("U-B", buf);
  116. memset(buf, 0xff, sizeof(buf));
  117. ret = snprintf(buf, 6, "%ls", c2);
  118. ut_asserteq_str("kafb", buf);
  119. ut_asserteq(9, ret);
  120. memset(buf, 0xff, sizeof(buf));
  121. ret = snprintf(buf, 7, "%ls", c2);
  122. ut_asserteq_str("kafb\xC3\xA1", buf);
  123. ut_asserteq(9, ret);
  124. memset(buf, 0xff, sizeof(buf));
  125. ret = snprintf(buf, 8, "%ls", c3);
  126. ut_asserteq_str("\xE6\xBD\x9C\xE6\xB0\xB4", buf);
  127. ut_asserteq(9, ret);
  128. memset(buf, 0xff, sizeof(buf));
  129. ret = snprintf(buf, 11, "%ls", c4);
  130. ut_asserteq_str("\xF0\x90\x92\x8D\xF0\x90\x92\x96", buf);
  131. ut_asserteq(12, ret);
  132. memset(buf, 0xff, sizeof(buf));
  133. ret = snprintf(buf, 4, "%ls", c4);
  134. ut_asserteq_str("", buf);
  135. ut_asserteq(12, ret);
  136. return 0;
  137. }
  138. UNICODE_TEST(unicode_test_string16);
  139. #endif
  140. static int unicode_test_utf8_get(struct unit_test_state *uts)
  141. {
  142. const char *s;
  143. s32 code;
  144. int i;
  145. /* Check characters less than 0x800 */
  146. s = d2;
  147. for (i = 0; i < 8; ++i) {
  148. code = utf8_get((const char **)&s);
  149. /* c2 is the utf-8 encoding of d2 */
  150. ut_asserteq(c2[i], code);
  151. if (!code)
  152. break;
  153. }
  154. ut_asserteq_ptr(s, d2 + 9)
  155. /* Check characters less than 0x10000 */
  156. s = d3;
  157. for (i = 0; i < 4; ++i) {
  158. code = utf8_get((const char **)&s);
  159. /* c3 is the utf-8 encoding of d3 */
  160. ut_asserteq(c3[i], code);
  161. if (!code)
  162. break;
  163. }
  164. ut_asserteq_ptr(s, d3 + 9)
  165. /* Check character greater 0xffff */
  166. s = d4;
  167. code = utf8_get((const char **)&s);
  168. ut_asserteq(0x0001048d, code);
  169. ut_asserteq_ptr(s, d4 + 4);
  170. /* Check illegal character */
  171. s = j4;
  172. code = utf8_get((const char **)&s);
  173. ut_asserteq(-1, code);
  174. ut_asserteq_ptr(j4 + 1, s);
  175. return 0;
  176. }
  177. UNICODE_TEST(unicode_test_utf8_get);
  178. static int unicode_test_utf8_put(struct unit_test_state *uts)
  179. {
  180. char buffer[8] = { 0, };
  181. char *pos;
  182. /* Commercial at, translates to one character */
  183. pos = buffer;
  184. ut_assert(!utf8_put('@', &pos))
  185. ut_asserteq(1, pos - buffer);
  186. ut_asserteq('@', buffer[0]);
  187. ut_assert(!buffer[1]);
  188. /* Latin letter G with acute, translates to two charactes */
  189. pos = buffer;
  190. ut_assert(!utf8_put(0x1f4, &pos));
  191. ut_asserteq(2, pos - buffer);
  192. ut_asserteq_str("\xc7\xb4", buffer);
  193. /* Tagalog letter i, translates to three characters */
  194. pos = buffer;
  195. ut_assert(!utf8_put(0x1701, &pos));
  196. ut_asserteq(3, pos - buffer);
  197. ut_asserteq_str("\xe1\x9c\x81", buffer);
  198. /* Hamster face, translates to four characters */
  199. pos = buffer;
  200. ut_assert(!utf8_put(0x1f439, &pos));
  201. ut_asserteq(4, pos - buffer);
  202. ut_asserteq_str("\xf0\x9f\x90\xb9", buffer);
  203. /* Illegal code */
  204. pos = buffer;
  205. ut_asserteq(-1, utf8_put(0xd888, &pos));
  206. return 0;
  207. }
  208. UNICODE_TEST(unicode_test_utf8_put);
  209. static int unicode_test_utf8_utf16_strlen(struct unit_test_state *uts)
  210. {
  211. ut_asserteq(6, utf8_utf16_strlen(d1));
  212. ut_asserteq(8, utf8_utf16_strlen(d2));
  213. ut_asserteq(3, utf8_utf16_strlen(d3));
  214. ut_asserteq(6, utf8_utf16_strlen(d4));
  215. /* illegal utf-8 sequences */
  216. ut_asserteq(4, utf8_utf16_strlen(j1));
  217. ut_asserteq(4, utf8_utf16_strlen(j2));
  218. ut_asserteq(3, utf8_utf16_strlen(j3));
  219. return 0;
  220. }
  221. UNICODE_TEST(unicode_test_utf8_utf16_strlen);
  222. static int unicode_test_utf8_utf16_strnlen(struct unit_test_state *uts)
  223. {
  224. ut_asserteq(3, utf8_utf16_strnlen(d1, 3));
  225. ut_asserteq(6, utf8_utf16_strnlen(d1, 13));
  226. ut_asserteq(6, utf8_utf16_strnlen(d2, 6));
  227. ut_asserteq(2, utf8_utf16_strnlen(d3, 2));
  228. ut_asserteq(4, utf8_utf16_strnlen(d4, 2));
  229. ut_asserteq(6, utf8_utf16_strnlen(d4, 3));
  230. /* illegal utf-8 sequences */
  231. ut_asserteq(4, utf8_utf16_strnlen(j1, 16));
  232. ut_asserteq(4, utf8_utf16_strnlen(j2, 16));
  233. ut_asserteq(3, utf8_utf16_strnlen(j3, 16));
  234. return 0;
  235. }
  236. UNICODE_TEST(unicode_test_utf8_utf16_strnlen);
  237. /**
  238. * ut_u16_strcmp() - Compare to u16 strings.
  239. *
  240. * @a1: first string
  241. * @a2: second string
  242. * @count: number of u16 to compare
  243. * Return: -1 if a1 < a2, 0 if a1 == a2, 1 if a1 > a2
  244. */
  245. static int unicode_test_u16_strcmp(const u16 *a1, const u16 *a2, size_t count)
  246. {
  247. for (; (*a1 || *a2) && count; ++a1, ++a2, --count) {
  248. if (*a1 < *a2)
  249. return -1;
  250. if (*a1 > *a2)
  251. return 1;
  252. }
  253. return 0;
  254. }
  255. static int unicode_test_utf8_utf16_strcpy(struct unit_test_state *uts)
  256. {
  257. u16 buf[16];
  258. u16 *pos;
  259. pos = buf;
  260. utf8_utf16_strcpy(&pos, d1);
  261. ut_asserteq(6, pos - buf);
  262. ut_assert(!unicode_test_u16_strcmp(buf, c1, SIZE_MAX));
  263. pos = buf;
  264. utf8_utf16_strcpy(&pos, d2);
  265. ut_asserteq(8, pos - buf);
  266. ut_assert(!unicode_test_u16_strcmp(buf, c2, SIZE_MAX));
  267. pos = buf;
  268. utf8_utf16_strcpy(&pos, d3);
  269. ut_asserteq(3, pos - buf);
  270. ut_assert(!unicode_test_u16_strcmp(buf, c3, SIZE_MAX));
  271. pos = buf;
  272. utf8_utf16_strcpy(&pos, d4);
  273. ut_asserteq(6, pos - buf);
  274. ut_assert(!unicode_test_u16_strcmp(buf, c4, SIZE_MAX));
  275. /* Illegal utf-8 strings */
  276. pos = buf;
  277. utf8_utf16_strcpy(&pos, j1);
  278. ut_asserteq(4, pos - buf);
  279. ut_assert(!unicode_test_u16_strcmp(buf, u"j1?l", SIZE_MAX));
  280. pos = buf;
  281. utf8_utf16_strcpy(&pos, j2);
  282. ut_asserteq(4, pos - buf);
  283. ut_assert(!unicode_test_u16_strcmp(buf, u"j2?l", SIZE_MAX));
  284. pos = buf;
  285. utf8_utf16_strcpy(&pos, j3);
  286. ut_asserteq(3, pos - buf);
  287. ut_assert(!unicode_test_u16_strcmp(buf, u"j3?", SIZE_MAX));
  288. return 0;
  289. }
  290. UNICODE_TEST(unicode_test_utf8_utf16_strcpy);
  291. static int unicode_test_utf8_utf16_strncpy(struct unit_test_state *uts)
  292. {
  293. u16 buf[16];
  294. u16 *pos;
  295. pos = buf;
  296. memset(buf, 0, sizeof(buf));
  297. utf8_utf16_strncpy(&pos, d1, 4);
  298. ut_asserteq(4, pos - buf);
  299. ut_assert(!buf[4]);
  300. ut_assert(!unicode_test_u16_strcmp(buf, c1, 4));
  301. pos = buf;
  302. memset(buf, 0, sizeof(buf));
  303. utf8_utf16_strncpy(&pos, d2, 10);
  304. ut_asserteq(8, pos - buf);
  305. ut_assert(buf[4]);
  306. ut_assert(!unicode_test_u16_strcmp(buf, c2, SIZE_MAX));
  307. pos = buf;
  308. memset(buf, 0, sizeof(buf));
  309. utf8_utf16_strncpy(&pos, d3, 2);
  310. ut_asserteq(2, pos - buf);
  311. ut_assert(!buf[2]);
  312. ut_assert(!unicode_test_u16_strcmp(buf, c3, 2));
  313. pos = buf;
  314. memset(buf, 0, sizeof(buf));
  315. utf8_utf16_strncpy(&pos, d4, 2);
  316. ut_asserteq(4, pos - buf);
  317. ut_assert(!buf[4]);
  318. ut_assert(!unicode_test_u16_strcmp(buf, c4, 4));
  319. pos = buf;
  320. memset(buf, 0, sizeof(buf));
  321. utf8_utf16_strncpy(&pos, d4, 10);
  322. ut_asserteq(6, pos - buf);
  323. ut_assert(buf[5]);
  324. ut_assert(!unicode_test_u16_strcmp(buf, c4, SIZE_MAX));
  325. return 0;
  326. }
  327. UNICODE_TEST(unicode_test_utf8_utf16_strncpy);
  328. static int unicode_test_utf16_get(struct unit_test_state *uts)
  329. {
  330. const u16 *s;
  331. s32 code;
  332. int i;
  333. /* Check characters less than 0x10000 */
  334. s = c2;
  335. for (i = 0; i < 9; ++i) {
  336. code = utf16_get((const u16 **)&s);
  337. ut_asserteq(c2[i], code);
  338. if (!code)
  339. break;
  340. }
  341. ut_asserteq_ptr(c2 + 8, s);
  342. /* Check character greater 0xffff */
  343. s = c4;
  344. code = utf16_get((const u16 **)&s);
  345. ut_asserteq(0x0001048d, code);
  346. ut_asserteq_ptr(c4 + 2, s);
  347. return 0;
  348. }
  349. UNICODE_TEST(unicode_test_utf16_get);
  350. static int unicode_test_utf16_put(struct unit_test_state *uts)
  351. {
  352. u16 buffer[4] = { 0, };
  353. u16 *pos;
  354. /* Commercial at, translates to one word */
  355. pos = buffer;
  356. ut_assert(!utf16_put('@', &pos));
  357. ut_asserteq(1, pos - buffer);
  358. ut_asserteq((u16)'@', buffer[0]);
  359. ut_assert(!buffer[1]);
  360. /* Hamster face, translates to two words */
  361. pos = buffer;
  362. ut_assert(!utf16_put(0x1f439, &pos));
  363. ut_asserteq(2, pos - buffer);
  364. ut_asserteq((u16)0xd83d, buffer[0]);
  365. ut_asserteq((u16)0xdc39, buffer[1]);
  366. ut_assert(!buffer[2]);
  367. /* Illegal code */
  368. pos = buffer;
  369. ut_asserteq(-1, utf16_put(0xd888, &pos));
  370. return 0;
  371. }
  372. UNICODE_TEST(unicode_test_utf16_put);
  373. static int unicode_test_utf16_strnlen(struct unit_test_state *uts)
  374. {
  375. ut_asserteq(3, utf16_strnlen(c1, 3));
  376. ut_asserteq(6, utf16_strnlen(c1, 13));
  377. ut_asserteq(6, utf16_strnlen(c2, 6));
  378. ut_asserteq(2, utf16_strnlen(c3, 2));
  379. ut_asserteq(2, utf16_strnlen(c4, 2));
  380. ut_asserteq(3, utf16_strnlen(c4, 3));
  381. /* illegal utf-16 word sequences */
  382. ut_asserteq(4, utf16_strnlen(i1, 16));
  383. ut_asserteq(4, utf16_strnlen(i2, 16));
  384. ut_asserteq(3, utf16_strnlen(i3, 16));
  385. return 0;
  386. }
  387. UNICODE_TEST(unicode_test_utf16_strnlen);
  388. static int unicode_test_utf16_utf8_strlen(struct unit_test_state *uts)
  389. {
  390. ut_asserteq(6, utf16_utf8_strlen(c1));
  391. ut_asserteq(9, utf16_utf8_strlen(c2));
  392. ut_asserteq(9, utf16_utf8_strlen(c3));
  393. ut_asserteq(12, utf16_utf8_strlen(c4));
  394. /* illegal utf-16 word sequences */
  395. ut_asserteq(4, utf16_utf8_strlen(i1));
  396. ut_asserteq(4, utf16_utf8_strlen(i2));
  397. ut_asserteq(3, utf16_utf8_strlen(i3));
  398. return 0;
  399. }
  400. UNICODE_TEST(unicode_test_utf16_utf8_strlen);
  401. static int unicode_test_utf16_utf8_strnlen(struct unit_test_state *uts)
  402. {
  403. ut_asserteq(3, utf16_utf8_strnlen(c1, 3));
  404. ut_asserteq(6, utf16_utf8_strnlen(c1, 13));
  405. ut_asserteq(7, utf16_utf8_strnlen(c2, 6));
  406. ut_asserteq(6, utf16_utf8_strnlen(c3, 2));
  407. ut_asserteq(8, utf16_utf8_strnlen(c4, 2));
  408. ut_asserteq(12, utf16_utf8_strnlen(c4, 3));
  409. return 0;
  410. }
  411. UNICODE_TEST(unicode_test_utf16_utf8_strnlen);
  412. static int unicode_test_utf16_utf8_strcpy(struct unit_test_state *uts)
  413. {
  414. char buf[16];
  415. char *pos;
  416. pos = buf;
  417. utf16_utf8_strcpy(&pos, c1);
  418. ut_asserteq(6, pos - buf);
  419. ut_asserteq_str(d1, buf);
  420. pos = buf;
  421. utf16_utf8_strcpy(&pos, c2);
  422. ut_asserteq(9, pos - buf);
  423. ut_asserteq_str(d2, buf);
  424. pos = buf;
  425. utf16_utf8_strcpy(&pos, c3);
  426. ut_asserteq(9, pos - buf);
  427. ut_asserteq_str(d3, buf);
  428. pos = buf;
  429. utf16_utf8_strcpy(&pos, c4);
  430. ut_asserteq(12, pos - buf);
  431. ut_asserteq_str(d4, buf);
  432. /* Illegal utf-16 strings */
  433. pos = buf;
  434. utf16_utf8_strcpy(&pos, i1);
  435. ut_asserteq(4, pos - buf);
  436. ut_asserteq_str("i1?l", buf);
  437. pos = buf;
  438. utf16_utf8_strcpy(&pos, i2);
  439. ut_asserteq(4, pos - buf);
  440. ut_asserteq_str("i2?l", buf);
  441. pos = buf;
  442. utf16_utf8_strcpy(&pos, i3);
  443. ut_asserteq(3, pos - buf);
  444. ut_asserteq_str("i3?", buf);
  445. return 0;
  446. }
  447. UNICODE_TEST(unicode_test_utf16_utf8_strcpy);
  448. static int unicode_test_utf16_utf8_strncpy(struct unit_test_state *uts)
  449. {
  450. char buf[16];
  451. char *pos;
  452. pos = buf;
  453. memset(buf, 0, sizeof(buf));
  454. utf16_utf8_strncpy(&pos, c1, 4);
  455. ut_asserteq(4, pos - buf);
  456. ut_assert(!buf[4]);
  457. ut_assert(!strncmp(buf, d1, 4));
  458. pos = buf;
  459. memset(buf, 0, sizeof(buf));
  460. utf16_utf8_strncpy(&pos, c2, 10);
  461. ut_asserteq(9, pos - buf);
  462. ut_assert(buf[4]);
  463. ut_assert(!strncmp(buf, d2, SIZE_MAX));
  464. pos = buf;
  465. memset(buf, 0, sizeof(buf));
  466. utf16_utf8_strncpy(&pos, c3, 2);
  467. ut_asserteq(6, pos - buf);
  468. ut_assert(!buf[6]);
  469. ut_assert(!strncmp(buf, d3, 6));
  470. pos = buf;
  471. memset(buf, 0, sizeof(buf));
  472. utf16_utf8_strncpy(&pos, c4, 2);
  473. ut_asserteq(8, pos - buf);
  474. ut_assert(!buf[8]);
  475. ut_assert(!strncmp(buf, d4, 8));
  476. pos = buf;
  477. memset(buf, 0, sizeof(buf));
  478. utf16_utf8_strncpy(&pos, c4, 10);
  479. ut_asserteq(12, pos - buf);
  480. ut_assert(buf[5]);
  481. ut_assert(!strncmp(buf, d4, SIZE_MAX));
  482. return 0;
  483. }
  484. UNICODE_TEST(unicode_test_utf16_utf8_strncpy);
  485. static int unicode_test_utf_to_lower(struct unit_test_state *uts)
  486. {
  487. ut_asserteq('@', utf_to_lower('@'));
  488. ut_asserteq('a', utf_to_lower('A'));
  489. ut_asserteq('z', utf_to_lower('Z'));
  490. ut_asserteq('[', utf_to_lower('['));
  491. ut_asserteq('m', utf_to_lower('m'));
  492. /* Latin letter O with diaresis (umlaut) */
  493. ut_asserteq(0x00f6, utf_to_lower(0x00d6));
  494. #ifdef CONFIG_EFI_UNICODE_CAPITALIZATION
  495. /* Cyrillic letter I*/
  496. ut_asserteq(0x0438, utf_to_lower(0x0418));
  497. #endif
  498. return 0;
  499. }
  500. UNICODE_TEST(unicode_test_utf_to_lower);
  501. static int unicode_test_utf_to_upper(struct unit_test_state *uts)
  502. {
  503. ut_asserteq('`', utf_to_upper('`'));
  504. ut_asserteq('A', utf_to_upper('a'));
  505. ut_asserteq('Z', utf_to_upper('z'));
  506. ut_asserteq('{', utf_to_upper('{'));
  507. ut_asserteq('M', utf_to_upper('M'));
  508. /* Latin letter O with diaresis (umlaut) */
  509. ut_asserteq(0x00d6, utf_to_upper(0x00f6));
  510. #ifdef CONFIG_EFI_UNICODE_CAPITALIZATION
  511. /* Cyrillic letter I */
  512. ut_asserteq(0x0418, utf_to_upper(0x0438));
  513. #endif
  514. return 0;
  515. }
  516. UNICODE_TEST(unicode_test_utf_to_upper);
  517. static int unicode_test_u16_strncmp(struct unit_test_state *uts)
  518. {
  519. ut_assert(u16_strncmp(u"abc", u"abc", 3) == 0);
  520. ut_assert(u16_strncmp(u"abcdef", u"abcghi", 3) == 0);
  521. ut_assert(u16_strncmp(u"abcdef", u"abcghi", 6) < 0);
  522. ut_assert(u16_strncmp(u"abcghi", u"abcdef", 6) > 0);
  523. ut_assert(u16_strcmp(u"abc", u"abc") == 0);
  524. ut_assert(u16_strcmp(u"abcdef", u"deghi") < 0);
  525. ut_assert(u16_strcmp(u"deghi", u"abcdef") > 0);
  526. return 0;
  527. }
  528. UNICODE_TEST(unicode_test_u16_strncmp);
  529. static int unicode_test_u16_strsize(struct unit_test_state *uts)
  530. {
  531. ut_asserteq_64(u16_strsize(c1), 14);
  532. ut_asserteq_64(u16_strsize(c2), 18);
  533. ut_asserteq_64(u16_strsize(c3), 8);
  534. ut_asserteq_64(u16_strsize(c4), 14);
  535. return 0;
  536. }
  537. UNICODE_TEST(unicode_test_u16_strsize);
  538. static int unicode_test_utf_to_cp(struct unit_test_state *uts)
  539. {
  540. int ret;
  541. s32 c;
  542. c = '\n';
  543. ret = utf_to_cp(&c, codepage_437);
  544. ut_asserteq(0, ret);
  545. ut_asserteq('\n', c);
  546. c = 'a';
  547. ret = utf_to_cp(&c, codepage_437);
  548. ut_asserteq(0, ret);
  549. ut_asserteq('a', c);
  550. c = 0x03c4; /* Greek small letter tau */
  551. ret = utf_to_cp(&c, codepage_437);
  552. ut_asserteq(0, ret);
  553. ut_asserteq(0xe7, c);
  554. c = 0x03a4; /* Greek capital letter tau */
  555. ret = utf_to_cp(&c, codepage_437);
  556. ut_asserteq(-ENOENT, ret);
  557. ut_asserteq('?', c);
  558. return 0;
  559. }
  560. UNICODE_TEST(unicode_test_utf_to_cp);
  561. static void utf8_to_cp437_stream_helper(const char *in, char *out)
  562. {
  563. char buffer[5];
  564. int ret;
  565. *buffer = 0;
  566. for (; *in; ++in) {
  567. ret = utf8_to_cp437_stream(*in, buffer);
  568. if (ret)
  569. *out++ = ret;
  570. }
  571. *out = 0;
  572. }
  573. static int unicode_test_utf8_to_cp437_stream(struct unit_test_state *uts)
  574. {
  575. char buf[16];
  576. utf8_to_cp437_stream_helper(d1, buf);
  577. ut_asserteq_str("U-Boot", buf);
  578. utf8_to_cp437_stream_helper(d2, buf);
  579. ut_asserteq_str("kafb\xa0tur", buf);
  580. utf8_to_cp437_stream_helper(d5, buf);
  581. ut_asserteq_str("? is not B", buf);
  582. utf8_to_cp437_stream_helper(j2, buf);
  583. ut_asserteq_str("j2l", buf);
  584. return 0;
  585. }
  586. UNICODE_TEST(unicode_test_utf8_to_cp437_stream);
  587. static void utf8_to_utf32_stream_helper(const char *in, s32 *out)
  588. {
  589. char buffer[5];
  590. int ret;
  591. *buffer = 0;
  592. for (; *in; ++in) {
  593. ret = utf8_to_utf32_stream(*in, buffer);
  594. if (ret)
  595. *out++ = ret;
  596. }
  597. *out = 0;
  598. }
  599. static int unicode_test_utf8_to_utf32_stream(struct unit_test_state *uts)
  600. {
  601. s32 buf[16];
  602. const u32 u1[] = {0x55, 0x2D, 0x42, 0x6F, 0x6F, 0x74, 0x0000};
  603. const u32 u2[] = {0x6B, 0x61, 0x66, 0x62, 0xE1, 0x74, 0x75, 0x72, 0x00};
  604. const u32 u3[] = {0x0392, 0x20, 0x69, 0x73, 0x20, 0x6E, 0x6F, 0x74,
  605. 0x20, 0x42, 0x00};
  606. const u32 u4[] = {0x6A, 0x32, 0x6C, 0x00};
  607. memset(buf, 0, sizeof(buf));
  608. utf8_to_utf32_stream_helper(d1, buf);
  609. ut_asserteq_mem(u1, buf, sizeof(u1));
  610. memset(buf, 0, sizeof(buf));
  611. utf8_to_utf32_stream_helper(d2, buf);
  612. ut_asserteq_mem(u2, buf, sizeof(u2));
  613. memset(buf, 0, sizeof(buf));
  614. utf8_to_utf32_stream_helper(d5, buf);
  615. ut_asserteq_mem(u3, buf, sizeof(u3));
  616. memset(buf, 0, sizeof(buf));
  617. utf8_to_utf32_stream_helper(j2, buf);
  618. ut_asserteq_mem(u4, buf, sizeof(u4));
  619. return 0;
  620. }
  621. UNICODE_TEST(unicode_test_utf8_to_utf32_stream);
  622. #ifdef CONFIG_EFI_LOADER
  623. static int unicode_test_efi_create_indexed_name(struct unit_test_state *uts)
  624. {
  625. u16 buf[16];
  626. u16 const expected[] = u"Capsule0AF9";
  627. u16 *pos;
  628. memset(buf, 0xeb, sizeof(buf));
  629. pos = efi_create_indexed_name(buf, sizeof(buf), "Capsule", 0x0af9);
  630. ut_asserteq_mem(expected, buf, sizeof(expected));
  631. ut_asserteq(pos - buf, u16_strnlen(buf, SIZE_MAX));
  632. return 0;
  633. }
  634. UNICODE_TEST(unicode_test_efi_create_indexed_name);
  635. #endif
  636. int do_ut_unicode(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
  637. {
  638. struct unit_test *tests = UNIT_TEST_SUITE_START(unicode_test);
  639. const int n_ents = UNIT_TEST_SUITE_COUNT(unicode_test);
  640. return cmd_ut_category("Unicode", "unicode_test_",
  641. tests, n_ents, argc, argv);
  642. }