rev |
line source |
shann@25699
|
1 --- a/iconvdata/Makefile
|
shann@25699
|
2 +++ b/iconvdata/Makefile
|
shann@25699
|
3 @@ -73,7 +73,7 @@
|
shann@25699
|
4 ifeq (yes,$(build-shared))
|
shann@25699
|
5 tests = bug-iconv1 bug-iconv2 tst-loading tst-e2big tst-iconv4 bug-iconv4 \
|
shann@25699
|
6 tst-iconv6 bug-iconv5 bug-iconv6 tst-iconv7 bug-iconv8 bug-iconv9 \
|
shann@25699
|
7 - bug-iconv10 bug-iconv11 bug-iconv12
|
shann@25699
|
8 + bug-iconv10 bug-iconv11 bug-iconv12 tst-iconv-iso-2022-cn-ext
|
shann@25699
|
9 ifeq ($(have-thread-library),yes)
|
shann@25699
|
10 tests += bug-iconv3
|
shann@25699
|
11 endif
|
shann@25699
|
12 @@ -316,6 +316,8 @@
|
shann@25699
|
13 $(addprefix $(objpfx),$(modules.so))
|
shann@25699
|
14 $(objpfx)bug-iconv12.out: $(objpfx)gconv-modules \
|
shann@25699
|
15 $(addprefix $(objpfx),$(modules.so))
|
shann@25699
|
16 +$(objpfx)tst-iconv-iso-2022-cn-ext.out: $(addprefix $(objpfx), $(gconv-modules)) \
|
shann@25699
|
17 + $(addprefix $(objpfx),$(modules.so))
|
shann@25699
|
18
|
shann@25699
|
19 $(objpfx)iconv-test.out: run-iconv-test.sh $(objpfx)gconv-modules \
|
shann@25699
|
20 $(addprefix $(objpfx),$(modules.so)) \
|
shann@25699
|
21 diff --git a/iconvdata/iso-2022-cn-ext.c b/iconvdata/iso-2022-cn-ext.c
|
shann@25699
|
22 index 947b807421..34e1010bed 100644
|
shann@25699
|
23 --- a/iconvdata/iso-2022-cn-ext.c
|
shann@25699
|
24 +++ b/iconvdata/iso-2022-cn-ext.c
|
shann@25699
|
25 @@ -575,6 +575,12 @@ DIAG_IGNORE_Os_NEEDS_COMMENT (5, "-Wmaybe-uninitialized");
|
shann@25699
|
26 { \
|
shann@25699
|
27 const char *escseq; \
|
shann@25699
|
28 \
|
shann@25699
|
29 + if (outptr + 4 > outend) \
|
shann@25699
|
30 + { \
|
shann@25699
|
31 + result = __GCONV_FULL_OUTPUT; \
|
shann@25699
|
32 + break; \
|
shann@25699
|
33 + } \
|
shann@25699
|
34 + \
|
shann@25699
|
35 assert (used == CNS11643_2_set); /* XXX */ \
|
shann@25699
|
36 escseq = "*H"; \
|
shann@25699
|
37 *outptr++ = ESC; \
|
shann@25699
|
38 @@ -588,6 +594,12 @@ DIAG_IGNORE_Os_NEEDS_COMMENT (5, "-Wmaybe-uninitialized");
|
shann@25699
|
39 { \
|
shann@25699
|
40 const char *escseq; \
|
shann@25699
|
41 \
|
shann@25699
|
42 + if (outptr + 4 > outend) \
|
shann@25699
|
43 + { \
|
shann@25699
|
44 + result = __GCONV_FULL_OUTPUT; \
|
shann@25699
|
45 + break; \
|
shann@25699
|
46 + } \
|
shann@25699
|
47 + \
|
shann@25699
|
48 assert ((used >> 5) >= 3 && (used >> 5) <= 7); \
|
shann@25699
|
49 escseq = "+I+J+K+L+M" + ((used >> 5) - 3) * 2; \
|
shann@25699
|
50 *outptr++ = ESC; \
|
shann@25699
|
51 diff --git a/iconvdata/tst-iconv-iso-2022-cn-ext.c b/iconvdata/tst-iconv-iso-2022-cn-ext.c
|
shann@25699
|
52 new file mode 100644
|
shann@25699
|
53 index 0000000000..96a8765fd5
|
shann@25699
|
54 --- /dev/null
|
shann@25699
|
55 +++ b/iconvdata/tst-iconv-iso-2022-cn-ext.c
|
shann@25699
|
56 @@ -0,0 +1,128 @@
|
shann@25699
|
57 +/* Verify ISO-2022-CN-EXT does not write out of the bounds.
|
shann@25699
|
58 + Copyright (C) 2024 Free Software Foundation, Inc.
|
shann@25699
|
59 + This file is part of the GNU C Library.
|
shann@25699
|
60 +
|
shann@25699
|
61 + The GNU C Library is free software; you can redistribute it and/or
|
shann@25699
|
62 + modify it under the terms of the GNU Lesser General Public
|
shann@25699
|
63 + License as published by the Free Software Foundation; either
|
shann@25699
|
64 + version 2.1 of the License, or (at your option) any later version.
|
shann@25699
|
65 +
|
shann@25699
|
66 + The GNU C Library is distributed in the hope that it will be useful,
|
shann@25699
|
67 + but WITHOUT ANY WARRANTY; without even the implied warranty of
|
shann@25699
|
68 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
shann@25699
|
69 + Lesser General Public License for more details.
|
shann@25699
|
70 +
|
shann@25699
|
71 + You should have received a copy of the GNU Lesser General Public
|
shann@25699
|
72 + License along with the GNU C Library; if not, see
|
shann@25699
|
73 + <https://www.gnu.org/licenses/>. */
|
shann@25699
|
74 +
|
shann@25699
|
75 +#include <stdio.h>
|
shann@25699
|
76 +#include <string.h>
|
shann@25699
|
77 +
|
shann@25699
|
78 +#include <errno.h>
|
shann@25699
|
79 +#include <iconv.h>
|
shann@25699
|
80 +#include <sys/mman.h>
|
shann@25699
|
81 +
|
shann@25699
|
82 +#include <support/xunistd.h>
|
shann@25699
|
83 +#include <support/check.h>
|
shann@25699
|
84 +#include <support/support.h>
|
shann@25699
|
85 +
|
shann@25699
|
86 +/* The test sets up a two memory page buffer with the second page marked
|
shann@25699
|
87 + PROT_NONE to trigger a fault if the conversion writes beyond the exact
|
shann@25699
|
88 + expected amount. Then we carry out various conversions and precisely
|
shann@25699
|
89 + place the start of the output buffer in order to trigger a SIGSEGV if the
|
shann@25699
|
90 + process writes anywhere between 1 and page sized bytes more (only one
|
shann@25699
|
91 + PROT_NONE page is setup as a canary) than expected. These tests exercise
|
shann@25699
|
92 + all three of the cases in ISO-2022-CN-EXT where the converter must switch
|
shann@25699
|
93 + character sets and may run out of buffer space while doing the
|
shann@25699
|
94 + operation. */
|
shann@25699
|
95 +
|
shann@25699
|
96 +static int
|
shann@25699
|
97 +do_test (void)
|
shann@25699
|
98 +{
|
shann@25699
|
99 + iconv_t cd = iconv_open ("ISO-2022-CN-EXT", "UTF-8");
|
shann@25699
|
100 + TEST_VERIFY_EXIT (cd != (iconv_t) -1);
|
shann@25699
|
101 +
|
shann@25699
|
102 + char *ntf;
|
shann@25699
|
103 + size_t ntfsize;
|
shann@25699
|
104 + char *outbufbase;
|
shann@25699
|
105 + {
|
shann@25699
|
106 + int pgz = getpagesize ();
|
shann@25699
|
107 + TEST_VERIFY_EXIT (pgz > 0);
|
shann@25699
|
108 + ntfsize = 2 * pgz;
|
shann@25699
|
109 +
|
shann@25699
|
110 + ntf = xmmap (NULL, ntfsize, PROT_READ | PROT_WRITE, MAP_PRIVATE
|
shann@25699
|
111 + | MAP_ANONYMOUS, -1);
|
shann@25699
|
112 + xmprotect (ntf + pgz, pgz, PROT_NONE);
|
shann@25699
|
113 +
|
shann@25699
|
114 + outbufbase = ntf + pgz;
|
shann@25699
|
115 + }
|
shann@25699
|
116 +
|
shann@25699
|
117 + /* Check if SOdesignation escape sequence does not trigger an OOB write. */
|
shann@25699
|
118 + {
|
shann@25699
|
119 + char inbuf[] = "\xe4\xba\xa4\xe6\x8d\xa2";
|
shann@25699
|
120 +
|
shann@25699
|
121 + for (int i = 0; i < 9; i++)
|
shann@25699
|
122 + {
|
shann@25699
|
123 + char *inp = inbuf;
|
shann@25699
|
124 + size_t inleft = sizeof (inbuf) - 1;
|
shann@25699
|
125 +
|
shann@25699
|
126 + char *outp = outbufbase - i;
|
shann@25699
|
127 + size_t outleft = i;
|
shann@25699
|
128 +
|
shann@25699
|
129 + TEST_VERIFY_EXIT (iconv (cd, &inp, &inleft, &outp, &outleft)
|
shann@25699
|
130 + == (size_t) -1);
|
shann@25699
|
131 + TEST_COMPARE (errno, E2BIG);
|
shann@25699
|
132 +
|
shann@25699
|
133 + TEST_VERIFY_EXIT (iconv (cd, NULL, NULL, NULL, NULL) == 0);
|
shann@25699
|
134 + }
|
shann@25699
|
135 + }
|
shann@25699
|
136 +
|
shann@25699
|
137 + /* Same as before for SS2designation. */
|
shann@25699
|
138 + {
|
shann@25699
|
139 + char inbuf[] = "ã´½ \xe3\xb4\xbd";
|
shann@25699
|
140 +
|
shann@25699
|
141 + for (int i = 0; i < 14; i++)
|
shann@25699
|
142 + {
|
shann@25699
|
143 + char *inp = inbuf;
|
shann@25699
|
144 + size_t inleft = sizeof (inbuf) - 1;
|
shann@25699
|
145 +
|
shann@25699
|
146 + char *outp = outbufbase - i;
|
shann@25699
|
147 + size_t outleft = i;
|
shann@25699
|
148 +
|
shann@25699
|
149 + TEST_VERIFY_EXIT (iconv (cd, &inp, &inleft, &outp, &outleft)
|
shann@25699
|
150 + == (size_t) -1);
|
shann@25699
|
151 + TEST_COMPARE (errno, E2BIG);
|
shann@25699
|
152 +
|
shann@25699
|
153 + TEST_VERIFY_EXIT (iconv (cd, NULL, NULL, NULL, NULL) == 0);
|
shann@25699
|
154 + }
|
shann@25699
|
155 + }
|
shann@25699
|
156 +
|
shann@25699
|
157 + /* Same as before for SS3designation. */
|
shann@25699
|
158 + {
|
shann@25699
|
159 + char inbuf[] = "å \xe5\x8a\x84";
|
shann@25699
|
160 +
|
shann@25699
|
161 + for (int i = 0; i < 14; i++)
|
shann@25699
|
162 + {
|
shann@25699
|
163 + char *inp = inbuf;
|
shann@25699
|
164 + size_t inleft = sizeof (inbuf) - 1;
|
shann@25699
|
165 +
|
shann@25699
|
166 + char *outp = outbufbase - i;
|
shann@25699
|
167 + size_t outleft = i;
|
shann@25699
|
168 +
|
shann@25699
|
169 + TEST_VERIFY_EXIT (iconv (cd, &inp, &inleft, &outp, &outleft)
|
shann@25699
|
170 + == (size_t) -1);
|
shann@25699
|
171 + TEST_COMPARE (errno, E2BIG);
|
shann@25699
|
172 +
|
shann@25699
|
173 + TEST_VERIFY_EXIT (iconv (cd, NULL, NULL, NULL, NULL) == 0);
|
shann@25699
|
174 + }
|
shann@25699
|
175 + }
|
shann@25699
|
176 +
|
shann@25699
|
177 + TEST_VERIFY_EXIT (iconv_close (cd) != -1);
|
shann@25699
|
178 +
|
shann@25699
|
179 + xmunmap (ntf, ntfsize);
|
shann@25699
|
180 +
|
shann@25699
|
181 + return 0;
|
shann@25699
|
182 +}
|
shann@25699
|
183 +
|
shann@25699
|
184 +#include <support/test-driver.c>
|
shann@25699
|
185 --
|
shann@25699
|
186 2.39.3
|