]>
Commit | Line | Data |
---|---|---|
1c9633d6 DH |
1 | /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/ |
2 | /*** | |
3 | This file is part of systemd. | |
4 | ||
5 | Copyright (C) 2014 David Herrmann <dh.herrmann@gmail.com> | |
6 | ||
7 | systemd is free software; you can redistribute it and/or modify it | |
8 | under the terms of the GNU Lesser General Public License as published by | |
9 | the Free Software Foundation; either version 2.1 of the License, or | |
10 | (at your option) any later version. | |
11 | ||
12 | systemd is distributed in the hope that it will be useful, but | |
13 | WITHOUT ANY WARRANTY; without even the implied warranty of | |
14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
15 | Lesser General Public License for more details. | |
16 | ||
17 | You should have received a copy of the GNU Lesser General Public License | |
18 | along with systemd; If not, see <http://www.gnu.org/licenses/>. | |
19 | ***/ | |
20 | ||
21 | /* | |
22 | * Terminal Parser Tests | |
23 | */ | |
24 | ||
25 | #include <assert.h> | |
26 | #include <errno.h> | |
27 | #include <stdio.h> | |
28 | #include <stdlib.h> | |
29 | #include <string.h> | |
30 | #include "macro.h" | |
31 | #include "term-internal.h" | |
32 | #include "util.h" | |
33 | ||
34 | static void test_term_utf8_invalid(void) { | |
35 | term_utf8 p = { }; | |
f1f5b2a3 | 36 | uint32_t *res; |
1c9633d6 DH |
37 | size_t len; |
38 | ||
f1f5b2a3 DH |
39 | len = term_utf8_decode(NULL, NULL, 0); |
40 | assert_se(!len); | |
1c9633d6 | 41 | |
f1f5b2a3 DH |
42 | len = term_utf8_decode(&p, NULL, 0); |
43 | assert_se(len == 1); | |
1c9633d6 | 44 | |
f1f5b2a3 DH |
45 | res = NULL; |
46 | len = term_utf8_decode(NULL, &res, 0); | |
47 | assert_se(!len); | |
1c9633d6 | 48 | assert_se(res != NULL); |
f1f5b2a3 DH |
49 | assert_se(!*res); |
50 | ||
51 | len = term_utf8_decode(&p, &res, 0); | |
1c9633d6 | 52 | assert_se(len == 1); |
f1f5b2a3 DH |
53 | assert_se(res != NULL); |
54 | assert_se(!*res); | |
1c9633d6 | 55 | |
f1f5b2a3 | 56 | len = term_utf8_decode(&p, &res, 0xCf); |
1c9633d6 | 57 | assert_se(len == 0); |
1c9633d6 | 58 | assert_se(res != NULL); |
f1f5b2a3 DH |
59 | assert_se(!*res); |
60 | ||
61 | len = term_utf8_decode(&p, &res, 0); | |
1c9633d6 | 62 | assert_se(len == 2); |
f1f5b2a3 DH |
63 | assert_se(res != NULL); |
64 | assert_se(res[0] == 0xCf && res[1] == 0); | |
1c9633d6 DH |
65 | } |
66 | ||
67 | static void test_term_utf8_range(void) { | |
68 | term_utf8 p = { }; | |
f1f5b2a3 | 69 | uint32_t *res; |
1c9633d6 DH |
70 | char u8[4]; |
71 | uint32_t i, j; | |
72 | size_t ulen, len; | |
73 | ||
74 | /* Convert all ucs-4 chars to utf-8 and back */ | |
75 | ||
76 | for (i = 0; i < 0x10FFFF; ++i) { | |
77 | ulen = term_utf8_encode(u8, i); | |
78 | if (!ulen) | |
79 | continue; | |
80 | ||
81 | for (j = 0; j < ulen; ++j) { | |
f1f5b2a3 DH |
82 | len = term_utf8_decode(&p, &res, u8[j]); |
83 | if (len < 1) { | |
1c9633d6 DH |
84 | assert_se(j + 1 != ulen); |
85 | continue; | |
86 | } | |
87 | ||
88 | assert_se(j + 1 == ulen); | |
89 | assert_se(len == 1 && *res == i); | |
90 | assert_se(i <= 127 || ulen >= 2); | |
91 | } | |
92 | } | |
93 | } | |
94 | ||
95 | static void test_term_utf8_mix(void) { | |
96 | static const char source[] = { | |
97 | 0x00, /* normal 0 */ | |
98 | 0xC0, 0x80, /* overlong 0 */ | |
99 | 0xC0, 0x81, /* overlong 1 */ | |
100 | 0xE0, 0x80, 0x81, /* overlong 1 */ | |
101 | 0xF0, 0x80, 0x80, 0x81, /* overlong 1 */ | |
102 | 0xC0, 0x00, /* invalid continuation */ | |
103 | 0xC0, 0xC0, 0x81, /* invalid continuation with a following overlong 1 */ | |
104 | 0xF8, 0x80, 0x80, 0x80, 0x81, /* overlong 1 with 5 bytes */ | |
105 | 0xE0, 0x80, 0xC0, 0x81, /* invalid 3-byte followed by valid 2-byte */ | |
106 | 0xF0, 0x80, 0x80, 0xC0, 0x81, /* invalid 4-byte followed by valid 2-byte */ | |
107 | }; | |
108 | static const uint32_t result[] = { | |
109 | 0x0000, | |
110 | 0x0000, | |
111 | 0x0001, | |
112 | 0x0001, | |
113 | 0x0001, | |
114 | 0x00C0, 0x0000, | |
115 | 0x00C0, 0x0001, | |
116 | 0x00F8, 0x0080, 0x0080, 0x0080, 0x0081, | |
117 | 0x00E0, 0x0080, 0x0001, | |
118 | 0x00F0, 0x0080, 0x0080, 0x0001, | |
119 | }; | |
120 | term_utf8 p = { }; | |
f1f5b2a3 | 121 | uint32_t *res; |
1c9633d6 DH |
122 | unsigned int i, j; |
123 | size_t len; | |
124 | ||
125 | for (i = 0, j = 0; i < sizeof(source); ++i) { | |
f1f5b2a3 DH |
126 | len = term_utf8_decode(&p, &res, source[i]); |
127 | if (len < 1) | |
1c9633d6 DH |
128 | continue; |
129 | ||
130 | assert_se(j + len <= ELEMENTSOF(result)); | |
131 | assert_se(!memcmp(res, &result[j], sizeof(uint32_t) * len)); | |
132 | j += len; | |
133 | } | |
134 | ||
135 | assert_se(j == ELEMENTSOF(result)); | |
136 | } | |
137 | ||
138 | int main(int argc, char *argv[]) { | |
139 | test_term_utf8_invalid(); | |
140 | test_term_utf8_range(); | |
141 | test_term_utf8_mix(); | |
142 | ||
143 | return 0; | |
144 | } |