codecs.c 44.7 KB
Newer Older
1 2 3 4 5 6
/* ------------------------------------------------------------------------

   Python Codec Registry and support functions

Written by Marc-Andre Lemburg (mal@lemburg.com).

7
Copyright (c) Corporation for National Research Initiatives.
8 9 10 11

   ------------------------------------------------------------------------ */

#include "Python.h"
12
#include "pycore_pystate.h"
13
#include "ucnhash.h"
14 15
#include <ctype.h>

16 17
const char *Py_hexdigits = "0123456789abcdef";

18 19 20
/* --- Codec Registry ----------------------------------------------------- */

/* Import the standard encodings package which will register the first
21
   codec search function.
22 23 24 25

   This is done in a lazy way so that the Unicode implementation does
   not downgrade startup time of scripts not needing it.

26 27
   ImportErrors are silently ignored by this function. Only one try is
   made.
28 29 30

*/

31
static int _PyCodecRegistry_Init(void); /* Forward */
32 33 34

int PyCodec_Register(PyObject *search_function)
{
35
    PyInterpreterState *interp = _PyInterpreterState_Get();
36
    if (interp->codec_search_path == NULL && _PyCodecRegistry_Init())
37
        goto onError;
38
    if (search_function == NULL) {
39 40
        PyErr_BadArgument();
        goto onError;
41 42
    }
    if (!PyCallable_Check(search_function)) {
43 44
        PyErr_SetString(PyExc_TypeError, "argument must be callable");
        goto onError;
45
    }
46
    return PyList_Append(interp->codec_search_path, search_function);
47 48 49

 onError:
    return -1;
50 51
}

52 53 54
/* Convert a string to a normalized Python string: all characters are
   converted to lower case, spaces are replaced with underscores. */

55
static
56
PyObject *normalizestring(const char *string)
57
{
58
    size_t i;
59
    size_t len = strlen(string);
60 61
    char *p;
    PyObject *v;
62

63
    if (len > PY_SSIZE_T_MAX) {
64 65
        PyErr_SetString(PyExc_OverflowError, "string is too large");
        return NULL;
66
    }
67 68 69

    p = PyMem_Malloc(len + 1);
    if (p == NULL)
70
        return PyErr_NoMemory();
71
    for (i = 0; i < len; i++) {
72
        char ch = string[i];
73 74 75
        if (ch == ' ')
            ch = '-';
        else
76
            ch = Py_TOLOWER(Py_CHARMASK(ch));
77
        p[i] = ch;
78
    }
79 80 81
    p[i] = '\0';
    v = PyUnicode_FromString(p);
    PyMem_Free(p);
82 83 84 85 86 87 88 89 90 91
    return v;
}

/* Lookup the given encoding and return a tuple providing the codec
   facilities.

   The encoding string is looked up converted to all lower-case
   characters. This makes encodings looked up through this mechanism
   effectively case-insensitive.

92
   If no codec is found, a LookupError is set and NULL returned.
93 94 95 96 97 98

   As side effect, this tries to load the encodings package, if not
   yet done. This is part of the lazy load strategy for the encodings
   package.

*/
99 100 101

PyObject *_PyCodec_Lookup(const char *encoding)
{
Guido van Rossum's avatar
Guido van Rossum committed
102
    PyObject *result, *args = NULL, *v;
103
    Py_ssize_t i, len;
104

105
    if (encoding == NULL) {
106 107
        PyErr_BadArgument();
        goto onError;
108
    }
109

110
    PyInterpreterState *interp = _PyInterpreterState_GET_UNSAFE();
111
    if (interp->codec_search_path == NULL && _PyCodecRegistry_Init())
112
        goto onError;
113

114
    /* Convert the encoding to a normalized Python string: all
115
       characters are converted to lower case, spaces and hyphens are
116 117
       replaced with underscores. */
    v = normalizestring(encoding);
118
    if (v == NULL)
119
        goto onError;
120
    PyUnicode_InternInPlace(&v);
121 122

    /* First, try to lookup the name in the registry dictionary */
123
    result = PyDict_GetItem(interp->codec_search_cache, v);
124
    if (result != NULL) {
125 126 127
        Py_INCREF(result);
        Py_DECREF(v);
        return result;
128
    }
129

130 131 132
    /* Next, scan the search functions in order of registration */
    args = PyTuple_New(1);
    if (args == NULL)
133
        goto onError;
134
    PyTuple_SET_ITEM(args,0,v);
Guido van Rossum's avatar
Guido van Rossum committed
135

136
    len = PyList_Size(interp->codec_search_path);
Guido van Rossum's avatar
Guido van Rossum committed
137
    if (len < 0)
138
        goto onError;
139
    if (len == 0) {
140 141 142 143
        PyErr_SetString(PyExc_LookupError,
                        "no codec search functions registered: "
                        "can't find encoding");
        goto onError;
144
    }
145 146

    for (i = 0; i < len; i++) {
147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165
        PyObject *func;

        func = PyList_GetItem(interp->codec_search_path, i);
        if (func == NULL)
            goto onError;
        result = PyEval_CallObject(func, args);
        if (result == NULL)
            goto onError;
        if (result == Py_None) {
            Py_DECREF(result);
            continue;
        }
        if (!PyTuple_Check(result) || PyTuple_GET_SIZE(result) != 4) {
            PyErr_SetString(PyExc_TypeError,
                            "codec search functions must return 4-tuples");
            Py_DECREF(result);
            goto onError;
        }
        break;
166 167
    }
    if (i == len) {
168 169
        /* XXX Perhaps we should cache misses too ? */
        PyErr_Format(PyExc_LookupError,
170
                     "unknown encoding: %s", encoding);
171
        goto onError;
172 173 174
    }

    /* Cache and return the result */
Neal Norwitz's avatar
Neal Norwitz committed
175
    if (PyDict_SetItem(interp->codec_search_cache, v, result) < 0) {
176 177
        Py_DECREF(result);
        goto onError;
Neal Norwitz's avatar
Neal Norwitz committed
178
    }
179 180 181 182 183 184 185 186
    Py_DECREF(args);
    return result;

 onError:
    Py_XDECREF(args);
    return NULL;
}

187 188 189 190 191
int _PyCodec_Forget(const char *encoding)
{
    PyObject *v;
    int result;

192
    PyInterpreterState *interp = _PyInterpreterState_Get();
193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211
    if (interp->codec_search_path == NULL) {
        return -1;
    }

    /* Convert the encoding to a normalized Python string: all
       characters are converted to lower case, spaces and hyphens are
       replaced with underscores. */
    v = normalizestring(encoding);
    if (v == NULL) {
        return -1;
    }

    /* Drop the named codec from the internal cache */
    result = PyDict_DelItem(interp->codec_search_cache, v);
    Py_DECREF(v);

    return result;
}

212 213 214 215 216
/* Codec registry encoding check API. */

int PyCodec_KnownEncoding(const char *encoding)
{
    PyObject *codecs;
217

218 219
    codecs = _PyCodec_Lookup(encoding);
    if (!codecs) {
220 221
        PyErr_Clear();
        return 0;
222 223
    }
    else {
224 225
        Py_DECREF(codecs);
        return 1;
226 227 228
    }
}

229 230
static
PyObject *args_tuple(PyObject *object,
231
                     const char *errors)
232 233
{
    PyObject *args;
234

235 236
    args = PyTuple_New(1 + (errors != NULL));
    if (args == NULL)
237
        return NULL;
238 239 240
    Py_INCREF(object);
    PyTuple_SET_ITEM(args,0,object);
    if (errors) {
241 242 243 244 245 246 247 248
        PyObject *v;

        v = PyUnicode_FromString(errors);
        if (v == NULL) {
            Py_DECREF(args);
            return NULL;
        }
        PyTuple_SET_ITEM(args, 1, v);
249 250 251 252
    }
    return args;
}

253
/* Helper function to get a codec item */
254 255

static
256
PyObject *codec_getitem(const char *encoding, int index)
257 258 259 260 261 262
{
    PyObject *codecs;
    PyObject *v;

    codecs = _PyCodec_Lookup(encoding);
    if (codecs == NULL)
263
        return NULL;
264
    v = PyTuple_GET_ITEM(codecs, index);
265
    Py_DECREF(codecs);
266 267 268 269
    Py_INCREF(v);
    return v;
}

270
/* Helper functions to create an incremental codec. */
271
static
272 273 274
PyObject *codec_makeincrementalcodec(PyObject *codec_info,
                                     const char *errors,
                                     const char *attrname)
275
{
276
    PyObject *ret, *inccodec;
277

278
    inccodec = PyObject_GetAttrString(codec_info, attrname);
279
    if (inccodec == NULL)
280
        return NULL;
281
    if (errors)
282
        ret = PyObject_CallFunction(inccodec, "s", errors);
283
    else
284
        ret = _PyObject_CallNoArg(inccodec);
285 286
    Py_DECREF(inccodec);
    return ret;
287 288
}

289 290 291 292 293 294 295 296 297 298 299 300 301 302 303
static
PyObject *codec_getincrementalcodec(const char *encoding,
                                    const char *errors,
                                    const char *attrname)
{
    PyObject *codec_info, *ret;

    codec_info = _PyCodec_Lookup(encoding);
    if (codec_info == NULL)
        return NULL;
    ret = codec_makeincrementalcodec(codec_info, errors, attrname);
    Py_DECREF(codec_info);
    return ret;
}

304 305 306 307
/* Helper function to create a stream codec. */

static
PyObject *codec_getstreamcodec(const char *encoding,
308 309 310
                               PyObject *stream,
                               const char *errors,
                               const int index)
311
{
312
    PyObject *codecs, *streamcodec, *codeccls;
313 314 315

    codecs = _PyCodec_Lookup(encoding);
    if (codecs == NULL)
316
        return NULL;
317

318 319
    codeccls = PyTuple_GET_ITEM(codecs, index);
    if (errors != NULL)
320
        streamcodec = PyObject_CallFunction(codeccls, "Os", stream, errors);
321
    else
322
        streamcodec = PyObject_CallFunctionObjArgs(codeccls, stream, NULL);
323
    Py_DECREF(codecs);
324 325
    return streamcodec;
}
326

327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344
/* Helpers to work with the result of _PyCodec_Lookup

 */
PyObject *_PyCodecInfo_GetIncrementalDecoder(PyObject *codec_info,
                                             const char *errors)
{
    return codec_makeincrementalcodec(codec_info, errors,
                                      "incrementaldecoder");
}

PyObject *_PyCodecInfo_GetIncrementalEncoder(PyObject *codec_info,
                                             const char *errors)
{
    return codec_makeincrementalcodec(codec_info, errors,
                                      "incrementalencoder");
}


345 346
/* Convenience APIs to query the Codec registry.

347
   All APIs return a codec object with incremented refcount.
348

349 350 351 352 353
 */

PyObject *PyCodec_Encoder(const char *encoding)
{
    return codec_getitem(encoding, 0);
354 355
}

356
PyObject *PyCodec_Decoder(const char *encoding)
357
{
358 359
    return codec_getitem(encoding, 1);
}
360

361
PyObject *PyCodec_IncrementalEncoder(const char *encoding,
362
                                     const char *errors)
363 364 365
{
    return codec_getincrementalcodec(encoding, errors, "incrementalencoder");
}
366

367
PyObject *PyCodec_IncrementalDecoder(const char *encoding,
368
                                     const char *errors)
369 370
{
    return codec_getincrementalcodec(encoding, errors, "incrementaldecoder");
371 372
}

373
PyObject *PyCodec_StreamReader(const char *encoding,
374 375
                               PyObject *stream,
                               const char *errors)
376
{
377
    return codec_getstreamcodec(encoding, stream, errors, 2);
378 379 380
}

PyObject *PyCodec_StreamWriter(const char *encoding,
381 382
                               PyObject *stream,
                               const char *errors)
383
{
384
    return codec_getstreamcodec(encoding, stream, errors, 3);
385 386
}

387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402
/* Helper that tries to ensure the reported exception chain indicates the
 * codec that was invoked to trigger the failure without changing the type
 * of the exception raised.
 */
static void
wrap_codec_error(const char *operation,
                 const char *encoding)
{
    /* TrySetFromCause will replace the active exception with a suitably
     * updated clone if it can, otherwise it will leave the original
     * exception alone.
     */
    _PyErr_TrySetFromCause("%s with '%s' codec failed",
                           operation, encoding);
}

403
/* Encode an object (e.g. a Unicode object) using the given encoding
404 405 406 407
   and return the resulting encoded object (usually a Python string).

   errors is passed to the encoder factory as argument if non-NULL. */

408 409 410 411 412
static PyObject *
_PyCodec_EncodeInternal(PyObject *object,
                        PyObject *encoder,
                        const char *encoding,
                        const char *errors)
413
{
414
    PyObject *args = NULL, *result = NULL;
415
    PyObject *v = NULL;
416 417 418

    args = args_tuple(object, errors);
    if (args == NULL)
419
        goto onError;
420 421

    result = PyEval_CallObject(encoder, args);
422 423
    if (result == NULL) {
        wrap_codec_error("encoding", encoding);
424
        goto onError;
425
    }
426

427
    if (!PyTuple_Check(result) ||
428 429 430 431
        PyTuple_GET_SIZE(result) != 2) {
        PyErr_SetString(PyExc_TypeError,
                        "encoder must return a tuple (object, integer)");
        goto onError;
432
    }
433 434
    v = PyTuple_GET_ITEM(result,0);
    Py_INCREF(v);
435 436
    /* We don't check or use the second (integer) entry. */

437 438 439 440
    Py_DECREF(args);
    Py_DECREF(encoder);
    Py_DECREF(result);
    return v;
441

442
 onError:
443
    Py_XDECREF(result);
444 445
    Py_XDECREF(args);
    Py_XDECREF(encoder);
446
    return NULL;
447 448 449
}

/* Decode an object (usually a Python string) using the given encoding
450
   and return an equivalent object (e.g. a Unicode object).
451 452 453

   errors is passed to the decoder factory as argument if non-NULL. */

454 455 456 457 458
static PyObject *
_PyCodec_DecodeInternal(PyObject *object,
                        PyObject *decoder,
                        const char *encoding,
                        const char *errors)
459 460 461 462 463 464
{
    PyObject *args = NULL, *result = NULL;
    PyObject *v;

    args = args_tuple(object, errors);
    if (args == NULL)
465
        goto onError;
466

467
    result = PyEval_CallObject(decoder,args);
468 469
    if (result == NULL) {
        wrap_codec_error("decoding", encoding);
470
        goto onError;
471
    }
472
    if (!PyTuple_Check(result) ||
473 474 475 476
        PyTuple_GET_SIZE(result) != 2) {
        PyErr_SetString(PyExc_TypeError,
                        "decoder must return a tuple (object,integer)");
        goto onError;
477 478 479 480 481 482 483 484 485
    }
    v = PyTuple_GET_ITEM(result,0);
    Py_INCREF(v);
    /* We don't check or use the second (integer) entry. */

    Py_DECREF(args);
    Py_DECREF(decoder);
    Py_DECREF(result);
    return v;
486

487 488 489 490 491 492 493
 onError:
    Py_XDECREF(args);
    Py_XDECREF(decoder);
    Py_XDECREF(result);
    return NULL;
}

494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521
/* Generic encoding/decoding API */
PyObject *PyCodec_Encode(PyObject *object,
                         const char *encoding,
                         const char *errors)
{
    PyObject *encoder;

    encoder = PyCodec_Encoder(encoding);
    if (encoder == NULL)
        return NULL;

    return _PyCodec_EncodeInternal(object, encoder, encoding, errors);
}

PyObject *PyCodec_Decode(PyObject *object,
                         const char *encoding,
                         const char *errors)
{
    PyObject *decoder;

    decoder = PyCodec_Decoder(encoding);
    if (decoder == NULL)
        return NULL;

    return _PyCodec_DecodeInternal(object, decoder, encoding, errors);
}

/* Text encoding/decoding API */
522 523
PyObject * _PyCodec_LookupTextEncoding(const char *encoding,
                                       const char *alternate_command)
524 525 526 527 528 529 530 531 532 533 534 535 536 537 538
{
    _Py_IDENTIFIER(_is_text_encoding);
    PyObject *codec;
    PyObject *attr;
    int is_text_codec;

    codec = _PyCodec_Lookup(encoding);
    if (codec == NULL)
        return NULL;

    /* Backwards compatibility: assume any raw tuple describes a text
     * encoding, and the same for anything lacking the private
     * attribute.
     */
    if (!PyTuple_CheckExact(codec)) {
539 540 541 542 543
        if (_PyObject_LookupAttrId(codec, &PyId__is_text_encoding, &attr) < 0) {
            Py_DECREF(codec);
            return NULL;
        }
        if (attr != NULL) {
544 545
            is_text_codec = PyObject_IsTrue(attr);
            Py_DECREF(attr);
546
            if (is_text_codec <= 0) {
547
                Py_DECREF(codec);
548 549 550 551 552
                if (!is_text_codec)
                    PyErr_Format(PyExc_LookupError,
                                 "'%.400s' is not a text encoding; "
                                 "use %s to handle arbitrary codecs",
                                 encoding, alternate_command);
553 554 555 556 557
                return NULL;
            }
        }
    }

558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574
    /* This appears to be a valid text encoding */
    return codec;
}


static
PyObject *codec_getitem_checked(const char *encoding,
                                const char *alternate_command,
                                int index)
{
    PyObject *codec;
    PyObject *v;

    codec = _PyCodec_LookupTextEncoding(encoding, alternate_command);
    if (codec == NULL)
        return NULL;

575 576
    v = PyTuple_GET_ITEM(codec, index);
    Py_INCREF(v);
577
    Py_DECREF(codec);
578 579 580 581 582
    return v;
}

static PyObject * _PyCodec_TextEncoder(const char *encoding)
{
583
    return codec_getitem_checked(encoding, "codecs.encode()", 0);
584 585 586 587
}

static PyObject * _PyCodec_TextDecoder(const char *encoding)
{
588
    return codec_getitem_checked(encoding, "codecs.decode()", 1);
589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616
}

PyObject *_PyCodec_EncodeText(PyObject *object,
                              const char *encoding,
                              const char *errors)
{
    PyObject *encoder;

    encoder = _PyCodec_TextEncoder(encoding);
    if (encoder == NULL)
        return NULL;

    return _PyCodec_EncodeInternal(object, encoder, encoding, errors);
}

PyObject *_PyCodec_DecodeText(PyObject *object,
                              const char *encoding,
                              const char *errors)
{
    PyObject *decoder;

    decoder = _PyCodec_TextDecoder(encoding);
    if (decoder == NULL)
        return NULL;

    return _PyCodec_DecodeInternal(object, decoder, encoding, errors);
}

617 618 619 620 621 622 623 624
/* Register the error handling callback function error under the name
   name. This function will be called by the codec when it encounters
   an unencodable characters/undecodable bytes and doesn't know the
   callback name, when name is specified as the error parameter
   in the call to the encode/decode function.
   Return 0 on success, -1 on error */
int PyCodec_RegisterError(const char *name, PyObject *error)
{
625
    PyInterpreterState *interp = _PyInterpreterState_Get();
626
    if (interp->codec_search_path == NULL && _PyCodecRegistry_Init())
627
        return -1;
628
    if (!PyCallable_Check(error)) {
629 630
        PyErr_SetString(PyExc_TypeError, "handler must be callable");
        return -1;
631
    }
632
    return PyDict_SetItemString(interp->codec_error_registry,
633
                                name, error);
634 635 636 637 638 639 640 641 642
}

/* Lookup the error handling callback function registered under the
   name error. As a special case NULL can be passed, in which case
   the error handling callback for strict encoding will be returned. */
PyObject *PyCodec_LookupError(const char *name)
{
    PyObject *handler = NULL;

643
    PyInterpreterState *interp = _PyInterpreterState_GET_UNSAFE();
644
    if (interp->codec_search_path == NULL && _PyCodecRegistry_Init())
645
        return NULL;
646

647
    if (name==NULL)
648
        name = "strict";
649
    handler = PyDict_GetItemString(interp->codec_error_registry, name);
650
    if (!handler)
651
        PyErr_Format(PyExc_LookupError, "unknown error handler name '%.400s'", name);
652
    else
653
        Py_INCREF(handler);
654 655 656 657 658
    return handler;
}

static void wrong_exception_type(PyObject *exc)
{
659 660 661
    PyErr_Format(PyExc_TypeError,
                 "don't know how to handle %.200s in error callback",
                 exc->ob_type->tp_name);
662 663 664 665
}

PyObject *PyCodec_StrictErrors(PyObject *exc)
{
666 667
    if (PyExceptionInstance_Check(exc))
        PyErr_SetObject(PyExceptionInstance_Class(exc), exc);
668
    else
669
        PyErr_SetString(PyExc_TypeError, "codec must pass exception instance");
670 671 672 673 674 675
    return NULL;
}


PyObject *PyCodec_IgnoreErrors(PyObject *exc)
{
Martin v. Löwis's avatar
Martin v. Löwis committed
676
    Py_ssize_t end;
677 678

    if (PyObject_TypeCheck(exc, (PyTypeObject *)PyExc_UnicodeEncodeError)) {
679 680
        if (PyUnicodeEncodeError_GetEnd(exc, &end))
            return NULL;
681
    }
682
    else if (PyObject_TypeCheck(exc, (PyTypeObject *)PyExc_UnicodeDecodeError)) {
683 684
        if (PyUnicodeDecodeError_GetEnd(exc, &end))
            return NULL;
685
    }
686
    else if (PyObject_TypeCheck(exc, (PyTypeObject *)PyExc_UnicodeTranslateError)) {
687 688
        if (PyUnicodeTranslateError_GetEnd(exc, &end))
            return NULL;
689 690
    }
    else {
691 692
        wrong_exception_type(exc);
        return NULL;
693
    }
694
    return Py_BuildValue("(Nn)", PyUnicode_New(0, 0), end);
695 696 697 698 699
}


PyObject *PyCodec_ReplaceErrors(PyObject *exc)
{
Martin v. Löwis's avatar
Martin v. Löwis committed
700
    Py_ssize_t start, end, i, len;
701

702
    if (PyObject_TypeCheck(exc, (PyTypeObject *)PyExc_UnicodeEncodeError)) {
703
        PyObject *res;
Martin v. Löwis's avatar
Martin v. Löwis committed
704 705
        int kind;
        void *data;
706 707 708 709
        if (PyUnicodeEncodeError_GetStart(exc, &start))
            return NULL;
        if (PyUnicodeEncodeError_GetEnd(exc, &end))
            return NULL;
Martin v. Löwis's avatar
Martin v. Löwis committed
710 711
        len = end - start;
        res = PyUnicode_New(len, '?');
712 713
        if (res == NULL)
            return NULL;
Martin v. Löwis's avatar
Martin v. Löwis committed
714 715 716 717
        kind = PyUnicode_KIND(res);
        data = PyUnicode_DATA(res);
        for (i = 0; i < len; ++i)
            PyUnicode_WRITE(kind, data, i, '?');
718
        assert(_PyUnicode_CheckConsistency(res, 1));
Martin v. Löwis's avatar
Martin v. Löwis committed
719
        return Py_BuildValue("(Nn)", res, end);
720
    }
721
    else if (PyObject_TypeCheck(exc, (PyTypeObject *)PyExc_UnicodeDecodeError)) {
722 723
        if (PyUnicodeDecodeError_GetEnd(exc, &end))
            return NULL;
724 725 726
        return Py_BuildValue("(Cn)",
                             (int)Py_UNICODE_REPLACEMENT_CHARACTER,
                             end);
727
    }
728
    else if (PyObject_TypeCheck(exc, (PyTypeObject *)PyExc_UnicodeTranslateError)) {
729
        PyObject *res;
Martin v. Löwis's avatar
Martin v. Löwis committed
730 731
        int kind;
        void *data;
732 733 734 735
        if (PyUnicodeTranslateError_GetStart(exc, &start))
            return NULL;
        if (PyUnicodeTranslateError_GetEnd(exc, &end))
            return NULL;
Martin v. Löwis's avatar
Martin v. Löwis committed
736 737
        len = end - start;
        res = PyUnicode_New(len, Py_UNICODE_REPLACEMENT_CHARACTER);
738 739
        if (res == NULL)
            return NULL;
Martin v. Löwis's avatar
Martin v. Löwis committed
740 741 742 743
        kind = PyUnicode_KIND(res);
        data = PyUnicode_DATA(res);
        for (i=0; i < len; i++)
            PyUnicode_WRITE(kind, data, i, Py_UNICODE_REPLACEMENT_CHARACTER);
744
        assert(_PyUnicode_CheckConsistency(res, 1));
Martin v. Löwis's avatar
Martin v. Löwis committed
745
        return Py_BuildValue("(Nn)", res, end);
746 747
    }
    else {
748 749
        wrong_exception_type(exc);
        return NULL;
750 751 752 753 754
    }
}

PyObject *PyCodec_XMLCharRefReplaceErrors(PyObject *exc)
{
755
    if (PyObject_TypeCheck(exc, (PyTypeObject *)PyExc_UnicodeEncodeError)) {
756 757
        PyObject *restuple;
        PyObject *object;
758
        Py_ssize_t i;
759 760 761
        Py_ssize_t start;
        Py_ssize_t end;
        PyObject *res;
762
        unsigned char *outp;
763
        Py_ssize_t ressize;
764
        Py_UCS4 ch;
765 766 767 768 769 770
        if (PyUnicodeEncodeError_GetStart(exc, &start))
            return NULL;
        if (PyUnicodeEncodeError_GetEnd(exc, &end))
            return NULL;
        if (!(object = PyUnicodeEncodeError_GetObject(exc)))
            return NULL;
771 772
        if (end - start > PY_SSIZE_T_MAX / (2+7+1))
            end = start + PY_SSIZE_T_MAX / (2+7+1);
773 774 775 776
        for (i = start, ressize = 0; i < end; ++i) {
            /* object is guaranteed to be "ready" */
            ch = PyUnicode_READ_CHAR(object, i);
            if (ch<10)
777
                ressize += 2+1+1;
778
            else if (ch<100)
779
                ressize += 2+2+1;
780
            else if (ch<1000)
781
                ressize += 2+3+1;
782
            else if (ch<10000)
783
                ressize += 2+4+1;
784
            else if (ch<100000)
785
                ressize += 2+5+1;
786
            else if (ch<1000000)
787 788 789 790 791
                ressize += 2+6+1;
            else
                ressize += 2+7+1;
        }
        /* allocate replacement */
792
        res = PyUnicode_New(ressize, 127);
793 794 795 796
        if (res == NULL) {
            Py_DECREF(object);
            return NULL;
        }
797
        outp = PyUnicode_1BYTE_DATA(res);
798
        /* generate replacement */
799
        for (i = start; i < end; ++i) {
800 801
            int digits;
            int base;
802
            ch = PyUnicode_READ_CHAR(object, i);
803 804
            *outp++ = '&';
            *outp++ = '#';
805
            if (ch<10) {
806 807 808
                digits = 1;
                base = 1;
            }
809
            else if (ch<100) {
810 811 812
                digits = 2;
                base = 10;
            }
813
            else if (ch<1000) {
814 815 816
                digits = 3;
                base = 100;
            }
817
            else if (ch<10000) {
818 819 820
                digits = 4;
                base = 1000;
            }
821
            else if (ch<100000) {
822 823 824
                digits = 5;
                base = 10000;
            }
825
            else if (ch<1000000) {
826 827 828 829 830 831 832 833
                digits = 6;
                base = 100000;
            }
            else {
                digits = 7;
                base = 1000000;
            }
            while (digits-->0) {
834 835
                *outp++ = '0' + ch/base;
                ch %= base;
836 837 838 839
                base /= 10;
            }
            *outp++ = ';';
        }
840 841
        assert(_PyUnicode_CheckConsistency(res, 1));
        restuple = Py_BuildValue("(Nn)", res, end);
842 843
        Py_DECREF(object);
        return restuple;
844 845
    }
    else {
846 847
        wrong_exception_type(exc);
        return NULL;
848 849 850 851 852
    }
}

PyObject *PyCodec_BackslashReplaceErrors(PyObject *exc)
{
853 854 855 856 857 858 859 860 861
    PyObject *object;
    Py_ssize_t i;
    Py_ssize_t start;
    Py_ssize_t end;
    PyObject *res;
    unsigned char *outp;
    int ressize;
    Py_UCS4 c;

862
    if (PyObject_TypeCheck(exc, (PyTypeObject *)PyExc_UnicodeDecodeError)) {
863
        const unsigned char *p;
864
        if (PyUnicodeDecodeError_GetStart(exc, &start))
865
            return NULL;
866
        if (PyUnicodeDecodeError_GetEnd(exc, &end))
867
            return NULL;
868 869
        if (!(object = PyUnicodeDecodeError_GetObject(exc)))
            return NULL;
870
        p = (const unsigned char*)PyBytes_AS_STRING(object);
871
        res = PyUnicode_New(4 * (end - start), 127);
872 873
        if (res == NULL) {
            Py_DECREF(object);
874
            return NULL;
875
        }
876 877 878 879 880 881 882
        outp = PyUnicode_1BYTE_DATA(res);
        for (i = start; i < end; i++, outp += 4) {
            unsigned char c = p[i];
            outp[0] = '\\';
            outp[1] = 'x';
            outp[2] = Py_hexdigits[(c>>4)&0xf];
            outp[3] = Py_hexdigits[c&0xf];
883 884
        }

885
        assert(_PyUnicode_CheckConsistency(res, 1));
886
        Py_DECREF(object);
887 888
        return Py_BuildValue("(Nn)", res, end);
    }
889
    if (PyObject_TypeCheck(exc, (PyTypeObject *)PyExc_UnicodeEncodeError)) {
890 891 892 893 894 895 896
        if (PyUnicodeEncodeError_GetStart(exc, &start))
            return NULL;
        if (PyUnicodeEncodeError_GetEnd(exc, &end))
            return NULL;
        if (!(object = PyUnicodeEncodeError_GetObject(exc)))
            return NULL;
    }
897
    else if (PyObject_TypeCheck(exc, (PyTypeObject *)PyExc_UnicodeTranslateError)) {
898 899 900 901 902 903
        if (PyUnicodeTranslateError_GetStart(exc, &start))
            return NULL;
        if (PyUnicodeTranslateError_GetEnd(exc, &end))
            return NULL;
        if (!(object = PyUnicodeTranslateError_GetObject(exc)))
            return NULL;
904 905
    }
    else {
906 907
        wrong_exception_type(exc);
        return NULL;
908
    }
909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955

    if (end - start > PY_SSIZE_T_MAX / (1+1+8))
        end = start + PY_SSIZE_T_MAX / (1+1+8);
    for (i = start, ressize = 0; i < end; ++i) {
        /* object is guaranteed to be "ready" */
        c = PyUnicode_READ_CHAR(object, i);
        if (c >= 0x10000) {
            ressize += 1+1+8;
        }
        else if (c >= 0x100) {
            ressize += 1+1+4;
        }
        else
            ressize += 1+1+2;
    }
    res = PyUnicode_New(ressize, 127);
    if (res == NULL) {
        Py_DECREF(object);
        return NULL;
    }
    outp = PyUnicode_1BYTE_DATA(res);
    for (i = start; i < end; ++i) {
        c = PyUnicode_READ_CHAR(object, i);
        *outp++ = '\\';
        if (c >= 0x00010000) {
            *outp++ = 'U';
            *outp++ = Py_hexdigits[(c>>28)&0xf];
            *outp++ = Py_hexdigits[(c>>24)&0xf];
            *outp++ = Py_hexdigits[(c>>20)&0xf];
            *outp++ = Py_hexdigits[(c>>16)&0xf];
            *outp++ = Py_hexdigits[(c>>12)&0xf];
            *outp++ = Py_hexdigits[(c>>8)&0xf];
        }
        else if (c >= 0x100) {
            *outp++ = 'u';
            *outp++ = Py_hexdigits[(c>>12)&0xf];
            *outp++ = Py_hexdigits[(c>>8)&0xf];
        }
        else
            *outp++ = 'x';
        *outp++ = Py_hexdigits[(c>>4)&0xf];
        *outp++ = Py_hexdigits[c&0xf];
    }

    assert(_PyUnicode_CheckConsistency(res, 1));
    Py_DECREF(object);
    return Py_BuildValue("(Nn)", res, end);
956 957
}

958 959 960 961
static _PyUnicode_Name_CAPI *ucnhash_CAPI = NULL;

PyObject *PyCodec_NameReplaceErrors(PyObject *exc)
{
962
    if (PyObject_TypeCheck(exc, (PyTypeObject *)PyExc_UnicodeEncodeError)) {
963 964 965 966 967 968 969
        PyObject *restuple;
        PyObject *object;
        Py_ssize_t i;
        Py_ssize_t start;
        Py_ssize_t end;
        PyObject *res;
        unsigned char *outp;
970 971
        Py_ssize_t ressize;
        int replsize;
972 973 974 975 976 977 978 979
        Py_UCS4 c;
        char buffer[256]; /* NAME_MAXLEN */
        if (PyUnicodeEncodeError_GetStart(exc, &start))
            return NULL;
        if (PyUnicodeEncodeError_GetEnd(exc, &end))
            return NULL;
        if (!(object = PyUnicodeEncodeError_GetObject(exc)))
            return NULL;
980
        if (!ucnhash_CAPI) {
981 982 983
            /* load the unicode data module */
            ucnhash_CAPI = (_PyUnicode_Name_CAPI *)PyCapsule_Import(
                                            PyUnicodeData_CAPSULE_NAME, 1);
984 985
            if (!ucnhash_CAPI)
                return NULL;
986 987 988 989
        }
        for (i = start, ressize = 0; i < end; ++i) {
            /* object is guaranteed to be "ready" */
            c = PyUnicode_READ_CHAR(object, i);
990
            if (ucnhash_CAPI->getname(NULL, c, buffer, sizeof(buffer), 1)) {
991
                replsize = 1+1+1+(int)strlen(buffer)+1;
992 993
            }
            else if (c >= 0x10000) {
994
                replsize = 1+1+8;
995 996
            }
            else if (c >= 0x100) {
997
                replsize = 1+1+4;
998 999
            }
            else
1000 1001 1002 1003
                replsize = 1+1+2;
            if (ressize > PY_SSIZE_T_MAX - replsize)
                break;
            ressize += replsize;
1004
        }
1005
        end = i;
1006 1007 1008 1009 1010 1011 1012
        res = PyUnicode_New(ressize, 127);
        if (res==NULL)
            return NULL;
        for (i = start, outp = PyUnicode_1BYTE_DATA(res);
            i < end; ++i) {
            c = PyUnicode_READ_CHAR(object, i);
            *outp++ = '\\';
1013
            if (ucnhash_CAPI->getname(NULL, c, buffer, sizeof(buffer), 1)) {
1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040
                *outp++ = 'N';
                *outp++ = '{';
                strcpy((char *)outp, buffer);
                outp += strlen(buffer);
                *outp++ = '}';
                continue;
            }
            if (c >= 0x00010000) {
                *outp++ = 'U';
                *outp++ = Py_hexdigits[(c>>28)&0xf];
                *outp++ = Py_hexdigits[(c>>24)&0xf];
                *outp++ = Py_hexdigits[(c>>20)&0xf];
                *outp++ = Py_hexdigits[(c>>16)&0xf];
                *outp++ = Py_hexdigits[(c>>12)&0xf];
                *outp++ = Py_hexdigits[(c>>8)&0xf];
            }
            else if (c >= 0x100) {
                *outp++ = 'u';
                *outp++ = Py_hexdigits[(c>>12)&0xf];
                *outp++ = Py_hexdigits[(c>>8)&0xf];
            }
            else
                *outp++ = 'x';
            *outp++ = Py_hexdigits[(c>>4)&0xf];
            *outp++ = Py_hexdigits[c&0xf];
        }

Benjamin Peterson's avatar
Benjamin Peterson committed
1041
        assert(outp == PyUnicode_1BYTE_DATA(res) + ressize);
1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052
        assert(_PyUnicode_CheckConsistency(res, 1));
        restuple = Py_BuildValue("(Nn)", res, end);
        Py_DECREF(object);
        return restuple;
    }
    else {
        wrong_exception_type(exc);
        return NULL;
    }
}

1053
#define ENC_UNKNOWN     -1
1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068
#define ENC_UTF8        0
#define ENC_UTF16BE     1
#define ENC_UTF16LE     2
#define ENC_UTF32BE     3
#define ENC_UTF32LE     4

static int
get_standard_encoding(const char *encoding, int *bytelength)
{
    if (Py_TOLOWER(encoding[0]) == 'u' &&
        Py_TOLOWER(encoding[1]) == 't' &&
        Py_TOLOWER(encoding[2]) == 'f') {
        encoding += 3;
        if (*encoding == '-' || *encoding == '_' )
            encoding++;
1069 1070 1071 1072 1073
        if (encoding[0] == '8' && encoding[1] == '\0') {
            *bytelength = 3;
            return ENC_UTF8;
        }
        else if (encoding[0] == '1' && encoding[1] == '6') {
1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111
            encoding += 2;
            *bytelength = 2;
            if (*encoding == '\0') {
#ifdef WORDS_BIGENDIAN
                return ENC_UTF16BE;
#else
                return ENC_UTF16LE;
#endif
            }
            if (*encoding == '-' || *encoding == '_' )
                encoding++;
            if (Py_TOLOWER(encoding[1]) == 'e' && encoding[2] == '\0') {
                if (Py_TOLOWER(encoding[0]) == 'b')
                    return ENC_UTF16BE;
                if (Py_TOLOWER(encoding[0]) == 'l')
                    return ENC_UTF16LE;
            }
        }
        else if (encoding[0] == '3' && encoding[1] == '2') {
            encoding += 2;
            *bytelength = 4;
            if (*encoding == '\0') {
#ifdef WORDS_BIGENDIAN
                return ENC_UTF32BE;
#else
                return ENC_UTF32LE;
#endif
            }
            if (*encoding == '-' || *encoding == '_' )
                encoding++;
            if (Py_TOLOWER(encoding[1]) == 'e' && encoding[2] == '\0') {
                if (Py_TOLOWER(encoding[0]) == 'b')
                    return ENC_UTF32BE;
                if (Py_TOLOWER(encoding[0]) == 'l')
                    return ENC_UTF32LE;
            }
        }
    }
1112 1113 1114 1115
    else if (strcmp(encoding, "CP_UTF8") == 0) {
        *bytelength = 3;
        return ENC_UTF8;
    }
1116
    return ENC_UNKNOWN;
1117 1118
}

1119 1120 1121
/* This handler is declared static until someone demonstrates
   a need to call it directly. */
static PyObject *
1122
PyCodec_SurrogatePassErrors(PyObject *exc)
1123 1124 1125
{
    PyObject *restuple;
    PyObject *object;
1126
    PyObject *encode;
1127
    const char *encoding;
1128 1129
    int code;
    int bytelength;
1130
    Py_ssize_t i;
1131 1132 1133
    Py_ssize_t start;
    Py_ssize_t end;
    PyObject *res;
1134 1135

    if (PyObject_TypeCheck(exc, (PyTypeObject *)PyExc_UnicodeEncodeError)) {
1136
        unsigned char *outp;
1137 1138 1139 1140 1141 1142
        if (PyUnicodeEncodeError_GetStart(exc, &start))
            return NULL;
        if (PyUnicodeEncodeError_GetEnd(exc, &end))
            return NULL;
        if (!(object = PyUnicodeEncodeError_GetObject(exc)))
            return NULL;
1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153
        if (!(encode = PyUnicodeEncodeError_GetEncoding(exc))) {
            Py_DECREF(object);
            return NULL;
        }
        if (!(encoding = PyUnicode_AsUTF8(encode))) {
            Py_DECREF(object);
            Py_DECREF(encode);
            return NULL;
        }
        code = get_standard_encoding(encoding, &bytelength);
        Py_DECREF(encode);
1154 1155 1156 1157 1158 1159
        if (code == ENC_UNKNOWN) {
            /* Not supported, fail with original exception */
            PyErr_SetObject(PyExceptionInstance_Class(exc), exc);
            Py_DECREF(object);
            return NULL;
        }
1160

1161 1162
        if (end - start > PY_SSIZE_T_MAX / bytelength)
            end = start + PY_SSIZE_T_MAX / bytelength;
1163
        res = PyBytes_FromStringAndSize(NULL, bytelength*(end-start));
1164 1165 1166 1167
        if (!res) {
            Py_DECREF(object);
            return NULL;
        }
1168
        outp = (unsigned char*)PyBytes_AsString(res);
1169 1170 1171
        for (i = start; i < end; i++) {
            /* object is guaranteed to be "ready" */
            Py_UCS4 ch = PyUnicode_READ_CHAR(object, i);
1172
            if (!Py_UNICODE_IS_SURROGATE(ch)) {
1173 1174 1175 1176 1177 1178
                /* Not a surrogate, fail with original exception */
                PyErr_SetObject(PyExceptionInstance_Class(exc), exc);
                Py_DECREF(res);
                Py_DECREF(object);
                return NULL;
            }
1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205
            switch (code) {
            case ENC_UTF8:
                *outp++ = (unsigned char)(0xe0 | (ch >> 12));
                *outp++ = (unsigned char)(0x80 | ((ch >> 6) & 0x3f));
                *outp++ = (unsigned char)(0x80 | (ch & 0x3f));
                break;
            case ENC_UTF16LE:
                *outp++ = (unsigned char) ch;
                *outp++ = (unsigned char)(ch >> 8);
                break;
            case ENC_UTF16BE:
                *outp++ = (unsigned char)(ch >> 8);
                *outp++ = (unsigned char) ch;
                break;
            case ENC_UTF32LE:
                *outp++ = (unsigned char) ch;
                *outp++ = (unsigned char)(ch >> 8);
                *outp++ = (unsigned char)(ch >> 16);
                *outp++ = (unsigned char)(ch >> 24);
                break;
            case ENC_UTF32BE:
                *outp++ = (unsigned char)(ch >> 24);
                *outp++ = (unsigned char)(ch >> 16);
                *outp++ = (unsigned char)(ch >> 8);
                *outp++ = (unsigned char) ch;
                break;
            }
1206 1207 1208 1209 1210
        }
        restuple = Py_BuildValue("(On)", res, end);
        Py_DECREF(res);
        Py_DECREF(object);
        return restuple;
1211
    }
1212
    else if (PyObject_TypeCheck(exc, (PyTypeObject *)PyExc_UnicodeDecodeError)) {
1213
        const unsigned char *p;
1214
        Py_UCS4 ch = 0;
1215 1216
        if (PyUnicodeDecodeError_GetStart(exc, &start))
            return NULL;
1217 1218
        if (PyUnicodeDecodeError_GetEnd(exc, &end))
            return NULL;
1219 1220
        if (!(object = PyUnicodeDecodeError_GetObject(exc)))
            return NULL;
1221
        p = (const unsigned char*)PyBytes_AS_STRING(object);
1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232
        if (!(encode = PyUnicodeDecodeError_GetEncoding(exc))) {
            Py_DECREF(object);
            return NULL;
        }
        if (!(encoding = PyUnicode_AsUTF8(encode))) {
            Py_DECREF(object);
            Py_DECREF(encode);
            return NULL;
        }
        code = get_standard_encoding(encoding, &bytelength);
        Py_DECREF(encode);
1233 1234 1235 1236 1237 1238
        if (code == ENC_UNKNOWN) {
            /* Not supported, fail with original exception */
            PyErr_SetObject(PyExceptionInstance_Class(exc), exc);
            Py_DECREF(object);
            return NULL;
        }
1239

1240 1241 1242
        /* Try decoding a single surrogate character. If
           there are more, let the codec call us again. */
        p += start;
1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265
        if (PyBytes_GET_SIZE(object) - start >= bytelength) {
            switch (code) {
            case ENC_UTF8:
                if ((p[0] & 0xf0) == 0xe0 &&
                    (p[1] & 0xc0) == 0x80 &&
                    (p[2] & 0xc0) == 0x80) {
                    /* it's a three-byte code */
                    ch = ((p[0] & 0x0f) << 12) + ((p[1] & 0x3f) << 6) + (p[2] & 0x3f);
                }
                break;
            case ENC_UTF16LE:
                ch = p[1] << 8 | p[0];
                break;
            case ENC_UTF16BE:
                ch = p[0] << 8 | p[1];
                break;
            case ENC_UTF32LE:
                ch = (p[3] << 24) | (p[2] << 16) | (p[1] << 8) | p[0];
                break;
            case ENC_UTF32BE:
                ch = (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3];
                break;
            }
1266
        }
1267

1268
        Py_DECREF(object);
1269 1270
        if (!Py_UNICODE_IS_SURROGATE(ch)) {
            /* it's not a surrogate - fail */
1271 1272 1273
            PyErr_SetObject(PyExceptionInstance_Class(exc), exc);
            return NULL;
        }
1274 1275 1276
        res = PyUnicode_FromOrdinal(ch);
        if (res == NULL)
            return NULL;
1277
        return Py_BuildValue("(Nn)", res, start + bytelength);
1278 1279
    }
    else {
1280 1281
        wrong_exception_type(exc);
        return NULL;
1282 1283 1284
    }
}

1285
static PyObject *
1286
PyCodec_SurrogateEscapeErrors(PyObject *exc)
1287 1288 1289
{
    PyObject *restuple;
    PyObject *object;
1290
    Py_ssize_t i;
1291 1292 1293
    Py_ssize_t start;
    Py_ssize_t end;
    PyObject *res;
1294 1295

    if (PyObject_TypeCheck(exc, (PyTypeObject *)PyExc_UnicodeEncodeError)) {
1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308
        char *outp;
        if (PyUnicodeEncodeError_GetStart(exc, &start))
            return NULL;
        if (PyUnicodeEncodeError_GetEnd(exc, &end))
            return NULL;
        if (!(object = PyUnicodeEncodeError_GetObject(exc)))
            return NULL;
        res = PyBytes_FromStringAndSize(NULL, end-start);
        if (!res) {
            Py_DECREF(object);
            return NULL;
        }
        outp = PyBytes_AsString(res);
1309 1310 1311
        for (i = start; i < end; i++) {
            /* object is guaranteed to be "ready" */
            Py_UCS4 ch = PyUnicode_READ_CHAR(object, i);
1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324
            if (ch < 0xdc80 || ch > 0xdcff) {
                /* Not a UTF-8b surrogate, fail with original exception */
                PyErr_SetObject(PyExceptionInstance_Class(exc), exc);
                Py_DECREF(res);
                Py_DECREF(object);
                return NULL;
            }
            *outp++ = ch - 0xdc00;
        }
        restuple = Py_BuildValue("(On)", res, end);
        Py_DECREF(res);
        Py_DECREF(object);
        return restuple;
1325
    }
1326
    else if (PyObject_TypeCheck(exc, (PyTypeObject *)PyExc_UnicodeDecodeError)) {
1327
        PyObject *str;
1328
        const unsigned char *p;
1329
        Py_UCS2 ch[4]; /* decode up to 4 bad bytes. */
1330 1331 1332 1333 1334 1335 1336
        int consumed = 0;
        if (PyUnicodeDecodeError_GetStart(exc, &start))
            return NULL;
        if (PyUnicodeDecodeError_GetEnd(exc, &end))
            return NULL;
        if (!(object = PyUnicodeDecodeError_GetObject(exc)))
            return NULL;
1337
        p = (const unsigned char*)PyBytes_AS_STRING(object);
1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350
        while (consumed < 4 && consumed < end-start) {
            /* Refuse to escape ASCII bytes. */
            if (p[start+consumed] < 128)
                break;
            ch[consumed] = 0xdc00 + p[start+consumed];
            consumed++;
        }
        Py_DECREF(object);
        if (!consumed) {
            /* codec complained about ASCII byte. */
            PyErr_SetObject(PyExceptionInstance_Class(exc), exc);
            return NULL;
        }
1351 1352 1353 1354
        str = PyUnicode_FromKindAndData(PyUnicode_2BYTE_KIND, ch, consumed);
        if (str == NULL)
            return NULL;
        return Py_BuildValue("(Nn)", str, start+consumed);
1355 1356
    }
    else {
1357 1358
        wrong_exception_type(exc);
        return NULL;
1359 1360 1361
    }
}

1362

1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391
static PyObject *strict_errors(PyObject *self, PyObject *exc)
{
    return PyCodec_StrictErrors(exc);
}


static PyObject *ignore_errors(PyObject *self, PyObject *exc)
{
    return PyCodec_IgnoreErrors(exc);
}


static PyObject *replace_errors(PyObject *self, PyObject *exc)
{
    return PyCodec_ReplaceErrors(exc);
}


static PyObject *xmlcharrefreplace_errors(PyObject *self, PyObject *exc)
{
    return PyCodec_XMLCharRefReplaceErrors(exc);
}


static PyObject *backslashreplace_errors(PyObject *self, PyObject *exc)
{
    return PyCodec_BackslashReplaceErrors(exc);
}

1392 1393 1394 1395 1396
static PyObject *namereplace_errors(PyObject *self, PyObject *exc)
{
    return PyCodec_NameReplaceErrors(exc);
}

1397
static PyObject *surrogatepass_errors(PyObject *self, PyObject *exc)
1398
{
1399
    return PyCodec_SurrogatePassErrors(exc);
1400 1401
}

1402
static PyObject *surrogateescape_errors(PyObject *self, PyObject *exc)
1403
{
1404
    return PyCodec_SurrogateEscapeErrors(exc);
1405 1406
}

1407
static int _PyCodecRegistry_Init(void)
1408
{
1409
    static struct {
1410 1411
        char *name;
        PyMethodDef def;
1412 1413
    } methods[] =
    {
1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461
        {
            "strict",
            {
                "strict_errors",
                strict_errors,
                METH_O,
                PyDoc_STR("Implements the 'strict' error handling, which "
                          "raises a UnicodeError on coding errors.")
            }
        },
        {
            "ignore",
            {
                "ignore_errors",
                ignore_errors,
                METH_O,
                PyDoc_STR("Implements the 'ignore' error handling, which "
                          "ignores malformed data and continues.")
            }
        },
        {
            "replace",
            {
                "replace_errors",
                replace_errors,
                METH_O,
                PyDoc_STR("Implements the 'replace' error handling, which "
                          "replaces malformed data with a replacement marker.")
            }
        },
        {
            "xmlcharrefreplace",
            {
                "xmlcharrefreplace_errors",
                xmlcharrefreplace_errors,
                METH_O,
                PyDoc_STR("Implements the 'xmlcharrefreplace' error handling, "
                          "which replaces an unencodable character with the "
                          "appropriate XML character reference.")
            }
        },
        {
            "backslashreplace",
            {
                "backslashreplace_errors",
                backslashreplace_errors,
                METH_O,
                PyDoc_STR("Implements the 'backslashreplace' error handling, "
1462 1463
                          "which replaces malformed data with a backslashed "
                          "escape sequence.")
1464 1465
            }
        },
1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476
        {
            "namereplace",
            {
                "namereplace_errors",
                namereplace_errors,
                METH_O,
                PyDoc_STR("Implements the 'namereplace' error handling, "
                          "which replaces an unencodable character with a "
                          "\\N{...} escape sequence.")
            }
        },
1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492
        {
            "surrogatepass",
            {
                "surrogatepass",
                surrogatepass_errors,
                METH_O
            }
        },
        {
            "surrogateescape",
            {
                "surrogateescape",
                surrogateescape_errors,
                METH_O
            }
        }
1493
    };
1494

1495
    PyInterpreterState *interp = _PyInterpreterState_Get();
1496
    PyObject *mod;
1497
    unsigned i;
1498 1499

    if (interp->codec_search_path != NULL)
1500
        return 0;
1501 1502 1503 1504 1505 1506

    interp->codec_search_path = PyList_New(0);
    interp->codec_search_cache = PyDict_New();
    interp->codec_error_registry = PyDict_New();

    if (interp->codec_error_registry) {
1507
        for (i = 0; i < Py_ARRAY_LENGTH(methods); ++i) {
1508
            PyObject *func = PyCFunction_NewEx(&methods[i].def, NULL, NULL);
1509 1510 1511 1512 1513 1514 1515 1516
            int res;
            if (!func)
                Py_FatalError("can't initialize codec error registry");
            res = PyCodec_RegisterError(methods[i].name, func);
            Py_DECREF(func);
            if (res)
                Py_FatalError("can't initialize codec error registry");
        }
1517
    }
1518 1519

    if (interp->codec_search_path == NULL ||
1520 1521 1522
        interp->codec_search_cache == NULL ||
        interp->codec_error_registry == NULL)
        Py_FatalError("can't initialize codec registry");
1523

1524
    mod = PyImport_ImportModuleNoBlock("encodings");
1525
    if (mod == NULL) {
1526
        return -1;
1527 1528
    }
    Py_DECREF(mod);
1529
    interp->codecs_initialized = 1;
1530
    return 0;
1531
}