Coverage Report

Created: 2026-07-14 06:16

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/cpython/Modules/_codecsmodule.c
Line
Count
Source
1
/* ------------------------------------------------------------------------
2
3
   _codecs -- Provides access to the codec registry and the builtin
4
              codecs.
5
6
   This module should never be imported directly. The standard library
7
   module "codecs" wraps this builtin module for use within Python.
8
9
   The codec registry is accessible via:
10
11
     register(search_function) -> None
12
13
     lookup(encoding) -> CodecInfo object
14
15
   The builtin Unicode codecs use the following interface:
16
17
     <encoding>_encode(Unicode_object[,errors='strict']) ->
18
        (string object, bytes consumed)
19
20
     <encoding>_decode(char_buffer_obj[,errors='strict']) ->
21
        (Unicode object, bytes consumed)
22
23
   These <encoding>s are available: utf_8, unicode_escape,
24
   raw_unicode_escape, latin_1, ascii (7-bit), mbcs (on win32).
25
26
27
Written by Marc-Andre Lemburg (mal@lemburg.com).
28
29
Copyright (c) Corporation for National Research Initiatives.
30
31
   ------------------------------------------------------------------------ */
32
33
#include "Python.h"
34
#include "pycore_codecs.h"        // _PyCodec_Lookup()
35
#include "pycore_unicodeobject.h" // _PyUnicode_EncodeCharmap
36
37
#ifdef MS_WINDOWS
38
#include <windows.h>
39
#endif
40
41
/*[clinic input]
42
module _codecs
43
[clinic start generated code]*/
44
/*[clinic end generated code: output=da39a3ee5e6b4b0d input=e1390e3da3cb9deb]*/
45
46
#include "pycore_runtime.h"
47
#include "clinic/_codecsmodule.c.h"
48
49
/* --- Registry ----------------------------------------------------------- */
50
51
/*[clinic input]
52
_codecs.register
53
    search_function: object
54
    /
55
56
Register a codec search function.
57
58
Search functions are expected to take one argument, the encoding
59
name in all lower case letters, and either return None, or a tuple
60
of functions (encoder, decoder, stream_reader, stream_writer) (or
61
a CodecInfo object).
62
[clinic start generated code]*/
63
64
static PyObject *
65
_codecs_register(PyObject *module, PyObject *search_function)
66
/*[clinic end generated code: output=d1bf21e99db7d6d3 input=2321d8c8c0420dfc]*/
67
72
{
68
72
    if (PyCodec_Register(search_function))
69
0
        return NULL;
70
71
72
    Py_RETURN_NONE;
72
72
}
73
74
/*[clinic input]
75
_codecs.unregister
76
    search_function: object
77
    /
78
79
Unregister a codec search function and clear the registry's cache.
80
81
If the search function is not registered, do nothing.
82
[clinic start generated code]*/
83
84
static PyObject *
85
_codecs_unregister(PyObject *module, PyObject *search_function)
86
/*[clinic end generated code: output=1f0edee9cf246399 input=dd7c004c652d345e]*/
87
0
{
88
0
    if (PyCodec_Unregister(search_function) < 0) {
89
0
        return NULL;
90
0
    }
91
92
0
    Py_RETURN_NONE;
93
0
}
94
95
/*[clinic input]
96
@permit_long_summary
97
_codecs.lookup
98
    encoding: str
99
    /
100
101
Looks up a codec tuple in the Python codec registry and returns a CodecInfo object.
102
[clinic start generated code]*/
103
104
static PyObject *
105
_codecs_lookup_impl(PyObject *module, const char *encoding)
106
/*[clinic end generated code: output=9f0afa572080c36d input=02227d5429491ab3]*/
107
326k
{
108
326k
    return _PyCodec_Lookup(encoding);
109
326k
}
110
111
/*[clinic input]
112
_codecs.encode
113
    obj: object
114
    encoding: str(c_default="NULL") = "utf-8"
115
    errors: str(c_default="NULL") = "strict"
116
117
Encodes obj using the codec registered for encoding.
118
119
The default encoding is 'utf-8'.  errors may be given to set a
120
different error handling scheme.  Default is 'strict' meaning that
121
encoding errors raise a ValueError.  Other possible values are 'ignore',
122
'replace' and 'backslashreplace' as well as any other name registered
123
with codecs.register_error that can handle ValueErrors.
124
[clinic start generated code]*/
125
126
static PyObject *
127
_codecs_encode_impl(PyObject *module, PyObject *obj, const char *encoding,
128
                    const char *errors)
129
/*[clinic end generated code: output=385148eb9a067c86 input=e5271d443e391d7f]*/
130
0
{
131
0
    if (encoding == NULL)
132
0
        encoding = PyUnicode_GetDefaultEncoding();
133
134
    /* Encode via the codec registry */
135
0
    return PyCodec_Encode(obj, encoding, errors);
136
0
}
137
138
/*[clinic input]
139
_codecs.decode
140
    obj: object
141
    encoding: str(c_default="NULL") = "utf-8"
142
    errors: str(c_default="NULL") = "strict"
143
144
Decodes obj using the codec registered for encoding.
145
146
Default encoding is 'utf-8'.  errors may be given to set a
147
different error handling scheme.  Default is 'strict' meaning that
148
encoding errors raise a ValueError.  Other possible values are 'ignore',
149
'replace' and 'backslashreplace' as well as any other name registered
150
with codecs.register_error that can handle ValueErrors.
151
[clinic start generated code]*/
152
153
static PyObject *
154
_codecs_decode_impl(PyObject *module, PyObject *obj, const char *encoding,
155
                    const char *errors)
156
/*[clinic end generated code: output=679882417dc3a0bd input=3e6254628f9ca538]*/
157
0
{
158
0
    if (encoding == NULL)
159
0
        encoding = PyUnicode_GetDefaultEncoding();
160
161
    /* Decode via the codec registry */
162
0
    return PyCodec_Decode(obj, encoding, errors);
163
0
}
164
165
/* --- Helpers ------------------------------------------------------------ */
166
167
static
168
PyObject *codec_tuple(PyObject *decoded,
169
                      Py_ssize_t len)
170
1.87M
{
171
1.87M
    if (decoded == NULL)
172
140k
        return NULL;
173
1.73M
    return Py_BuildValue("Nn", decoded, len);
174
1.87M
}
175
176
/* --- String codecs ------------------------------------------------------ */
177
/*[clinic input]
178
_codecs.escape_decode
179
    data: Py_buffer(accept={str, buffer})
180
    errors: str(accept={str, NoneType}) = None
181
    /
182
[clinic start generated code]*/
183
184
static PyObject *
185
_codecs_escape_decode_impl(PyObject *module, Py_buffer *data,
186
                           const char *errors)
187
/*[clinic end generated code: output=505200ba8056979a input=77298a561c90bd82]*/
188
0
{
189
0
    PyObject *decoded = PyBytes_DecodeEscape(data->buf, data->len,
190
0
                                             errors, 0, NULL);
191
0
    return codec_tuple(decoded, data->len);
192
0
}
193
194
/*[clinic input]
195
_codecs.escape_encode
196
    data: object(subclass_of='&PyBytes_Type')
197
    errors: str(accept={str, NoneType}) = None
198
    /
199
[clinic start generated code]*/
200
201
static PyObject *
202
_codecs_escape_encode_impl(PyObject *module, PyObject *data,
203
                           const char *errors)
204
/*[clinic end generated code: output=4af1d477834bab34 input=8f4b144799a94245]*/
205
0
{
206
0
    Py_ssize_t size = PyBytes_GET_SIZE(data);
207
0
    if (size > PY_SSIZE_T_MAX / 4) {
208
0
        PyErr_SetString(PyExc_OverflowError,
209
0
            "string is too large to encode");
210
0
            return NULL;
211
0
    }
212
0
    Py_ssize_t newsize = 4*size;
213
214
0
    PyBytesWriter *writer = PyBytesWriter_Create(newsize);
215
0
    if (writer == NULL) {
216
0
        return NULL;
217
0
    }
218
0
    char *p = PyBytesWriter_GetData(writer);
219
220
0
    for (Py_ssize_t i = 0; i < size; i++) {
221
        /* There's at least enough room for a hex escape */
222
0
        assert(newsize - (p - (char*)PyBytesWriter_GetData(writer)) >= 4);
223
224
0
        char c = PyBytes_AS_STRING(data)[i];
225
0
        if (c == '\'' || c == '\\') {
226
0
            *p++ = '\\'; *p++ = c;
227
0
        }
228
0
        else if (c == '\t') {
229
0
            *p++ = '\\'; *p++ = 't';
230
0
        }
231
0
        else if (c == '\n') {
232
0
            *p++ = '\\'; *p++ = 'n';
233
0
        }
234
0
        else if (c == '\r') {
235
0
            *p++ = '\\'; *p++ = 'r';
236
0
        }
237
0
        else if (c < ' ' || c >= 0x7f) {
238
0
            *p++ = '\\';
239
0
            *p++ = 'x';
240
0
            *p++ = Py_hexdigits[(c & 0xf0) >> 4];
241
0
            *p++ = Py_hexdigits[c & 0xf];
242
0
        }
243
0
        else {
244
0
            *p++ = c;
245
0
        }
246
0
    }
247
248
0
    PyObject *decoded = PyBytesWriter_FinishWithPointer(writer, p);
249
0
    return codec_tuple(decoded, size);
250
0
}
251
252
/* --- Decoder ------------------------------------------------------------ */
253
/*[clinic input]
254
_codecs.utf_7_decode
255
    data: Py_buffer
256
    errors: str(accept={str, NoneType}) = None
257
    final: bool = False
258
    /
259
[clinic start generated code]*/
260
261
static PyObject *
262
_codecs_utf_7_decode_impl(PyObject *module, Py_buffer *data,
263
                          const char *errors, int final)
264
/*[clinic end generated code: output=0cd3a944a32a4089 input=dbf8c8998102dc7d]*/
265
31.5k
{
266
31.5k
    Py_ssize_t consumed = data->len;
267
31.5k
    PyObject *decoded = PyUnicode_DecodeUTF7Stateful(data->buf, data->len,
268
31.5k
                                                     errors,
269
31.5k
                                                     final ? NULL : &consumed);
270
31.5k
    return codec_tuple(decoded, consumed);
271
31.5k
}
272
273
/*[clinic input]
274
_codecs.utf_8_decode
275
    data: Py_buffer
276
    errors: str(accept={str, NoneType}) = None
277
    final: bool = False
278
    /
279
[clinic start generated code]*/
280
281
static PyObject *
282
_codecs_utf_8_decode_impl(PyObject *module, Py_buffer *data,
283
                          const char *errors, int final)
284
/*[clinic end generated code: output=10f74dec8d9bb8bf input=ca06bc8a9c970e25]*/
285
62.1k
{
286
62.1k
    Py_ssize_t consumed = data->len;
287
62.1k
    PyObject *decoded = PyUnicode_DecodeUTF8Stateful(data->buf, data->len,
288
62.1k
                                                     errors,
289
62.1k
                                                     final ? NULL : &consumed);
290
62.1k
    return codec_tuple(decoded, consumed);
291
62.1k
}
292
293
/*[clinic input]
294
_codecs.utf_16_decode
295
    data: Py_buffer
296
    errors: str(accept={str, NoneType}) = None
297
    final: bool = False
298
    /
299
[clinic start generated code]*/
300
301
static PyObject *
302
_codecs_utf_16_decode_impl(PyObject *module, Py_buffer *data,
303
                           const char *errors, int final)
304
/*[clinic end generated code: output=783b442abcbcc2d0 input=5b0f52071ba6cadc]*/
305
18.6k
{
306
18.6k
    int byteorder = 0;
307
    /* This is overwritten unless final is true. */
308
18.6k
    Py_ssize_t consumed = data->len;
309
18.6k
    PyObject *decoded = PyUnicode_DecodeUTF16Stateful(data->buf, data->len,
310
18.6k
                                                      errors, &byteorder,
311
18.6k
                                                      final ? NULL : &consumed);
312
18.6k
    return codec_tuple(decoded, consumed);
313
18.6k
}
314
315
/*[clinic input]
316
_codecs.utf_16_le_decode
317
    data: Py_buffer
318
    errors: str(accept={str, NoneType}) = None
319
    final: bool = False
320
    /
321
[clinic start generated code]*/
322
323
static PyObject *
324
_codecs_utf_16_le_decode_impl(PyObject *module, Py_buffer *data,
325
                              const char *errors, int final)
326
/*[clinic end generated code: output=899b9e6364379dcd input=115bd8c7b783d0bf]*/
327
56
{
328
56
    int byteorder = -1;
329
    /* This is overwritten unless final is true. */
330
56
    Py_ssize_t consumed = data->len;
331
56
    PyObject *decoded = PyUnicode_DecodeUTF16Stateful(data->buf, data->len,
332
56
                                                      errors, &byteorder,
333
56
                                                      final ? NULL : &consumed);
334
56
    return codec_tuple(decoded, consumed);
335
56
}
336
337
/*[clinic input]
338
_codecs.utf_16_be_decode
339
    data: Py_buffer
340
    errors: str(accept={str, NoneType}) = None
341
    final: bool = False
342
    /
343
[clinic start generated code]*/
344
345
static PyObject *
346
_codecs_utf_16_be_decode_impl(PyObject *module, Py_buffer *data,
347
                              const char *errors, int final)
348
/*[clinic end generated code: output=49f6465ea07669c8 input=63131422b01f9cb4]*/
349
236
{
350
236
    int byteorder = 1;
351
    /* This is overwritten unless final is true. */
352
236
    Py_ssize_t consumed = data->len;
353
236
    PyObject *decoded = PyUnicode_DecodeUTF16Stateful(data->buf, data->len,
354
236
                                                      errors, &byteorder,
355
236
                                                      final ? NULL : &consumed);
356
236
    return codec_tuple(decoded, consumed);
357
236
}
358
359
/* This non-standard version also provides access to the byteorder
360
   parameter of the builtin UTF-16 codec.
361
362
   It returns a tuple (unicode, bytesread, byteorder) with byteorder
363
   being the value in effect at the end of data.
364
365
*/
366
/*[clinic input]
367
_codecs.utf_16_ex_decode
368
    data: Py_buffer
369
    errors: str(accept={str, NoneType}) = None
370
    byteorder: int = 0
371
    final: bool = False
372
    /
373
[clinic start generated code]*/
374
375
static PyObject *
376
_codecs_utf_16_ex_decode_impl(PyObject *module, Py_buffer *data,
377
                              const char *errors, int byteorder, int final)
378
/*[clinic end generated code: output=0f385f251ecc1988 input=f368a51cf384bf4c]*/
379
0
{
380
    /* This is overwritten unless final is true. */
381
0
    Py_ssize_t consumed = data->len;
382
383
0
    PyObject *decoded = PyUnicode_DecodeUTF16Stateful(data->buf, data->len,
384
0
                                                      errors, &byteorder,
385
0
                                                      final ? NULL : &consumed);
386
0
    if (decoded == NULL)
387
0
        return NULL;
388
0
    return Py_BuildValue("Nni", decoded, consumed, byteorder);
389
0
}
390
391
/*[clinic input]
392
_codecs.utf_32_decode
393
    data: Py_buffer
394
    errors: str(accept={str, NoneType}) = None
395
    final: bool = False
396
    /
397
[clinic start generated code]*/
398
399
static PyObject *
400
_codecs_utf_32_decode_impl(PyObject *module, Py_buffer *data,
401
                           const char *errors, int final)
402
/*[clinic end generated code: output=2fc961807f7b145f input=fcdf3658c5e9b5f3]*/
403
36.9k
{
404
36.9k
    int byteorder = 0;
405
    /* This is overwritten unless final is true. */
406
36.9k
    Py_ssize_t consumed = data->len;
407
36.9k
    PyObject *decoded = PyUnicode_DecodeUTF32Stateful(data->buf, data->len,
408
36.9k
                                                      errors, &byteorder,
409
36.9k
                                                      final ? NULL : &consumed);
410
36.9k
    return codec_tuple(decoded, consumed);
411
36.9k
}
412
413
/*[clinic input]
414
_codecs.utf_32_le_decode
415
    data: Py_buffer
416
    errors: str(accept={str, NoneType}) = None
417
    final: bool = False
418
    /
419
[clinic start generated code]*/
420
421
static PyObject *
422
_codecs_utf_32_le_decode_impl(PyObject *module, Py_buffer *data,
423
                              const char *errors, int final)
424
/*[clinic end generated code: output=ec8f46b67a94f3e6 input=12220556e885f817]*/
425
44
{
426
44
    int byteorder = -1;
427
    /* This is overwritten unless final is true. */
428
44
    Py_ssize_t consumed = data->len;
429
44
    PyObject *decoded = PyUnicode_DecodeUTF32Stateful(data->buf, data->len,
430
44
                                                      errors, &byteorder,
431
44
                                                      final ? NULL : &consumed);
432
44
    return codec_tuple(decoded, consumed);
433
44
}
434
435
/*[clinic input]
436
_codecs.utf_32_be_decode
437
    data: Py_buffer
438
    errors: str(accept={str, NoneType}) = None
439
    final: bool = False
440
    /
441
[clinic start generated code]*/
442
443
static PyObject *
444
_codecs_utf_32_be_decode_impl(PyObject *module, Py_buffer *data,
445
                              const char *errors, int final)
446
/*[clinic end generated code: output=ff82bae862c92c4e input=2bc669b4781598db]*/
447
62
{
448
62
    int byteorder = 1;
449
    /* This is overwritten unless final is true. */
450
62
    Py_ssize_t consumed = data->len;
451
62
    PyObject *decoded = PyUnicode_DecodeUTF32Stateful(data->buf, data->len,
452
62
                                                      errors, &byteorder,
453
62
                                                      final ? NULL : &consumed);
454
62
    return codec_tuple(decoded, consumed);
455
62
}
456
457
/* This non-standard version also provides access to the byteorder
458
   parameter of the builtin UTF-32 codec.
459
460
   It returns a tuple (unicode, bytesread, byteorder) with byteorder
461
   being the value in effect at the end of data.
462
463
*/
464
/*[clinic input]
465
_codecs.utf_32_ex_decode
466
    data: Py_buffer
467
    errors: str(accept={str, NoneType}) = None
468
    byteorder: int = 0
469
    final: bool = False
470
    /
471
[clinic start generated code]*/
472
473
static PyObject *
474
_codecs_utf_32_ex_decode_impl(PyObject *module, Py_buffer *data,
475
                              const char *errors, int byteorder, int final)
476
/*[clinic end generated code: output=6bfb177dceaf4848 input=4a2323d0013620df]*/
477
0
{
478
0
    Py_ssize_t consumed = data->len;
479
0
    PyObject *decoded = PyUnicode_DecodeUTF32Stateful(data->buf, data->len,
480
0
                                                      errors, &byteorder,
481
0
                                                      final ? NULL : &consumed);
482
0
    if (decoded == NULL)
483
0
        return NULL;
484
0
    return Py_BuildValue("Nni", decoded, consumed, byteorder);
485
0
}
486
487
/*[clinic input]
488
_codecs.unicode_escape_decode
489
    data: Py_buffer(accept={str, buffer})
490
    errors: str(accept={str, NoneType}) = None
491
    final: bool = True
492
    /
493
[clinic start generated code]*/
494
495
static PyObject *
496
_codecs_unicode_escape_decode_impl(PyObject *module, Py_buffer *data,
497
                                   const char *errors, int final)
498
/*[clinic end generated code: output=b284f97b12c635ee input=15019f081ffe272b]*/
499
553
{
500
553
    Py_ssize_t consumed = data->len;
501
553
    PyObject *decoded = _PyUnicode_DecodeUnicodeEscapeStateful(data->buf, data->len,
502
553
                                                               errors,
503
553
                                                               final ? NULL : &consumed);
504
553
    return codec_tuple(decoded, consumed);
505
553
}
506
507
/*[clinic input]
508
_codecs.raw_unicode_escape_decode
509
    data: Py_buffer(accept={str, buffer})
510
    errors: str(accept={str, NoneType}) = None
511
    final: bool = True
512
    /
513
[clinic start generated code]*/
514
515
static PyObject *
516
_codecs_raw_unicode_escape_decode_impl(PyObject *module, Py_buffer *data,
517
                                       const char *errors, int final)
518
/*[clinic end generated code: output=11dbd96301e2879e input=b93f823aa8c343ad]*/
519
106
{
520
106
    Py_ssize_t consumed = data->len;
521
106
    PyObject *decoded = _PyUnicode_DecodeRawUnicodeEscapeStateful(data->buf, data->len,
522
106
                                                                  errors,
523
106
                                                                  final ? NULL : &consumed);
524
106
    return codec_tuple(decoded, consumed);
525
106
}
526
527
/*[clinic input]
528
_codecs.latin_1_decode
529
    data: Py_buffer
530
    errors: str(accept={str, NoneType}) = None
531
    /
532
[clinic start generated code]*/
533
534
static PyObject *
535
_codecs_latin_1_decode_impl(PyObject *module, Py_buffer *data,
536
                            const char *errors)
537
/*[clinic end generated code: output=07f3dfa3f72c7d8f input=76ca58fd6dcd08c7]*/
538
4.35k
{
539
4.35k
    PyObject *decoded = PyUnicode_DecodeLatin1(data->buf, data->len, errors);
540
4.35k
    return codec_tuple(decoded, data->len);
541
4.35k
}
542
543
/*[clinic input]
544
_codecs.ascii_decode
545
    data: Py_buffer
546
    errors: str(accept={str, NoneType}) = None
547
    /
548
[clinic start generated code]*/
549
550
static PyObject *
551
_codecs_ascii_decode_impl(PyObject *module, Py_buffer *data,
552
                          const char *errors)
553
/*[clinic end generated code: output=2627d72058d42429 input=e428a267a04b4481]*/
554
26.5k
{
555
26.5k
    PyObject *decoded = PyUnicode_DecodeASCII(data->buf, data->len, errors);
556
26.5k
    return codec_tuple(decoded, data->len);
557
26.5k
}
558
559
/*[clinic input]
560
_codecs.charmap_decode
561
    data: Py_buffer
562
    errors: str(accept={str, NoneType}) = None
563
    mapping: object = None
564
    /
565
[clinic start generated code]*/
566
567
static PyObject *
568
_codecs_charmap_decode_impl(PyObject *module, Py_buffer *data,
569
                            const char *errors, PyObject *mapping)
570
/*[clinic end generated code: output=2c335b09778cf895 input=15b69df43458eb40]*/
571
614k
{
572
614k
    PyObject *decoded;
573
574
614k
    if (mapping == Py_None)
575
27
        mapping = NULL;
576
577
614k
    decoded = PyUnicode_DecodeCharmap(data->buf, data->len, mapping, errors);
578
614k
    return codec_tuple(decoded, data->len);
579
614k
}
580
581
#ifdef MS_WINDOWS
582
583
/*[clinic input]
584
_codecs.mbcs_decode
585
    data: Py_buffer
586
    errors: str(accept={str, NoneType}) = None
587
    final: bool = False
588
    /
589
[clinic start generated code]*/
590
591
static PyObject *
592
_codecs_mbcs_decode_impl(PyObject *module, Py_buffer *data,
593
                         const char *errors, int final)
594
/*[clinic end generated code: output=39b65b8598938c4b input=f144ad1ed6d8f5a6]*/
595
{
596
    Py_ssize_t consumed = data->len;
597
    PyObject *decoded = PyUnicode_DecodeMBCSStateful(data->buf, data->len,
598
            errors, final ? NULL : &consumed);
599
    return codec_tuple(decoded, consumed);
600
}
601
602
/*[clinic input]
603
_codecs.oem_decode
604
    data: Py_buffer
605
    errors: str(accept={str, NoneType}) = None
606
    final: bool = False
607
    /
608
[clinic start generated code]*/
609
610
static PyObject *
611
_codecs_oem_decode_impl(PyObject *module, Py_buffer *data,
612
                        const char *errors, int final)
613
/*[clinic end generated code: output=da1617612f3fcad8 input=629bf87376d211b4]*/
614
{
615
    Py_ssize_t consumed = data->len;
616
    PyObject *decoded = PyUnicode_DecodeCodePageStateful(CP_OEMCP,
617
        data->buf, data->len, errors, final ? NULL : &consumed);
618
    return codec_tuple(decoded, consumed);
619
}
620
621
/*[clinic input]
622
_codecs.code_page_decode
623
    codepage: int
624
    data: Py_buffer
625
    errors: str(accept={str, NoneType}) = None
626
    final: bool = False
627
    /
628
[clinic start generated code]*/
629
630
static PyObject *
631
_codecs_code_page_decode_impl(PyObject *module, int codepage,
632
                              Py_buffer *data, const char *errors, int final)
633
/*[clinic end generated code: output=53008ea967da3fff input=6a32589b0658c277]*/
634
{
635
    Py_ssize_t consumed = data->len;
636
    PyObject *decoded = PyUnicode_DecodeCodePageStateful(codepage,
637
                                                         data->buf, data->len,
638
                                                         errors,
639
                                                         final ? NULL : &consumed);
640
    return codec_tuple(decoded, consumed);
641
}
642
643
#endif /* MS_WINDOWS */
644
645
#ifdef HAVE_ICONV
646
647
/*[clinic input]
648
_codecs.iconv_decode
649
    encoding: str
650
    data: Py_buffer
651
    errors: str(accept={str, NoneType}) = None
652
    final: bool = False
653
    /
654
[clinic start generated code]*/
655
656
static PyObject *
657
_codecs_iconv_decode_impl(PyObject *module, const char *encoding,
658
                          Py_buffer *data, const char *errors, int final)
659
/*[clinic end generated code: output=6c6145a9decc2ba8 input=d15a04d7d3a3e0cd]*/
660
2.15k
{
661
2.15k
    Py_ssize_t consumed = data->len;
662
2.15k
    PyObject *decoded = _PyUnicode_DecodeIconv(encoding, data->buf, data->len,
663
2.15k
                                               errors,
664
2.15k
                                               final ? NULL : &consumed);
665
2.15k
    return codec_tuple(decoded, consumed);
666
2.15k
}
667
668
#endif /* HAVE_ICONV */
669
670
/* --- Encoder ------------------------------------------------------------ */
671
672
/*[clinic input]
673
_codecs.readbuffer_encode
674
    data: Py_buffer(accept={str, buffer})
675
    errors: str(accept={str, NoneType}) = None
676
    /
677
[clinic start generated code]*/
678
679
static PyObject *
680
_codecs_readbuffer_encode_impl(PyObject *module, Py_buffer *data,
681
                               const char *errors)
682
/*[clinic end generated code: output=c645ea7cdb3d6e86 input=aa10cfdf252455c5]*/
683
0
{
684
0
    PyObject *result = PyBytes_FromStringAndSize(data->buf, data->len);
685
0
    return codec_tuple(result, data->len);
686
0
}
687
688
/*[clinic input]
689
_codecs.utf_7_encode
690
    str: unicode
691
    errors: str(accept={str, NoneType}) = None
692
    /
693
[clinic start generated code]*/
694
695
static PyObject *
696
_codecs_utf_7_encode_impl(PyObject *module, PyObject *str,
697
                          const char *errors)
698
/*[clinic end generated code: output=0feda21ffc921bc8 input=2546dbbb3fa53114]*/
699
0
{
700
0
    return codec_tuple(_PyUnicode_EncodeUTF7(str, errors),
701
0
                       PyUnicode_GET_LENGTH(str));
702
0
}
703
704
/*[clinic input]
705
_codecs.utf_8_encode
706
    str: unicode
707
    errors: str(accept={str, NoneType}) = None
708
    /
709
[clinic start generated code]*/
710
711
static PyObject *
712
_codecs_utf_8_encode_impl(PyObject *module, PyObject *str,
713
                          const char *errors)
714
/*[clinic end generated code: output=02bf47332b9c796c input=a3e71ae01c3f93f3]*/
715
0
{
716
0
    return codec_tuple(_PyUnicode_AsUTF8String(str, errors),
717
0
                       PyUnicode_GET_LENGTH(str));
718
0
}
719
720
/* This version provides access to the byteorder parameter of the
721
   builtin UTF-16 codecs as optional third argument. It defaults to 0
722
   which means: use the native byte order and prepend the data with a
723
   BOM mark.
724
725
*/
726
727
/*[clinic input]
728
_codecs.utf_16_encode
729
    str: unicode
730
    errors: str(accept={str, NoneType}) = None
731
    byteorder: int = 0
732
    /
733
[clinic start generated code]*/
734
735
static PyObject *
736
_codecs_utf_16_encode_impl(PyObject *module, PyObject *str,
737
                           const char *errors, int byteorder)
738
/*[clinic end generated code: output=c654e13efa2e64e4 input=68cdc2eb8338555d]*/
739
0
{
740
0
    return codec_tuple(_PyUnicode_EncodeUTF16(str, errors, byteorder),
741
0
                       PyUnicode_GET_LENGTH(str));
742
0
}
743
744
/*[clinic input]
745
_codecs.utf_16_le_encode
746
    str: unicode
747
    errors: str(accept={str, NoneType}) = None
748
    /
749
[clinic start generated code]*/
750
751
static PyObject *
752
_codecs_utf_16_le_encode_impl(PyObject *module, PyObject *str,
753
                              const char *errors)
754
/*[clinic end generated code: output=431b01e55f2d4995 input=83d042706eed6798]*/
755
4.74k
{
756
4.74k
    return codec_tuple(_PyUnicode_EncodeUTF16(str, errors, -1),
757
4.74k
                       PyUnicode_GET_LENGTH(str));
758
4.74k
}
759
760
/*[clinic input]
761
_codecs.utf_16_be_encode
762
    str: unicode
763
    errors: str(accept={str, NoneType}) = None
764
    /
765
[clinic start generated code]*/
766
767
static PyObject *
768
_codecs_utf_16_be_encode_impl(PyObject *module, PyObject *str,
769
                              const char *errors)
770
/*[clinic end generated code: output=96886a6fd54dcae3 input=6f1e9e623b03071b]*/
771
4.96k
{
772
4.96k
    return codec_tuple(_PyUnicode_EncodeUTF16(str, errors, +1),
773
4.96k
                       PyUnicode_GET_LENGTH(str));
774
4.96k
}
775
776
/* This version provides access to the byteorder parameter of the
777
   builtin UTF-32 codecs as optional third argument. It defaults to 0
778
   which means: use the native byte order and prepend the data with a
779
   BOM mark.
780
781
*/
782
783
/*[clinic input]
784
_codecs.utf_32_encode
785
    str: unicode
786
    errors: str(accept={str, NoneType}) = None
787
    byteorder: int = 0
788
    /
789
[clinic start generated code]*/
790
791
static PyObject *
792
_codecs_utf_32_encode_impl(PyObject *module, PyObject *str,
793
                           const char *errors, int byteorder)
794
/*[clinic end generated code: output=5c760da0c09a8b83 input=8ec4c64d983bc52b]*/
795
0
{
796
0
    return codec_tuple(_PyUnicode_EncodeUTF32(str, errors, byteorder),
797
0
                       PyUnicode_GET_LENGTH(str));
798
0
}
799
800
/*[clinic input]
801
_codecs.utf_32_le_encode
802
    str: unicode
803
    errors: str(accept={str, NoneType}) = None
804
    /
805
[clinic start generated code]*/
806
807
static PyObject *
808
_codecs_utf_32_le_encode_impl(PyObject *module, PyObject *str,
809
                              const char *errors)
810
/*[clinic end generated code: output=b65cd176de8e36d6 input=f0918d41de3eb1b1]*/
811
0
{
812
0
    return codec_tuple(_PyUnicode_EncodeUTF32(str, errors, -1),
813
0
                       PyUnicode_GET_LENGTH(str));
814
0
}
815
816
/*[clinic input]
817
_codecs.utf_32_be_encode
818
    str: unicode
819
    errors: str(accept={str, NoneType}) = None
820
    /
821
[clinic start generated code]*/
822
823
static PyObject *
824
_codecs_utf_32_be_encode_impl(PyObject *module, PyObject *str,
825
                              const char *errors)
826
/*[clinic end generated code: output=1d9e71a9358709e9 input=967a99a95748b557]*/
827
0
{
828
0
    return codec_tuple(_PyUnicode_EncodeUTF32(str, errors, +1),
829
0
                       PyUnicode_GET_LENGTH(str));
830
0
}
831
832
/*[clinic input]
833
_codecs.unicode_escape_encode
834
    str: unicode
835
    errors: str(accept={str, NoneType}) = None
836
    /
837
[clinic start generated code]*/
838
839
static PyObject *
840
_codecs_unicode_escape_encode_impl(PyObject *module, PyObject *str,
841
                                   const char *errors)
842
/*[clinic end generated code: output=66271b30bc4f7a3c input=8c4de07597054e33]*/
843
753k
{
844
753k
    return codec_tuple(PyUnicode_AsUnicodeEscapeString(str),
845
753k
                       PyUnicode_GET_LENGTH(str));
846
753k
}
847
848
/*[clinic input]
849
_codecs.raw_unicode_escape_encode
850
    str: unicode
851
    errors: str(accept={str, NoneType}) = None
852
    /
853
[clinic start generated code]*/
854
855
static PyObject *
856
_codecs_raw_unicode_escape_encode_impl(PyObject *module, PyObject *str,
857
                                       const char *errors)
858
/*[clinic end generated code: output=a66a806ed01c830a input=4aa6f280d78e4574]*/
859
247k
{
860
247k
    return codec_tuple(PyUnicode_AsRawUnicodeEscapeString(str),
861
247k
                       PyUnicode_GET_LENGTH(str));
862
247k
}
863
864
/*[clinic input]
865
_codecs.latin_1_encode
866
    str: unicode
867
    errors: str(accept={str, NoneType}) = None
868
    /
869
[clinic start generated code]*/
870
871
static PyObject *
872
_codecs_latin_1_encode_impl(PyObject *module, PyObject *str,
873
                            const char *errors)
874
/*[clinic end generated code: output=2c28c83a27884e08 input=ec3ef74bf85c5c5d]*/
875
0
{
876
0
    return codec_tuple(_PyUnicode_AsLatin1String(str, errors),
877
0
                       PyUnicode_GET_LENGTH(str));
878
0
}
879
880
/*[clinic input]
881
_codecs.ascii_encode
882
    str: unicode
883
    errors: str(accept={str, NoneType}) = None
884
    /
885
[clinic start generated code]*/
886
887
static PyObject *
888
_codecs_ascii_encode_impl(PyObject *module, PyObject *str,
889
                          const char *errors)
890
/*[clinic end generated code: output=b5e035182d33befc input=93e6e602838bd3de]*/
891
0
{
892
0
    return codec_tuple(_PyUnicode_AsASCIIString(str, errors),
893
0
                       PyUnicode_GET_LENGTH(str));
894
0
}
895
896
/*[clinic input]
897
_codecs.charmap_encode
898
    str: unicode
899
    errors: str(accept={str, NoneType}) = None
900
    mapping: object = None
901
    /
902
[clinic start generated code]*/
903
904
static PyObject *
905
_codecs_charmap_encode_impl(PyObject *module, PyObject *str,
906
                            const char *errors, PyObject *mapping)
907
/*[clinic end generated code: output=047476f48495a9e9 input=2a98feae73dadce8]*/
908
0
{
909
0
    if (mapping == Py_None)
910
0
        mapping = NULL;
911
912
0
    return codec_tuple(_PyUnicode_EncodeCharmap(str, mapping, errors),
913
0
                       PyUnicode_GET_LENGTH(str));
914
0
}
915
916
/*[clinic input]
917
_codecs.charmap_build
918
    map: unicode
919
    /
920
[clinic start generated code]*/
921
922
static PyObject *
923
_codecs_charmap_build_impl(PyObject *module, PyObject *map)
924
/*[clinic end generated code: output=bb073c27031db9ac input=d91a91d1717dbc6d]*/
925
135
{
926
135
    return PyUnicode_BuildEncodingMap(map);
927
135
}
928
929
#ifdef MS_WINDOWS
930
931
/*[clinic input]
932
_codecs.mbcs_encode
933
    str: unicode
934
    errors: str(accept={str, NoneType}) = None
935
    /
936
[clinic start generated code]*/
937
938
static PyObject *
939
_codecs_mbcs_encode_impl(PyObject *module, PyObject *str, const char *errors)
940
/*[clinic end generated code: output=76e2e170c966c080 input=2e932fc289ea5a5b]*/
941
{
942
    return codec_tuple(PyUnicode_EncodeCodePage(CP_ACP, str, errors),
943
                       PyUnicode_GET_LENGTH(str));
944
}
945
946
/*[clinic input]
947
_codecs.oem_encode
948
    str: unicode
949
    errors: str(accept={str, NoneType}) = None
950
    /
951
[clinic start generated code]*/
952
953
static PyObject *
954
_codecs_oem_encode_impl(PyObject *module, PyObject *str, const char *errors)
955
/*[clinic end generated code: output=65d5982c737de649 input=9eac86dc21eb14f2]*/
956
{
957
    return codec_tuple(PyUnicode_EncodeCodePage(CP_OEMCP, str, errors),
958
        PyUnicode_GET_LENGTH(str));
959
}
960
961
/*[clinic input]
962
_codecs.code_page_encode
963
    code_page: int
964
    str: unicode
965
    errors: str(accept={str, NoneType}) = None
966
    /
967
[clinic start generated code]*/
968
969
static PyObject *
970
_codecs_code_page_encode_impl(PyObject *module, int code_page, PyObject *str,
971
                              const char *errors)
972
/*[clinic end generated code: output=45673f6085657a9e input=7d18a33bc8cd0f94]*/
973
{
974
    return codec_tuple(PyUnicode_EncodeCodePage(code_page, str, errors),
975
                       PyUnicode_GET_LENGTH(str));
976
}
977
978
#endif /* MS_WINDOWS */
979
980
#ifdef HAVE_ICONV
981
982
/*[clinic input]
983
_codecs.iconv_encode
984
    encoding: str
985
    str: unicode
986
    errors: str(accept={str, NoneType}) = None
987
    /
988
[clinic start generated code]*/
989
990
static PyObject *
991
_codecs_iconv_encode_impl(PyObject *module, const char *encoding,
992
                          PyObject *str, const char *errors)
993
/*[clinic end generated code: output=bda0c5acd9be0f17 input=53a1e2028c9e2b43]*/
994
67.8k
{
995
67.8k
    return codec_tuple(_PyUnicode_EncodeIconv(encoding, str, errors),
996
67.8k
                       PyUnicode_GET_LENGTH(str));
997
67.8k
}
998
999
#endif /* HAVE_ICONV */
1000
1001
/* --- Error handler registry --------------------------------------------- */
1002
1003
/*[clinic input]
1004
_codecs.register_error
1005
    errors: str
1006
    handler: object
1007
    /
1008
1009
Register the specified error handler under the name errors.
1010
1011
handler must be a callable object, that will be called with an exception
1012
instance containing information about the location of the
1013
encoding/decoding error and must return a (replacement, new position)
1014
tuple.
1015
[clinic start generated code]*/
1016
1017
static PyObject *
1018
_codecs_register_error_impl(PyObject *module, const char *errors,
1019
                            PyObject *handler)
1020
/*[clinic end generated code: output=fa2f7d1879b3067d input=5bea01dfe835d9d8]*/
1021
0
{
1022
0
    if (PyCodec_RegisterError(errors, handler))
1023
0
        return NULL;
1024
0
    Py_RETURN_NONE;
1025
0
}
1026
1027
/*[clinic input]
1028
_codecs._unregister_error -> bool
1029
    errors: str
1030
    /
1031
1032
Un-register the specified error handler for the error handling `errors'.
1033
1034
Only custom error handlers can be un-registered. An exception is raised
1035
if the error handling is a built-in one (e.g., 'strict'), or if an error
1036
occurs.
1037
1038
Otherwise, this returns True if a custom handler has been successfully
1039
un-registered, and False if no custom handler for the specified error
1040
handling exists.
1041
1042
[clinic start generated code]*/
1043
1044
static int
1045
_codecs__unregister_error_impl(PyObject *module, const char *errors)
1046
/*[clinic end generated code: output=28c22be667465503 input=a63ab9e9ce1686d4]*/
1047
0
{
1048
0
    return _PyCodec_UnregisterError(errors);
1049
0
}
1050
1051
/*[clinic input]
1052
_codecs.lookup_error
1053
    name: str
1054
    /
1055
1056
lookup_error(errors) -> handler
1057
1058
Return the error handler for the specified error handling name or raise
1059
a LookupError, if no handler exists under this name.
1060
[clinic start generated code]*/
1061
1062
static PyObject *
1063
_codecs_lookup_error_impl(PyObject *module, const char *name)
1064
/*[clinic end generated code: output=087f05dc0c9a98cc input=86cfb6a7a9c67113]*/
1065
216
{
1066
216
    return PyCodec_LookupError(name);
1067
216
}
1068
1069
extern int _Py_normalize_encoding(const char *, char *, size_t, int);
1070
1071
/*[clinic input]
1072
_codecs._normalize_encoding
1073
    encoding: unicode
1074
1075
Normalize an encoding name *encoding*.
1076
1077
Used for encodings.normalize_encoding. Does not convert to lower case.
1078
[clinic start generated code]*/
1079
1080
static PyObject *
1081
_codecs__normalize_encoding_impl(PyObject *module, PyObject *encoding)
1082
/*[clinic end generated code: output=d27465d81e361f8e input=3ff3f4d64995b988]*/
1083
3.66k
{
1084
3.66k
    Py_ssize_t len;
1085
3.66k
    const char *cstr = PyUnicode_AsUTF8AndSize(encoding, &len);
1086
3.66k
    if (cstr == NULL) {
1087
0
        return NULL;
1088
0
    }
1089
1090
3.66k
    if (len > PY_SSIZE_T_MAX) {
1091
0
        PyErr_SetString(PyExc_OverflowError, "encoding is too large");
1092
0
        return NULL;
1093
0
    }
1094
1095
3.66k
    char *normalized = PyMem_Malloc(len + 1);
1096
3.66k
    if (normalized == NULL) {
1097
0
        return PyErr_NoMemory();
1098
0
    }
1099
1100
3.66k
    if (!_Py_normalize_encoding(cstr, normalized, len + 1, 0)) {
1101
0
        PyMem_Free(normalized);
1102
0
        return NULL;
1103
0
    }
1104
1105
3.66k
    PyObject *result = PyUnicode_FromString(normalized);
1106
3.66k
    PyMem_Free(normalized);
1107
3.66k
    return result;
1108
3.66k
}
1109
1110
/* --- Module API --------------------------------------------------------- */
1111
1112
static PyMethodDef _codecs_functions[] = {
1113
    _CODECS_REGISTER_METHODDEF
1114
    _CODECS_UNREGISTER_METHODDEF
1115
    _CODECS_LOOKUP_METHODDEF
1116
    _CODECS_ENCODE_METHODDEF
1117
    _CODECS_DECODE_METHODDEF
1118
    _CODECS_ESCAPE_ENCODE_METHODDEF
1119
    _CODECS_ESCAPE_DECODE_METHODDEF
1120
    _CODECS_UTF_8_ENCODE_METHODDEF
1121
    _CODECS_UTF_8_DECODE_METHODDEF
1122
    _CODECS_UTF_7_ENCODE_METHODDEF
1123
    _CODECS_UTF_7_DECODE_METHODDEF
1124
    _CODECS_UTF_16_ENCODE_METHODDEF
1125
    _CODECS_UTF_16_LE_ENCODE_METHODDEF
1126
    _CODECS_UTF_16_BE_ENCODE_METHODDEF
1127
    _CODECS_UTF_16_DECODE_METHODDEF
1128
    _CODECS_UTF_16_LE_DECODE_METHODDEF
1129
    _CODECS_UTF_16_BE_DECODE_METHODDEF
1130
    _CODECS_UTF_16_EX_DECODE_METHODDEF
1131
    _CODECS_UTF_32_ENCODE_METHODDEF
1132
    _CODECS_UTF_32_LE_ENCODE_METHODDEF
1133
    _CODECS_UTF_32_BE_ENCODE_METHODDEF
1134
    _CODECS_UTF_32_DECODE_METHODDEF
1135
    _CODECS_UTF_32_LE_DECODE_METHODDEF
1136
    _CODECS_UTF_32_BE_DECODE_METHODDEF
1137
    _CODECS_UTF_32_EX_DECODE_METHODDEF
1138
    _CODECS_UNICODE_ESCAPE_ENCODE_METHODDEF
1139
    _CODECS_UNICODE_ESCAPE_DECODE_METHODDEF
1140
    _CODECS_RAW_UNICODE_ESCAPE_ENCODE_METHODDEF
1141
    _CODECS_RAW_UNICODE_ESCAPE_DECODE_METHODDEF
1142
    _CODECS_LATIN_1_ENCODE_METHODDEF
1143
    _CODECS_LATIN_1_DECODE_METHODDEF
1144
    _CODECS_ASCII_ENCODE_METHODDEF
1145
    _CODECS_ASCII_DECODE_METHODDEF
1146
    _CODECS_CHARMAP_ENCODE_METHODDEF
1147
    _CODECS_CHARMAP_DECODE_METHODDEF
1148
    _CODECS_CHARMAP_BUILD_METHODDEF
1149
    _CODECS_READBUFFER_ENCODE_METHODDEF
1150
    _CODECS_MBCS_ENCODE_METHODDEF
1151
    _CODECS_MBCS_DECODE_METHODDEF
1152
    _CODECS_OEM_ENCODE_METHODDEF
1153
    _CODECS_OEM_DECODE_METHODDEF
1154
    _CODECS_CODE_PAGE_ENCODE_METHODDEF
1155
    _CODECS_CODE_PAGE_DECODE_METHODDEF
1156
    _CODECS_ICONV_ENCODE_METHODDEF
1157
    _CODECS_ICONV_DECODE_METHODDEF
1158
    _CODECS_REGISTER_ERROR_METHODDEF
1159
    _CODECS__UNREGISTER_ERROR_METHODDEF
1160
    _CODECS_LOOKUP_ERROR_METHODDEF
1161
    _CODECS__NORMALIZE_ENCODING_METHODDEF
1162
    {NULL, NULL}                /* sentinel */
1163
};
1164
1165
static PyModuleDef_Slot _codecs_slots[] = {
1166
    _Py_ABI_SLOT,
1167
    {Py_mod_multiple_interpreters, Py_MOD_PER_INTERPRETER_GIL_SUPPORTED},
1168
    {Py_mod_gil, Py_MOD_GIL_NOT_USED},
1169
    {0, NULL}
1170
};
1171
1172
static struct PyModuleDef codecsmodule = {
1173
        PyModuleDef_HEAD_INIT,
1174
        "_codecs",
1175
        NULL,
1176
        0,
1177
        _codecs_functions,
1178
        _codecs_slots,
1179
        NULL,
1180
        NULL,
1181
        NULL
1182
};
1183
1184
PyMODINIT_FUNC
1185
PyInit__codecs(void)
1186
36
{
1187
36
    return PyModuleDef_Init(&codecsmodule);
1188
36
}