blob: 197605b012e5c6d9112d7b7be24f62cb386f8073 [file] [log] [blame]
Antoine Pitrou0a3229d2011-11-21 20:39:13 +01001/* stringlib: codec implementations */
2
Serhiy Storchakabcde10a2016-05-16 09:42:29 +03003#if !STRINGLIB_IS_UNICODE
4# error "codecs.h is specific to Unicode"
5#endif
Antoine Pitrou0a3229d2011-11-21 20:39:13 +01006
Victor Stinnerc6b292c2020-06-08 16:30:33 +02007#include "pycore_bitutils.h" // _Py_bswap32()
Victor Stinner1ae035b2020-04-17 17:47:20 +02008
Antoine Pitrou0a3229d2011-11-21 20:39:13 +01009/* Mask to quickly check whether a C 'long' contains a
10 non-ASCII, UTF8-encoded char. */
11#if (SIZEOF_LONG == 8)
Mark Dickinson01ac8b62012-07-07 14:08:48 +020012# define ASCII_CHAR_MASK 0x8080808080808080UL
Antoine Pitrou0a3229d2011-11-21 20:39:13 +010013#elif (SIZEOF_LONG == 4)
Mark Dickinson01ac8b62012-07-07 14:08:48 +020014# define ASCII_CHAR_MASK 0x80808080UL
Antoine Pitrou0a3229d2011-11-21 20:39:13 +010015#else
16# error C 'long' size should be either 4 or 8!
17#endif
18
Mark Dickinson106c4142012-06-23 21:45:14 +010019/* 10xxxxxx */
20#define IS_CONTINUATION_BYTE(ch) ((ch) >= 0x80 && (ch) < 0xC0)
21
Antoine Pitrouca5f91b2012-05-10 16:36:02 +020022Py_LOCAL_INLINE(Py_UCS4)
23STRINGLIB(utf8_decode)(const char **inptr, const char *end,
24 STRINGLIB_CHAR *dest,
25 Py_ssize_t *outpos)
Antoine Pitrou0a3229d2011-11-21 20:39:13 +010026{
Antoine Pitrouca5f91b2012-05-10 16:36:02 +020027 Py_UCS4 ch;
28 const char *s = *inptr;
Antoine Pitrouca8aa4a2012-09-20 20:56:47 +020029 const char *aligned_end = (const char *) _Py_ALIGN_DOWN(end, SIZEOF_LONG);
Antoine Pitrouca5f91b2012-05-10 16:36:02 +020030 STRINGLIB_CHAR *p = dest + *outpos;
Antoine Pitrou0a3229d2011-11-21 20:39:13 +010031
32 while (s < end) {
Antoine Pitrouca5f91b2012-05-10 16:36:02 +020033 ch = (unsigned char)*s;
Antoine Pitrou0a3229d2011-11-21 20:39:13 +010034
35 if (ch < 0x80) {
36 /* Fast path for runs of ASCII characters. Given that common UTF-8
37 input will consist of an overwhelming majority of ASCII
38 characters, we try to optimize for this case by checking
39 as many characters as a C 'long' can contain.
40 First, check if we can do an aligned read, as most CPUs have
41 a penalty for unaligned reads.
42 */
Antoine Pitrouca8aa4a2012-09-20 20:56:47 +020043 if (_Py_IS_ALIGNED(s, SIZEOF_LONG)) {
Antoine Pitrou0a3229d2011-11-21 20:39:13 +010044 /* Help register allocation */
Antoine Pitrou9ed5f272013-08-13 20:18:52 +020045 const char *_s = s;
46 STRINGLIB_CHAR *_p = p;
Antoine Pitrou0a3229d2011-11-21 20:39:13 +010047 while (_s < aligned_end) {
48 /* Read a whole long at a time (either 4 or 8 bytes),
49 and do a fast unrolled copy if it only contains ASCII
50 characters. */
Andy Lestere6be9b52020-02-11 20:28:35 -060051 unsigned long value = *(const unsigned long *) _s;
Antoine Pitrou0a3229d2011-11-21 20:39:13 +010052 if (value & ASCII_CHAR_MASK)
53 break;
Christian Heimes743e0cd2012-10-17 23:52:17 +020054#if PY_LITTLE_ENDIAN
Antoine Pitrouca5f91b2012-05-10 16:36:02 +020055 _p[0] = (STRINGLIB_CHAR)(value & 0xFFu);
56 _p[1] = (STRINGLIB_CHAR)((value >> 8) & 0xFFu);
57 _p[2] = (STRINGLIB_CHAR)((value >> 16) & 0xFFu);
58 _p[3] = (STRINGLIB_CHAR)((value >> 24) & 0xFFu);
59# if SIZEOF_LONG == 8
60 _p[4] = (STRINGLIB_CHAR)((value >> 32) & 0xFFu);
61 _p[5] = (STRINGLIB_CHAR)((value >> 40) & 0xFFu);
62 _p[6] = (STRINGLIB_CHAR)((value >> 48) & 0xFFu);
63 _p[7] = (STRINGLIB_CHAR)((value >> 56) & 0xFFu);
64# endif
65#else
66# if SIZEOF_LONG == 8
67 _p[0] = (STRINGLIB_CHAR)((value >> 56) & 0xFFu);
68 _p[1] = (STRINGLIB_CHAR)((value >> 48) & 0xFFu);
69 _p[2] = (STRINGLIB_CHAR)((value >> 40) & 0xFFu);
70 _p[3] = (STRINGLIB_CHAR)((value >> 32) & 0xFFu);
71 _p[4] = (STRINGLIB_CHAR)((value >> 24) & 0xFFu);
72 _p[5] = (STRINGLIB_CHAR)((value >> 16) & 0xFFu);
73 _p[6] = (STRINGLIB_CHAR)((value >> 8) & 0xFFu);
74 _p[7] = (STRINGLIB_CHAR)(value & 0xFFu);
75# else
76 _p[0] = (STRINGLIB_CHAR)((value >> 24) & 0xFFu);
77 _p[1] = (STRINGLIB_CHAR)((value >> 16) & 0xFFu);
78 _p[2] = (STRINGLIB_CHAR)((value >> 8) & 0xFFu);
79 _p[3] = (STRINGLIB_CHAR)(value & 0xFFu);
80# endif
Antoine Pitrou0a3229d2011-11-21 20:39:13 +010081#endif
82 _s += SIZEOF_LONG;
83 _p += SIZEOF_LONG;
84 }
85 s = _s;
86 p = _p;
87 if (s == end)
88 break;
89 ch = (unsigned char)*s;
90 }
Antoine Pitrouca5f91b2012-05-10 16:36:02 +020091 if (ch < 0x80) {
92 s++;
93 *p++ = ch;
94 continue;
95 }
Antoine Pitrou0a3229d2011-11-21 20:39:13 +010096 }
97
Antoine Pitrouca5f91b2012-05-10 16:36:02 +020098 if (ch < 0xE0) {
99 /* \xC2\x80-\xDF\xBF -- 0080-07FF */
Victor Stinnerab60de42012-11-04 23:59:15 +0100100 Py_UCS4 ch2;
Ezio Melottif7ed5d12012-11-04 23:21:38 +0200101 if (ch < 0xC2) {
102 /* invalid sequence
103 \x80-\xBF -- continuation byte
104 \xC0-\xC1 -- fake 0000-007F */
105 goto InvalidStart;
106 }
Antoine Pitrouca5f91b2012-05-10 16:36:02 +0200107 if (end - s < 2) {
108 /* unexpected end of data: the caller will decide whether
109 it's an error or not */
110 break;
111 }
112 ch2 = (unsigned char)s[1];
Mark Dickinson106c4142012-06-23 21:45:14 +0100113 if (!IS_CONTINUATION_BYTE(ch2))
Antoine Pitrouca5f91b2012-05-10 16:36:02 +0200114 /* invalid continuation byte */
Ezio Melottif7ed5d12012-11-04 23:21:38 +0200115 goto InvalidContinuation1;
Antoine Pitrouca5f91b2012-05-10 16:36:02 +0200116 ch = (ch << 6) + ch2 -
117 ((0xC0 << 6) + 0x80);
118 assert ((ch > 0x007F) && (ch <= 0x07FF));
119 s += 2;
120 if (STRINGLIB_MAX_CHAR <= 0x007F ||
121 (STRINGLIB_MAX_CHAR < 0x07FF && ch > STRINGLIB_MAX_CHAR))
Ezio Melottif7ed5d12012-11-04 23:21:38 +0200122 /* Out-of-range */
123 goto Return;
Antoine Pitrou0a3229d2011-11-21 20:39:13 +0100124 *p++ = ch;
125 continue;
126 }
127
Antoine Pitrouca5f91b2012-05-10 16:36:02 +0200128 if (ch < 0xF0) {
129 /* \xE0\xA0\x80-\xEF\xBF\xBF -- 0800-FFFF */
130 Py_UCS4 ch2, ch3;
131 if (end - s < 3) {
132 /* unexpected end of data: the caller will decide whether
133 it's an error or not */
Ezio Melottif7ed5d12012-11-04 23:21:38 +0200134 if (end - s < 2)
135 break;
136 ch2 = (unsigned char)s[1];
137 if (!IS_CONTINUATION_BYTE(ch2) ||
138 (ch2 < 0xA0 ? ch == 0xE0 : ch == 0xED))
139 /* for clarification see comments below */
140 goto InvalidContinuation1;
Antoine Pitrouca5f91b2012-05-10 16:36:02 +0200141 break;
Antoine Pitrou0a3229d2011-11-21 20:39:13 +0100142 }
Antoine Pitrouca5f91b2012-05-10 16:36:02 +0200143 ch2 = (unsigned char)s[1];
144 ch3 = (unsigned char)s[2];
Ezio Melottif7ed5d12012-11-04 23:21:38 +0200145 if (!IS_CONTINUATION_BYTE(ch2)) {
Antoine Pitrouca5f91b2012-05-10 16:36:02 +0200146 /* invalid continuation byte */
Ezio Melottif7ed5d12012-11-04 23:21:38 +0200147 goto InvalidContinuation1;
Antoine Pitrouca5f91b2012-05-10 16:36:02 +0200148 }
149 if (ch == 0xE0) {
150 if (ch2 < 0xA0)
151 /* invalid sequence
152 \xE0\x80\x80-\xE0\x9F\xBF -- fake 0000-0800 */
Ezio Melottif7ed5d12012-11-04 23:21:38 +0200153 goto InvalidContinuation1;
154 } else if (ch == 0xED && ch2 >= 0xA0) {
Antoine Pitrouca5f91b2012-05-10 16:36:02 +0200155 /* Decoding UTF-8 sequences in range \xED\xA0\x80-\xED\xBF\xBF
156 will result in surrogates in range D800-DFFF. Surrogates are
157 not valid UTF-8 so they are rejected.
Benjamin Peterson51796e52020-03-10 21:10:59 -0700158 See https://www.unicode.org/versions/Unicode5.2.0/ch03.pdf
Antoine Pitrouca5f91b2012-05-10 16:36:02 +0200159 (table 3-7) and http://www.rfc-editor.org/rfc/rfc3629.txt */
Ezio Melottif7ed5d12012-11-04 23:21:38 +0200160 goto InvalidContinuation1;
161 }
162 if (!IS_CONTINUATION_BYTE(ch3)) {
163 /* invalid continuation byte */
164 goto InvalidContinuation2;
Antoine Pitrouca5f91b2012-05-10 16:36:02 +0200165 }
166 ch = (ch << 12) + (ch2 << 6) + ch3 -
167 ((0xE0 << 12) + (0x80 << 6) + 0x80);
Antoine Pitrou0a3229d2011-11-21 20:39:13 +0100168 assert ((ch > 0x07FF) && (ch <= 0xFFFF));
169 s += 3;
Antoine Pitrouca5f91b2012-05-10 16:36:02 +0200170 if (STRINGLIB_MAX_CHAR <= 0x07FF ||
171 (STRINGLIB_MAX_CHAR < 0xFFFF && ch > STRINGLIB_MAX_CHAR))
Ezio Melottif7ed5d12012-11-04 23:21:38 +0200172 /* Out-of-range */
173 goto Return;
Antoine Pitrou0a3229d2011-11-21 20:39:13 +0100174 *p++ = ch;
Antoine Pitrouca5f91b2012-05-10 16:36:02 +0200175 continue;
Antoine Pitrou0a3229d2011-11-21 20:39:13 +0100176 }
Antoine Pitrouca5f91b2012-05-10 16:36:02 +0200177
178 if (ch < 0xF5) {
179 /* \xF0\x90\x80\x80-\xF4\x8F\xBF\xBF -- 10000-10FFFF */
180 Py_UCS4 ch2, ch3, ch4;
181 if (end - s < 4) {
182 /* unexpected end of data: the caller will decide whether
183 it's an error or not */
Ezio Melottif7ed5d12012-11-04 23:21:38 +0200184 if (end - s < 2)
185 break;
186 ch2 = (unsigned char)s[1];
187 if (!IS_CONTINUATION_BYTE(ch2) ||
188 (ch2 < 0x90 ? ch == 0xF0 : ch == 0xF4))
189 /* for clarification see comments below */
190 goto InvalidContinuation1;
191 if (end - s < 3)
192 break;
193 ch3 = (unsigned char)s[2];
194 if (!IS_CONTINUATION_BYTE(ch3))
195 goto InvalidContinuation2;
Antoine Pitrouca5f91b2012-05-10 16:36:02 +0200196 break;
197 }
198 ch2 = (unsigned char)s[1];
199 ch3 = (unsigned char)s[2];
200 ch4 = (unsigned char)s[3];
Ezio Melottif7ed5d12012-11-04 23:21:38 +0200201 if (!IS_CONTINUATION_BYTE(ch2)) {
Antoine Pitrouca5f91b2012-05-10 16:36:02 +0200202 /* invalid continuation byte */
Ezio Melottif7ed5d12012-11-04 23:21:38 +0200203 goto InvalidContinuation1;
Antoine Pitrouca5f91b2012-05-10 16:36:02 +0200204 }
205 if (ch == 0xF0) {
206 if (ch2 < 0x90)
207 /* invalid sequence
Ezio Melottif7ed5d12012-11-04 23:21:38 +0200208 \xF0\x80\x80\x80-\xF0\x8F\xBF\xBF -- fake 0000-FFFF */
209 goto InvalidContinuation1;
210 } else if (ch == 0xF4 && ch2 >= 0x90) {
Antoine Pitrouca5f91b2012-05-10 16:36:02 +0200211 /* invalid sequence
Serhiy Storchaka894263b2019-06-25 11:54:18 +0300212 \xF4\x90\x80\x80- -- 110000- overflow */
Ezio Melottif7ed5d12012-11-04 23:21:38 +0200213 goto InvalidContinuation1;
214 }
215 if (!IS_CONTINUATION_BYTE(ch3)) {
216 /* invalid continuation byte */
217 goto InvalidContinuation2;
218 }
219 if (!IS_CONTINUATION_BYTE(ch4)) {
220 /* invalid continuation byte */
221 goto InvalidContinuation3;
Antoine Pitrouca5f91b2012-05-10 16:36:02 +0200222 }
223 ch = (ch << 18) + (ch2 << 12) + (ch3 << 6) + ch4 -
224 ((0xF0 << 18) + (0x80 << 12) + (0x80 << 6) + 0x80);
225 assert ((ch > 0xFFFF) && (ch <= 0x10FFFF));
226 s += 4;
227 if (STRINGLIB_MAX_CHAR <= 0xFFFF ||
228 (STRINGLIB_MAX_CHAR < 0x10FFFF && ch > STRINGLIB_MAX_CHAR))
Ezio Melottif7ed5d12012-11-04 23:21:38 +0200229 /* Out-of-range */
230 goto Return;
Antoine Pitrouca5f91b2012-05-10 16:36:02 +0200231 *p++ = ch;
232 continue;
233 }
234 goto InvalidStart;
Antoine Pitrou0a3229d2011-11-21 20:39:13 +0100235 }
Antoine Pitrouca5f91b2012-05-10 16:36:02 +0200236 ch = 0;
Antoine Pitrouca5f91b2012-05-10 16:36:02 +0200237Return:
238 *inptr = s;
239 *outpos = p - dest;
240 return ch;
241InvalidStart:
242 ch = 1;
243 goto Return;
Ezio Melottif7ed5d12012-11-04 23:21:38 +0200244InvalidContinuation1:
Antoine Pitrouca5f91b2012-05-10 16:36:02 +0200245 ch = 2;
246 goto Return;
Ezio Melottif7ed5d12012-11-04 23:21:38 +0200247InvalidContinuation2:
248 ch = 3;
249 goto Return;
250InvalidContinuation3:
251 ch = 4;
252 goto Return;
Antoine Pitrou0a3229d2011-11-21 20:39:13 +0100253}
254
Antoine Pitrou0a3229d2011-11-21 20:39:13 +0100255#undef ASCII_CHAR_MASK
256
Victor Stinner6099a032011-12-18 14:22:26 +0100257
258/* UTF-8 encoder specialized for a Unicode kind to avoid the slow
259 PyUnicode_READ() macro. Delete some parts of the code depending on the kind:
260 UCS-1 strings don't need to handle surrogates for example. */
Inada Naoki02a4d572020-02-27 13:48:59 +0900261Py_LOCAL_INLINE(char *)
262STRINGLIB(utf8_encoder)(_PyBytesWriter *writer,
263 PyObject *unicode,
Serhiy Storchakacd8295f2020-04-11 10:48:40 +0300264 const STRINGLIB_CHAR *data,
Victor Stinner6099a032011-12-18 14:22:26 +0100265 Py_ssize_t size,
Victor Stinner709d23d2019-05-02 14:56:30 -0400266 _Py_error_handler error_handler,
Victor Stinner6099a032011-12-18 14:22:26 +0100267 const char *errors)
268{
Serhiy Storchaka998c9cd2016-10-30 18:25:27 +0200269 Py_ssize_t i; /* index into data of next input character */
Victor Stinner6099a032011-12-18 14:22:26 +0100270 char *p; /* next free byte in output buffer */
Victor Stinner6099a032011-12-18 14:22:26 +0100271#if STRINGLIB_SIZEOF_CHAR > 1
Victor Stinner01ada392015-10-01 21:54:51 +0200272 PyObject *error_handler_obj = NULL;
Victor Stinner6099a032011-12-18 14:22:26 +0100273 PyObject *exc = NULL;
274 PyObject *rep = NULL;
275#endif
276#if STRINGLIB_SIZEOF_CHAR == 1
277 const Py_ssize_t max_char_size = 2;
Victor Stinner6099a032011-12-18 14:22:26 +0100278#elif STRINGLIB_SIZEOF_CHAR == 2
279 const Py_ssize_t max_char_size = 3;
Victor Stinner6099a032011-12-18 14:22:26 +0100280#else /* STRINGLIB_SIZEOF_CHAR == 4 */
281 const Py_ssize_t max_char_size = 4;
Victor Stinner6099a032011-12-18 14:22:26 +0100282#endif
283
284 assert(size >= 0);
Victor Stinnerfdfbf782015-10-09 00:33:49 +0200285 if (size > PY_SSIZE_T_MAX / max_char_size) {
286 /* integer overflow */
Inada Naoki02a4d572020-02-27 13:48:59 +0900287 PyErr_NoMemory();
288 return NULL;
Victor Stinner6099a032011-12-18 14:22:26 +0100289 }
Victor Stinnerfdfbf782015-10-09 00:33:49 +0200290
Inada Naoki02a4d572020-02-27 13:48:59 +0900291 _PyBytesWriter_Init(writer);
292 p = _PyBytesWriter_Alloc(writer, size * max_char_size);
Victor Stinnerfdfbf782015-10-09 00:33:49 +0200293 if (p == NULL)
294 return NULL;
Victor Stinner6099a032011-12-18 14:22:26 +0100295
296 for (i = 0; i < size;) {
297 Py_UCS4 ch = data[i++];
298
299 if (ch < 0x80) {
300 /* Encode ASCII */
301 *p++ = (char) ch;
302
303 }
304 else
305#if STRINGLIB_SIZEOF_CHAR > 1
306 if (ch < 0x0800)
307#endif
308 {
309 /* Encode Latin-1 */
310 *p++ = (char)(0xc0 | (ch >> 6));
311 *p++ = (char)(0x80 | (ch & 0x3f));
312 }
313#if STRINGLIB_SIZEOF_CHAR > 1
314 else if (Py_UNICODE_IS_SURROGATE(ch)) {
Victor Stinner01ada392015-10-01 21:54:51 +0200315 Py_ssize_t startpos, endpos, newpos;
Victor Stinner6bd525b2015-10-09 13:10:05 +0200316 Py_ssize_t k;
Victor Stinner1a05d6c2016-09-02 12:12:23 +0200317 if (error_handler == _Py_ERROR_UNKNOWN) {
Victor Stinner3d4226a2018-08-29 22:21:32 +0200318 error_handler = _Py_GetErrorHandler(errors);
Victor Stinner1a05d6c2016-09-02 12:12:23 +0200319 }
Victor Stinner01ada392015-10-01 21:54:51 +0200320
Victor Stinner6099a032011-12-18 14:22:26 +0100321 startpos = i-1;
Victor Stinner01ada392015-10-01 21:54:51 +0200322 endpos = startpos+1;
Victor Stinner6099a032011-12-18 14:22:26 +0100323
Victor Stinner01ada392015-10-01 21:54:51 +0200324 while ((endpos < size) && Py_UNICODE_IS_SURROGATE(data[endpos]))
325 endpos++;
Victor Stinner6099a032011-12-18 14:22:26 +0100326
Victor Stinnerfdfbf782015-10-09 00:33:49 +0200327 /* Only overallocate the buffer if it's not the last write */
Inada Naoki02a4d572020-02-27 13:48:59 +0900328 writer->overallocate = (endpos < size);
Victor Stinnerfdfbf782015-10-09 00:33:49 +0200329
Victor Stinner01ada392015-10-01 21:54:51 +0200330 switch (error_handler)
331 {
332 case _Py_ERROR_REPLACE:
333 memset(p, '?', endpos - startpos);
334 p += (endpos - startpos);
Stefan Krahf432a322017-08-21 13:09:59 +0200335 /* fall through */
Victor Stinner01ada392015-10-01 21:54:51 +0200336 case _Py_ERROR_IGNORE:
337 i += (endpos - startpos - 1);
338 break;
Victor Stinner6099a032011-12-18 14:22:26 +0100339
Victor Stinner01ada392015-10-01 21:54:51 +0200340 case _Py_ERROR_SURROGATEPASS:
341 for (k=startpos; k<endpos; k++) {
342 ch = data[k];
343 *p++ = (char)(0xe0 | (ch >> 12));
344 *p++ = (char)(0x80 | ((ch >> 6) & 0x3f));
345 *p++ = (char)(0x80 | (ch & 0x3f));
346 }
347 i += (endpos - startpos - 1);
348 break;
349
Victor Stinnere7bf86c2015-10-09 01:39:28 +0200350 case _Py_ERROR_BACKSLASHREPLACE:
Raymond Hettinger15f44ab2016-08-30 10:47:49 -0700351 /* subtract preallocated bytes */
Inada Naoki02a4d572020-02-27 13:48:59 +0900352 writer->min_size -= max_char_size * (endpos - startpos);
353 p = backslashreplace(writer, p,
Victor Stinnere7bf86c2015-10-09 01:39:28 +0200354 unicode, startpos, endpos);
355 if (p == NULL)
356 goto error;
357 i += (endpos - startpos - 1);
358 break;
359
360 case _Py_ERROR_XMLCHARREFREPLACE:
Raymond Hettinger15f44ab2016-08-30 10:47:49 -0700361 /* subtract preallocated bytes */
Inada Naoki02a4d572020-02-27 13:48:59 +0900362 writer->min_size -= max_char_size * (endpos - startpos);
363 p = xmlcharrefreplace(writer, p,
Victor Stinnere7bf86c2015-10-09 01:39:28 +0200364 unicode, startpos, endpos);
365 if (p == NULL)
366 goto error;
367 i += (endpos - startpos - 1);
368 break;
369
Victor Stinner01ada392015-10-01 21:54:51 +0200370 case _Py_ERROR_SURROGATEESCAPE:
371 for (k=startpos; k<endpos; k++) {
372 ch = data[k];
373 if (!(0xDC80 <= ch && ch <= 0xDCFF))
374 break;
375 *p++ = (char)(ch & 0xff);
376 }
377 if (k >= endpos) {
378 i += (endpos - startpos - 1);
379 break;
380 }
381 startpos = k;
382 assert(startpos < endpos);
Stefan Krahf432a322017-08-21 13:09:59 +0200383 /* fall through */
Victor Stinner01ada392015-10-01 21:54:51 +0200384 default:
385 rep = unicode_encode_call_errorhandler(
386 errors, &error_handler_obj, "utf-8", "surrogates not allowed",
387 unicode, &exc, startpos, endpos, &newpos);
388 if (!rep)
389 goto error;
390
Raymond Hettinger15f44ab2016-08-30 10:47:49 -0700391 /* subtract preallocated bytes */
Inada Naoki02a4d572020-02-27 13:48:59 +0900392 writer->min_size -= max_char_size * (newpos - startpos);
Victor Stinnerad771582015-10-09 12:38:53 +0200393
Victor Stinner01ada392015-10-01 21:54:51 +0200394 if (PyBytes_Check(rep)) {
Inada Naoki02a4d572020-02-27 13:48:59 +0900395 p = _PyBytesWriter_WriteBytes(writer, p,
Victor Stinnerce179bf2015-10-09 12:57:22 +0200396 PyBytes_AS_STRING(rep),
397 PyBytes_GET_SIZE(rep));
Victor Stinner01ada392015-10-01 21:54:51 +0200398 }
399 else {
400 /* rep is unicode */
401 if (PyUnicode_READY(rep) < 0)
402 goto error;
Victor Stinner6099a032011-12-18 14:22:26 +0100403
Victor Stinner01ada392015-10-01 21:54:51 +0200404 if (!PyUnicode_IS_ASCII(rep)) {
Serhiy Storchaka998c9cd2016-10-30 18:25:27 +0200405 raise_encode_exception(&exc, "utf-8", unicode,
406 startpos, endpos,
Victor Stinner6099a032011-12-18 14:22:26 +0100407 "surrogates not allowed");
408 goto error;
409 }
Victor Stinner01ada392015-10-01 21:54:51 +0200410
Inada Naoki02a4d572020-02-27 13:48:59 +0900411 p = _PyBytesWriter_WriteBytes(writer, p,
Victor Stinner6bd525b2015-10-09 13:10:05 +0200412 PyUnicode_DATA(rep),
413 PyUnicode_GET_LENGTH(rep));
Victor Stinner6099a032011-12-18 14:22:26 +0100414 }
Victor Stinner6bd525b2015-10-09 13:10:05 +0200415
416 if (p == NULL)
417 goto error;
Victor Stinner01ada392015-10-01 21:54:51 +0200418 Py_CLEAR(rep);
419
420 i = newpos;
Victor Stinner6099a032011-12-18 14:22:26 +0100421 }
Victor Stinnerfdfbf782015-10-09 00:33:49 +0200422
423 /* If overallocation was disabled, ensure that it was the last
424 write. Otherwise, we missed an optimization */
Inada Naoki02a4d572020-02-27 13:48:59 +0900425 assert(writer->overallocate || i == size);
Victor Stinner6099a032011-12-18 14:22:26 +0100426 }
427 else
428#if STRINGLIB_SIZEOF_CHAR > 2
429 if (ch < 0x10000)
430#endif
431 {
432 *p++ = (char)(0xe0 | (ch >> 12));
433 *p++ = (char)(0x80 | ((ch >> 6) & 0x3f));
434 *p++ = (char)(0x80 | (ch & 0x3f));
435 }
436#if STRINGLIB_SIZEOF_CHAR > 2
437 else /* ch >= 0x10000 */
438 {
439 assert(ch <= MAX_UNICODE);
440 /* Encode UCS4 Unicode ordinals */
441 *p++ = (char)(0xf0 | (ch >> 18));
442 *p++ = (char)(0x80 | ((ch >> 12) & 0x3f));
443 *p++ = (char)(0x80 | ((ch >> 6) & 0x3f));
444 *p++ = (char)(0x80 | (ch & 0x3f));
445 }
446#endif /* STRINGLIB_SIZEOF_CHAR > 2 */
447#endif /* STRINGLIB_SIZEOF_CHAR > 1 */
448 }
449
Victor Stinner6099a032011-12-18 14:22:26 +0100450#if STRINGLIB_SIZEOF_CHAR > 1
Victor Stinner01ada392015-10-01 21:54:51 +0200451 Py_XDECREF(error_handler_obj);
Victor Stinner6099a032011-12-18 14:22:26 +0100452 Py_XDECREF(exc);
453#endif
Inada Naoki02a4d572020-02-27 13:48:59 +0900454 return p;
Victor Stinner6099a032011-12-18 14:22:26 +0100455
456#if STRINGLIB_SIZEOF_CHAR > 1
457 error:
458 Py_XDECREF(rep);
Victor Stinner01ada392015-10-01 21:54:51 +0200459 Py_XDECREF(error_handler_obj);
Victor Stinner6099a032011-12-18 14:22:26 +0100460 Py_XDECREF(exc);
Victor Stinner6099a032011-12-18 14:22:26 +0100461 return NULL;
462#endif
Victor Stinner6099a032011-12-18 14:22:26 +0100463}
464
Antoine Pitrou63065d72012-05-15 23:48:04 +0200465/* The pattern for constructing UCS2-repeated masks. */
466#if SIZEOF_LONG == 8
467# define UCS2_REPEAT_MASK 0x0001000100010001ul
468#elif SIZEOF_LONG == 4
469# define UCS2_REPEAT_MASK 0x00010001ul
470#else
471# error C 'long' size should be either 4 or 8!
472#endif
473
474/* The mask for fast checking. */
475#if STRINGLIB_SIZEOF_CHAR == 1
476/* The mask for fast checking of whether a C 'long' contains a
477 non-ASCII or non-Latin1 UTF16-encoded characters. */
478# define FAST_CHAR_MASK (UCS2_REPEAT_MASK * (0xFFFFu & ~STRINGLIB_MAX_CHAR))
479#else
480/* The mask for fast checking of whether a C 'long' may contain
481 UTF16-encoded surrogate characters. This is an efficient heuristic,
482 assuming that non-surrogate characters with a code point >= 0x8000 are
483 rare in most input.
484*/
485# define FAST_CHAR_MASK (UCS2_REPEAT_MASK * 0x8000u)
486#endif
487/* The mask for fast byte-swapping. */
488#define STRIPPED_MASK (UCS2_REPEAT_MASK * 0x00FFu)
489/* Swap bytes. */
490#define SWAB(value) ((((value) >> 8) & STRIPPED_MASK) | \
491 (((value) & STRIPPED_MASK) << 8))
492
493Py_LOCAL_INLINE(Py_UCS4)
494STRINGLIB(utf16_decode)(const unsigned char **inptr, const unsigned char *e,
495 STRINGLIB_CHAR *dest, Py_ssize_t *outpos,
496 int native_ordering)
497{
498 Py_UCS4 ch;
499 const unsigned char *aligned_end =
Antoine Pitrouca8aa4a2012-09-20 20:56:47 +0200500 (const unsigned char *) _Py_ALIGN_DOWN(e, SIZEOF_LONG);
Antoine Pitrou63065d72012-05-15 23:48:04 +0200501 const unsigned char *q = *inptr;
502 STRINGLIB_CHAR *p = dest + *outpos;
503 /* Offsets from q for retrieving byte pairs in the right order. */
Christian Heimes743e0cd2012-10-17 23:52:17 +0200504#if PY_LITTLE_ENDIAN
Antoine Pitrou63065d72012-05-15 23:48:04 +0200505 int ihi = !!native_ordering, ilo = !native_ordering;
506#else
507 int ihi = !native_ordering, ilo = !!native_ordering;
508#endif
509 --e;
510
511 while (q < e) {
512 Py_UCS4 ch2;
513 /* First check for possible aligned read of a C 'long'. Unaligned
514 reads are more expensive, better to defer to another iteration. */
Antoine Pitrouca8aa4a2012-09-20 20:56:47 +0200515 if (_Py_IS_ALIGNED(q, SIZEOF_LONG)) {
Antoine Pitrou63065d72012-05-15 23:48:04 +0200516 /* Fast path for runs of in-range non-surrogate chars. */
Antoine Pitrou9ed5f272013-08-13 20:18:52 +0200517 const unsigned char *_q = q;
Antoine Pitrou63065d72012-05-15 23:48:04 +0200518 while (_q < aligned_end) {
Andy Lestere6be9b52020-02-11 20:28:35 -0600519 unsigned long block = * (const unsigned long *) _q;
Antoine Pitrou63065d72012-05-15 23:48:04 +0200520 if (native_ordering) {
521 /* Can use buffer directly */
522 if (block & FAST_CHAR_MASK)
523 break;
524 }
525 else {
526 /* Need to byte-swap */
527 if (block & SWAB(FAST_CHAR_MASK))
528 break;
529#if STRINGLIB_SIZEOF_CHAR == 1
530 block >>= 8;
531#else
532 block = SWAB(block);
533#endif
534 }
Christian Heimes743e0cd2012-10-17 23:52:17 +0200535#if PY_LITTLE_ENDIAN
Antoine Pitrou63065d72012-05-15 23:48:04 +0200536# if SIZEOF_LONG == 4
537 p[0] = (STRINGLIB_CHAR)(block & 0xFFFFu);
538 p[1] = (STRINGLIB_CHAR)(block >> 16);
539# elif SIZEOF_LONG == 8
540 p[0] = (STRINGLIB_CHAR)(block & 0xFFFFu);
541 p[1] = (STRINGLIB_CHAR)((block >> 16) & 0xFFFFu);
542 p[2] = (STRINGLIB_CHAR)((block >> 32) & 0xFFFFu);
543 p[3] = (STRINGLIB_CHAR)(block >> 48);
544# endif
545#else
546# if SIZEOF_LONG == 4
547 p[0] = (STRINGLIB_CHAR)(block >> 16);
548 p[1] = (STRINGLIB_CHAR)(block & 0xFFFFu);
549# elif SIZEOF_LONG == 8
550 p[0] = (STRINGLIB_CHAR)(block >> 48);
551 p[1] = (STRINGLIB_CHAR)((block >> 32) & 0xFFFFu);
552 p[2] = (STRINGLIB_CHAR)((block >> 16) & 0xFFFFu);
553 p[3] = (STRINGLIB_CHAR)(block & 0xFFFFu);
554# endif
555#endif
556 _q += SIZEOF_LONG;
557 p += SIZEOF_LONG / 2;
558 }
559 q = _q;
560 if (q >= e)
561 break;
562 }
563
564 ch = (q[ihi] << 8) | q[ilo];
565 q += 2;
566 if (!Py_UNICODE_IS_SURROGATE(ch)) {
567#if STRINGLIB_SIZEOF_CHAR < 2
568 if (ch > STRINGLIB_MAX_CHAR)
569 /* Out-of-range */
570 goto Return;
571#endif
572 *p++ = (STRINGLIB_CHAR)ch;
573 continue;
574 }
575
576 /* UTF-16 code pair: */
Antoine Pitrou63065d72012-05-15 23:48:04 +0200577 if (!Py_UNICODE_IS_HIGH_SURROGATE(ch))
578 goto IllegalEncoding;
Serhiy Storchaka894263b2019-06-25 11:54:18 +0300579 if (q >= e)
580 goto UnexpectedEnd;
Antoine Pitrou63065d72012-05-15 23:48:04 +0200581 ch2 = (q[ihi] << 8) | q[ilo];
582 q += 2;
583 if (!Py_UNICODE_IS_LOW_SURROGATE(ch2))
584 goto IllegalSurrogate;
585 ch = Py_UNICODE_JOIN_SURROGATES(ch, ch2);
586#if STRINGLIB_SIZEOF_CHAR < 4
587 /* Out-of-range */
588 goto Return;
589#else
590 *p++ = (STRINGLIB_CHAR)ch;
591#endif
592 }
593 ch = 0;
594Return:
595 *inptr = q;
596 *outpos = p - dest;
597 return ch;
598UnexpectedEnd:
599 ch = 1;
600 goto Return;
601IllegalEncoding:
602 ch = 2;
603 goto Return;
604IllegalSurrogate:
605 ch = 3;
606 goto Return;
607}
608#undef UCS2_REPEAT_MASK
609#undef FAST_CHAR_MASK
610#undef STRIPPED_MASK
611#undef SWAB
Antoine Pitrou27f6a3b2012-06-15 22:15:23 +0200612
613
Serhiy Storchaka58cf6072013-11-19 11:32:41 +0200614#if STRINGLIB_MAX_CHAR >= 0x80
615Py_LOCAL_INLINE(Py_ssize_t)
Serhiy Storchaka58cf6072013-11-19 11:32:41 +0200616STRINGLIB(utf16_encode)(const STRINGLIB_CHAR *in,
617 Py_ssize_t len,
618 unsigned short **outptr,
619 int native_ordering)
620{
621 unsigned short *out = *outptr;
622 const STRINGLIB_CHAR *end = in + len;
623#if STRINGLIB_SIZEOF_CHAR == 1
624 if (native_ordering) {
625 const STRINGLIB_CHAR *unrolled_end = in + _Py_SIZE_ROUND_DOWN(len, 4);
626 while (in < unrolled_end) {
627 out[0] = in[0];
628 out[1] = in[1];
629 out[2] = in[2];
630 out[3] = in[3];
631 in += 4; out += 4;
632 }
633 while (in < end) {
634 *out++ = *in++;
635 }
636 } else {
637# define SWAB2(CH) ((CH) << 8) /* high byte is zero */
Antoine Pitrouca8aa4a2012-09-20 20:56:47 +0200638 const STRINGLIB_CHAR *unrolled_end = in + _Py_SIZE_ROUND_DOWN(len, 4);
Antoine Pitrou27f6a3b2012-06-15 22:15:23 +0200639 while (in < unrolled_end) {
640 out[0] = SWAB2(in[0]);
641 out[1] = SWAB2(in[1]);
642 out[2] = SWAB2(in[2]);
643 out[3] = SWAB2(in[3]);
644 in += 4; out += 4;
645 }
646 while (in < end) {
Serhiy Storchaka58cf6072013-11-19 11:32:41 +0200647 Py_UCS4 ch = *in++;
648 *out++ = SWAB2((Py_UCS2)ch);
Antoine Pitrou27f6a3b2012-06-15 22:15:23 +0200649 }
Serhiy Storchaka58cf6072013-11-19 11:32:41 +0200650#undef SWAB2
Antoine Pitrou27f6a3b2012-06-15 22:15:23 +0200651 }
Serhiy Storchaka58cf6072013-11-19 11:32:41 +0200652 *outptr = out;
653 return len;
Antoine Pitrou27f6a3b2012-06-15 22:15:23 +0200654#else
655 if (native_ordering) {
Serhiy Storchaka58cf6072013-11-19 11:32:41 +0200656#if STRINGLIB_MAX_CHAR < 0x10000
657 const STRINGLIB_CHAR *unrolled_end = in + _Py_SIZE_ROUND_DOWN(len, 4);
658 while (in < unrolled_end) {
659 /* check if any character is a surrogate character */
660 if (((in[0] ^ 0xd800) &
661 (in[1] ^ 0xd800) &
662 (in[2] ^ 0xd800) &
663 (in[3] ^ 0xd800) & 0xf800) == 0)
664 break;
665 out[0] = in[0];
666 out[1] = in[1];
667 out[2] = in[2];
668 out[3] = in[3];
669 in += 4; out += 4;
670 }
671#endif
Antoine Pitrou27f6a3b2012-06-15 22:15:23 +0200672 while (in < end) {
Serhiy Storchaka58cf6072013-11-19 11:32:41 +0200673 Py_UCS4 ch;
674 ch = *in++;
675 if (ch < 0xd800)
Antoine Pitrou27f6a3b2012-06-15 22:15:23 +0200676 *out++ = ch;
Serhiy Storchaka58cf6072013-11-19 11:32:41 +0200677 else if (ch < 0xe000)
Serhiy Storchaka7e29eea2015-05-18 22:19:42 +0300678 /* reject surrogate characters (U+D800-U+DFFF) */
Serhiy Storchaka58cf6072013-11-19 11:32:41 +0200679 goto fail;
680#if STRINGLIB_MAX_CHAR >= 0x10000
681 else if (ch >= 0x10000) {
Antoine Pitrou27f6a3b2012-06-15 22:15:23 +0200682 out[0] = Py_UNICODE_HIGH_SURROGATE(ch);
683 out[1] = Py_UNICODE_LOW_SURROGATE(ch);
684 out += 2;
685 }
Serhiy Storchaka58cf6072013-11-19 11:32:41 +0200686#endif
687 else
688 *out++ = ch;
Antoine Pitrou27f6a3b2012-06-15 22:15:23 +0200689 }
690 } else {
Serhiy Storchaka58cf6072013-11-19 11:32:41 +0200691#define SWAB2(CH) (((CH) << 8) | ((CH) >> 8))
692#if STRINGLIB_MAX_CHAR < 0x10000
693 const STRINGLIB_CHAR *unrolled_end = in + _Py_SIZE_ROUND_DOWN(len, 4);
694 while (in < unrolled_end) {
695 /* check if any character is a surrogate character */
696 if (((in[0] ^ 0xd800) &
697 (in[1] ^ 0xd800) &
698 (in[2] ^ 0xd800) &
699 (in[3] ^ 0xd800) & 0xf800) == 0)
700 break;
701 out[0] = SWAB2(in[0]);
702 out[1] = SWAB2(in[1]);
703 out[2] = SWAB2(in[2]);
704 out[3] = SWAB2(in[3]);
705 in += 4; out += 4;
706 }
707#endif
Antoine Pitrou27f6a3b2012-06-15 22:15:23 +0200708 while (in < end) {
709 Py_UCS4 ch = *in++;
Serhiy Storchaka58cf6072013-11-19 11:32:41 +0200710 if (ch < 0xd800)
Antoine Pitrou27f6a3b2012-06-15 22:15:23 +0200711 *out++ = SWAB2((Py_UCS2)ch);
Serhiy Storchaka58cf6072013-11-19 11:32:41 +0200712 else if (ch < 0xe000)
Serhiy Storchaka7e29eea2015-05-18 22:19:42 +0300713 /* reject surrogate characters (U+D800-U+DFFF) */
Serhiy Storchaka58cf6072013-11-19 11:32:41 +0200714 goto fail;
715#if STRINGLIB_MAX_CHAR >= 0x10000
716 else if (ch >= 0x10000) {
Antoine Pitrou27f6a3b2012-06-15 22:15:23 +0200717 Py_UCS2 ch1 = Py_UNICODE_HIGH_SURROGATE(ch);
718 Py_UCS2 ch2 = Py_UNICODE_LOW_SURROGATE(ch);
719 out[0] = SWAB2(ch1);
720 out[1] = SWAB2(ch2);
721 out += 2;
722 }
Antoine Pitrou27f6a3b2012-06-15 22:15:23 +0200723#endif
Serhiy Storchaka58cf6072013-11-19 11:32:41 +0200724 else
725 *out++ = SWAB2((Py_UCS2)ch);
726 }
Antoine Pitrou27f6a3b2012-06-15 22:15:23 +0200727#undef SWAB2
Serhiy Storchaka58cf6072013-11-19 11:32:41 +0200728 }
729 *outptr = out;
730 return len;
731 fail:
732 *outptr = out;
733 return len - (end - in + 1);
734#endif
Antoine Pitrou27f6a3b2012-06-15 22:15:23 +0200735}
Serhiy Storchaka0d4df752015-05-12 23:12:45 +0300736
Victor Stinner1ae035b2020-04-17 17:47:20 +0200737static inline uint32_t
738STRINGLIB(SWAB4)(STRINGLIB_CHAR ch)
739{
740 uint32_t word = ch;
Serhiy Storchaka0d4df752015-05-12 23:12:45 +0300741#if STRINGLIB_SIZEOF_CHAR == 1
Victor Stinner1ae035b2020-04-17 17:47:20 +0200742 /* high bytes are zero */
743 return (word << 24);
Serhiy Storchaka0d4df752015-05-12 23:12:45 +0300744#elif STRINGLIB_SIZEOF_CHAR == 2
Victor Stinner1ae035b2020-04-17 17:47:20 +0200745 /* high bytes are zero */
Victor Stinnerd7c657d2020-04-17 19:13:34 +0200746 return ((word & 0x00FFu) << 24) | ((word & 0xFF00u) << 8);
Serhiy Storchaka0d4df752015-05-12 23:12:45 +0300747#else
Victor Stinner1ae035b2020-04-17 17:47:20 +0200748 return _Py_bswap32(word);
Serhiy Storchaka0d4df752015-05-12 23:12:45 +0300749#endif
Victor Stinner1ae035b2020-04-17 17:47:20 +0200750}
751
Serhiy Storchaka0d4df752015-05-12 23:12:45 +0300752Py_LOCAL_INLINE(Py_ssize_t)
753STRINGLIB(utf32_encode)(const STRINGLIB_CHAR *in,
754 Py_ssize_t len,
Victor Stinner1ae035b2020-04-17 17:47:20 +0200755 uint32_t **outptr,
Serhiy Storchaka0d4df752015-05-12 23:12:45 +0300756 int native_ordering)
757{
Victor Stinner1ae035b2020-04-17 17:47:20 +0200758 uint32_t *out = *outptr;
Serhiy Storchaka0d4df752015-05-12 23:12:45 +0300759 const STRINGLIB_CHAR *end = in + len;
760 if (native_ordering) {
761 const STRINGLIB_CHAR *unrolled_end = in + _Py_SIZE_ROUND_DOWN(len, 4);
762 while (in < unrolled_end) {
763#if STRINGLIB_SIZEOF_CHAR > 1
764 /* check if any character is a surrogate character */
765 if (((in[0] ^ 0xd800) &
766 (in[1] ^ 0xd800) &
767 (in[2] ^ 0xd800) &
768 (in[3] ^ 0xd800) & 0xf800) == 0)
769 break;
770#endif
771 out[0] = in[0];
772 out[1] = in[1];
773 out[2] = in[2];
774 out[3] = in[3];
775 in += 4; out += 4;
776 }
777 while (in < end) {
778 Py_UCS4 ch;
779 ch = *in++;
780#if STRINGLIB_SIZEOF_CHAR > 1
781 if (Py_UNICODE_IS_SURROGATE(ch)) {
Serhiy Storchaka9ce71a62015-05-18 22:20:18 +0300782 /* reject surrogate characters (U+D800-U+DFFF) */
Serhiy Storchaka0d4df752015-05-12 23:12:45 +0300783 goto fail;
784 }
785#endif
786 *out++ = ch;
787 }
788 } else {
789 const STRINGLIB_CHAR *unrolled_end = in + _Py_SIZE_ROUND_DOWN(len, 4);
790 while (in < unrolled_end) {
791#if STRINGLIB_SIZEOF_CHAR > 1
Serhiy Storchaka0d4df752015-05-12 23:12:45 +0300792 /* check if any character is a surrogate character */
793 if (((in[0] ^ 0xd800) &
794 (in[1] ^ 0xd800) &
795 (in[2] ^ 0xd800) &
796 (in[3] ^ 0xd800) & 0xf800) == 0)
797 break;
798#endif
Victor Stinner1ae035b2020-04-17 17:47:20 +0200799 out[0] = STRINGLIB(SWAB4)(in[0]);
800 out[1] = STRINGLIB(SWAB4)(in[1]);
801 out[2] = STRINGLIB(SWAB4)(in[2]);
802 out[3] = STRINGLIB(SWAB4)(in[3]);
Serhiy Storchaka0d4df752015-05-12 23:12:45 +0300803 in += 4; out += 4;
804 }
805 while (in < end) {
806 Py_UCS4 ch = *in++;
807#if STRINGLIB_SIZEOF_CHAR > 1
808 if (Py_UNICODE_IS_SURROGATE(ch)) {
Serhiy Storchaka9ce71a62015-05-18 22:20:18 +0300809 /* reject surrogate characters (U+D800-U+DFFF) */
Serhiy Storchaka0d4df752015-05-12 23:12:45 +0300810 goto fail;
811 }
812#endif
Victor Stinner1ae035b2020-04-17 17:47:20 +0200813 *out++ = STRINGLIB(SWAB4)(ch);
Serhiy Storchaka0d4df752015-05-12 23:12:45 +0300814 }
815 }
816 *outptr = out;
817 return len;
818#if STRINGLIB_SIZEOF_CHAR > 1
819 fail:
820 *outptr = out;
821 return len - (end - in + 1);
822#endif
823}
Serhiy Storchaka0d4df752015-05-12 23:12:45 +0300824
Serhiy Storchaka58cf6072013-11-19 11:32:41 +0200825#endif