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

   Python Codec Registry and support functions

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

Copyright (c) Corporation for National Research Initiatives.

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

#include "Python.h"
#include "pycore_call.h"          // _PyObject_CallNoArgs()
#include "pycore_codecs.h"        // export _PyCodec_LookupTextEncoding()
#include "pycore_interp.h"        // PyInterpreterState.codec_search_path
#include "pycore_pyerrors.h"      // _PyErr_FormatNote()
#include "pycore_pystate.h"       // _PyInterpreterState_GET()
#include "pycore_runtime.h"       // _Py_ID()
#include "pycore_ucnhash.h"       // _PyUnicode_Name_CAPI
#include "pycore_unicodeobject.h" // _PyUnicode_InternMortal()
#include "pycore_pyatomic_ft_wrappers.h"

static const char *codecs_builtin_error_handlers[] = {
    "strict", "ignore", "replace",
    "xmlcharrefreplace", "backslashreplace", "namereplace",
    "surrogatepass", "surrogateescape",
};

const char *Py_hexdigits = "0123456789abcdef";

/* --- Codec Registry ----------------------------------------------------- */

int PyCodec_Register(PyObject *search_function)
{
    PyInterpreterState *interp = _PyInterpreterState_GET();
    assert(interp->codecs.initialized);
    if (search_function == NULL) {
        PyErr_BadArgument();
        goto onError;
    }
    if (!PyCallable_Check(search_function)) {
        PyErr_SetString(PyExc_TypeError, "argument must be callable");
        goto onError;
    }
    FT_MUTEX_LOCK(&interp->codecs.search_path_mutex);
    int ret = PyList_Append(interp->codecs.search_path, search_function);
    FT_MUTEX_UNLOCK(&interp->codecs.search_path_mutex);

    return ret;

 onError:
    return -1;
}

int
PyCodec_Unregister(PyObject *search_function)
{
    PyInterpreterState *interp = _PyInterpreterState_GET();
    if (interp->codecs.initialized != 1) {
        /* Do nothing if codecs state was cleared (only possible during
           interpreter shutdown). */
        return 0;
    }

    PyObject *codec_search_path = interp->codecs.search_path;
    assert(PyList_CheckExact(codec_search_path));
    for (Py_ssize_t i = 0; i < PyList_GET_SIZE(codec_search_path); i++) {
        FT_MUTEX_LOCK(&interp->codecs.search_path_mutex);
        PyObject *item = PyList_GetItemRef(codec_search_path, i);
        int ret = 1;
        if (item == search_function) {
            // We hold a reference to the item, so its destructor can't run
            // while we hold search_path_mutex.
            ret = PyList_SetSlice(codec_search_path, i, i+1, NULL);
        }
        FT_MUTEX_UNLOCK(&interp->codecs.search_path_mutex);
        Py_DECREF(item);
        if (ret != 1) {
            assert(interp->codecs.search_cache != NULL);
            assert(PyDict_CheckExact(interp->codecs.search_cache));
            PyDict_Clear(interp->codecs.search_cache);
            return ret;
        }
    }
    return 0;
}

/* Convert a string to a normalized Python string: all ASCII letters are
   converted to lower case, spaces are replaced with hyphens. */

static PyObject*
normalizestring(const char *string)
{
    size_t i;
    size_t len = strlen(string);
    char *p;
    PyObject *v;

    if (len > PY_SSIZE_T_MAX) {
        PyErr_SetString(PyExc_OverflowError, "string is too large");
        return NULL;
    }

    p = PyMem_Malloc(len + 1);
    if (p == NULL)
        return PyErr_NoMemory();
    for (i = 0; i < len; i++) {
        char ch = string[i];
        if (ch == ' ')
            ch = '-';
        else
            ch = Py_TOLOWER(Py_CHARMASK(ch));
        p[i] = ch;
    }
    p[i] = '\0';
    v = PyUnicode_FromString(p);
    PyMem_Free(p);
    return v;
}

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

   ASCII letters in the encoding string is looked up converted to all
   lower case. This makes encodings looked up through this mechanism
   effectively case-insensitive. Spaces are replaced with hyphens for
   names like "US ASCII" and "ISO 8859-1".

   If no codec is found, a LookupError is set and NULL returned.

   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.

*/

PyObject *_PyCodec_Lookup(const char *encoding)
{
    if (encoding == NULL) {
        PyErr_BadArgument();
        return NULL;
    }

    PyInterpreterState *interp = _PyInterpreterState_GET();
    assert(interp->codecs.initialized);

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

    /* Intern the string. We'll make it immortal later if lookup succeeds. */
    _PyUnicode_InternMortal(interp, &v);

    /* First, try to lookup the name in the registry dictionary */
    PyObject *result;
    if (PyDict_GetItemRef(interp->codecs.search_cache, v, &result) < 0) {
        goto onError;
    }
    if (result != NULL) {
        Py_DECREF(v);
        return result;
    }

    /* Next, scan the search functions in order of registration */
    const Py_ssize_t len = PyList_Size(interp->codecs.search_path);
    if (len < 0)
        goto onError;
    if (len == 0) {
        PyErr_SetString(PyExc_LookupError,
                        "no codec search functions registered: "
                        "can't find encoding");
        goto onError;
    }

    Py_ssize_t i;
    for (i = 0; i < len; i++) {
        PyObject *func;

        func = PyList_GetItemRef(interp->codecs.search_path, i);
        if (func == NULL)
            goto onError;
        result = PyObject_CallOneArg(func, v);
        Py_DECREF(func);
        if (result == NULL)
            goto onError;
        if (result == Py_None) {
            Py_CLEAR(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;
    }
    if (result == NULL) {
        /* XXX Perhaps we should cache misses too ? */
        PyErr_Format(PyExc_LookupError,
                     "unknown encoding: %s", encoding);
        goto onError;
    }

    _PyUnicode_InternImmortal(interp, &v);

    /* Cache and return the result */
    if (PyDict_SetItem(interp->codecs.search_cache, v, result) < 0) {
        Py_DECREF(result);
        goto onError;
    }
    Py_DECREF(v);
    return result;

 onError:
    Py_DECREF(v);
    return NULL;
}

/* Codec registry encoding check API. */

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

    codecs = _PyCodec_Lookup(encoding);
    if (!codecs) {
        PyErr_Clear();
        return 0;
    }
    else {
        Py_DECREF(codecs);
        return 1;
    }
}

static
PyObject *args_tuple(PyObject *object,
                     const char *errors)
{
    PyObject *args;

    args = PyTuple_New(1 + (errors != NULL));
    if (args == NULL)
        return NULL;
    PyTuple_SET_ITEM(args, 0, Py_NewRef(object));
    if (errors) {
        PyObject *v;

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

/* Helper function to get a codec item */

static
PyObject *codec_getitem(const char *encoding, int index)
{
    PyObject *codecs;
    PyObject *v;

    codecs = _PyCodec_Lookup(encoding);
    if (codecs == NULL)
        return NULL;
    v = PyTuple_GET_ITEM(codecs, index);
    Py_DECREF(codecs);
    return Py_NewRef(v);
}

/* Helper functions to create an incremental codec. */
static
PyObject *codec_makeincrementalcodec(PyObject *codec_info,
                                     const char *errors,
                                     const char *attrname)
{
    PyObject *ret, *inccodec;

    inccodec = PyObject_GetAttrString(codec_info, attrname);
    if (inccodec == NULL)
        return NULL;
    if (errors)
        ret = PyObject_CallFunction(inccodec, "s", errors);
    else
        ret = _PyObject_CallNoArgs(inccodec);
    Py_DECREF(inccodec);
    return ret;
}

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;
}

/* Helper function to create a stream codec. */

static
PyObject *codec_getstreamcodec(const char *encoding,
                               PyObject *stream,
                               const char *errors,
                               const int index)
{
    PyObject *codecs, *streamcodec, *codeccls;

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

    codeccls = PyTuple_GET_ITEM(codecs, index);
    if (errors != NULL)
        streamcodec = PyObject_CallFunction(codeccls, "Os", stream, errors);
    else
        streamcodec = PyObject_CallOneArg(codeccls, stream);
    Py_DECREF(codecs);
    return streamcodec;
}

/* 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");
}


/* Convenience APIs to query the Codec registry.

   All APIs return a codec object with incremented refcount.

 */

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

PyObject *PyCodec_Decoder(const char *encoding)
{
    return codec_getitem(encoding, 1);
}

PyObject *PyCodec_IncrementalEncoder(const char *encoding,
                                     const char *errors)
{
    return codec_getincrementalcodec(encoding, errors, "incrementalencoder");
}

PyObject *PyCodec_IncrementalDecoder(const char *encoding,
                                     const char *errors)
{
    return codec_getincrementalcodec(encoding, errors, "incrementaldecoder");
}

PyObject *PyCodec_StreamReader(const char *encoding,
                               PyObject *stream,
                               const char *errors)
{
    return codec_getstreamcodec(encoding, stream, errors, 2);
}

PyObject *PyCodec_StreamWriter(const char *encoding,
                               PyObject *stream,
                               const char *errors)
{
    return codec_getstreamcodec(encoding, stream, errors, 3);
}

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

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

static PyObject *
_PyCodec_EncodeInternal(PyObject *object,
                        PyObject *encoder,
                        const char *encoding,
                        const char *errors)
{
    PyObject *args = NULL, *result = NULL;
    PyObject *v = NULL;

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

    result = PyObject_Call(encoder, args, NULL);
    if (result == NULL) {
        _PyErr_FormatNote("%s with '%s' codec failed", "encoding", encoding);
        goto onError;
    }

    if (!PyTuple_Check(result) ||
        PyTuple_GET_SIZE(result) != 2) {
        PyErr_SetString(PyExc_TypeError,
                        "encoder must return a tuple (object, integer)");
        goto onError;
    }
    v = Py_NewRef(PyTuple_GET_ITEM(result,0));
    /* We don't check or use the second (integer) entry. */

    Py_DECREF(args);
    Py_DECREF(encoder);
    Py_DECREF(result);
    return v;

 onError:
    Py_XDECREF(result);
    Py_XDECREF(args);
    Py_XDECREF(encoder);
    return NULL;
}

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

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

static PyObject *
_PyCodec_DecodeInternal(PyObject *object,
                        PyObject *decoder,
                        const char *encoding,
                        const char *errors)
{
    PyObject *args = NULL, *result = NULL;
    PyObject *v;

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

    result = PyObject_Call(decoder, args, NULL);
    if (result == NULL) {
        _PyErr_FormatNote("%s with '%s' codec failed", "decoding", encoding);
        goto onError;
    }
    if (!PyTuple_Check(result) ||
        PyTuple_GET_SIZE(result) != 2) {
        PyErr_SetString(PyExc_TypeError,
                        "decoder must return a tuple (object,integer)");
        goto onError;
    }
    v = Py_NewRef(PyTuple_GET_ITEM(result,0));
    /* We don't check or use the second (integer) entry. */

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

 onError:
    Py_XDECREF(args);
    Py_XDECREF(decoder);
    Py_XDECREF(result);
    return NULL;
}

/* 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 */
PyObject * _PyCodec_LookupTextEncoding(const char *encoding,
                                       const char *alternate_command)
{
    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)) {
        if (PyObject_GetOptionalAttr(codec, &_Py_ID(_is_text_encoding), &attr) < 0) {
            Py_DECREF(codec);
            return NULL;
        }
        if (attr != NULL) {
            is_text_codec = PyObject_IsTrue(attr);
            Py_DECREF(attr);
            if (is_text_codec <= 0) {
                Py_DECREF(codec);
                if (!is_text_codec) {
                    if (alternate_command != NULL) {
                        PyErr_Format(PyExc_LookupError,
                                     "'%.400s' is not a text encoding; "
                                     "use %s to handle arbitrary codecs",
                                     encoding, alternate_command);
                    }
                    else {
                        PyErr_Format(PyExc_LookupError,
                                     "'%.400s' is not a text encoding",
                                     encoding);
                    }
                }
                return NULL;
            }
        }
    }

    /* 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;

    v = Py_NewRef(PyTuple_GET_ITEM(codec, index));
    Py_DECREF(codec);
    return v;
}

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

static PyObject * _PyCodec_TextDecoder(const char *encoding)
{
    return codec_getitem_checked(encoding, "codecs.decode()", 1);
}

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);
}

/* 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)
{
    PyInterpreterState *interp = _PyInterpreterState_GET();
    assert(interp->codecs.initialized);
    if (!PyCallable_Check(error)) {
        PyErr_SetString(PyExc_TypeError, "handler must be callable");
        return -1;
    }
    return PyDict_SetItemString(interp->codecs.error_registry,
                                name, error);
}

int _PyCodec_UnregisterError(const char *name)
{
    for (size_t i = 0; i < Py_ARRAY_LENGTH(codecs_builtin_error_handlers); ++i) {
        if (strcmp(name, codecs_builtin_error_handlers[i]) == 0) {
            PyErr_Format(PyExc_ValueError,
                         "cannot un-register built-in error handler '%s'", name);
            return -1;
        }
    }
    PyInterpreterState *interp = _PyInterpreterState_GET();
    assert(interp->codecs.initialized);
    return PyDict_PopString(interp->codecs.error_registry, name, NULL);
}

/* 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)
{
    PyInterpreterState *interp = _PyInterpreterState_GET();
    assert(interp->codecs.initialized);

    if (name==NULL)
        name = "strict";
    PyObject *handler;
    if (PyDict_GetItemStringRef(interp->codecs.error_registry, name, &handler) < 0) {
        return NULL;
    }
    if (handler == NULL) {
        PyErr_Format(PyExc_LookupError, "unknown error handler name '%.400s'", name);
        return NULL;
    }
    return handler;
}


static inline void
wrong_exception_type(PyObject *exc)
{
    PyErr_Format(PyExc_TypeError,
                 "don't know how to handle %T in error callback", exc);
}


#define _PyIsUnicodeEncodeError(EXC)    \
    PyObject_TypeCheck(EXC, (PyTypeObject *)PyExc_UnicodeEncodeError)
#define _PyIsUnicodeDecodeError(EXC)    \
    PyObject_TypeCheck(EXC, (PyTypeObject *)PyExc_UnicodeDecodeError)
#define _PyIsUnicodeTranslateError(EXC) \
    PyObject_TypeCheck(EXC, (PyTypeObject *)PyExc_UnicodeTranslateError)


// --- codecs handlers: utilities ---------------------------------------------

/*
 * Return the number of characters (including special prefixes)
 * needed to represent 'ch' by codec_handler_write_unicode_hex().
 */
static inline Py_ssize_t
codec_handler_unicode_hex_width(Py_UCS4 ch)
{
    if (ch >= 0x10000) {
        // format: '\\' + 'U' + 8 hex digits
        return 1 + 1 + 8;
    }
    else if (ch >= 0x100) {
        // format: '\\' + 'u' + 4 hex digits
        return 1 + 1 + 4;
    }
    else {
        // format: '\\' + 'x' + 2 hex digits
        return 1 + 1 + 2;
    }
}


/*
 * Write the hexadecimal representation of 'ch' to the buffer pointed by 'p'
 * using 2, 4, or 8 characters prefixed by '\x', '\u', or '\U' respectively.
 */
static inline void
codec_handler_write_unicode_hex(Py_UCS1 **p, Py_UCS4 ch)
{
    *(*p)++ = '\\';
    if (ch >= 0x10000) {
        *(*p)++ = 'U';
        *(*p)++ = Py_hexdigits[(ch >> 28) & 0xf];
        *(*p)++ = Py_hexdigits[(ch >> 24) & 0xf];
        *(*p)++ = Py_hexdigits[(ch >> 20) & 0xf];
        *(*p)++ = Py_hexdigits[(ch >> 16) & 0xf];
        *(*p)++ = Py_hexdigits[(ch >> 12) & 0xf];
        *(*p)++ = Py_hexdigits[(ch >> 8) & 0xf];
    }
    else if (ch >= 0x100) {
        *(*p)++ = 'u';
        *(*p)++ = Py_hexdigits[(ch >> 12) & 0xf];
        *(*p)++ = Py_hexdigits[(ch >> 8) & 0xf];
    }
    else {
        *(*p)++ = 'x';
    }
    *(*p)++ = Py_hexdigits[(ch >> 4) & 0xf];
    *(*p)++ = Py_hexdigits[ch & 0xf];
}


/*
 * Determine the number of digits for a decimal representation of Unicode
 * codepoint 'ch' (by design, Unicode codepoints are limited to 7 digits).
 */
static inline int
n_decimal_digits_for_codepoint(Py_UCS4 ch)
{
    if (ch < 10) return 1;
    if (ch < 100) return 2;
    if (ch < 1000) return 3;
    if (ch < 10000) return 4;
    if (ch < 100000) return 5;
    if (ch < 1000000) return 6;
    if (ch < 10000000) return 7;
    // Unicode codepoints are limited to 1114111 (7 decimal digits)
    Py_UNREACHABLE();
}


/*
 * Create a Unicode string containing 'count' copies of the official
 * Unicode REPLACEMENT CHARACTER (0xFFFD).
 */
static PyObject *
codec_handler_unicode_replacement_character(Py_ssize_t count)
{
    PyObject *res = PyUnicode_New(count, Py_UNICODE_REPLACEMENT_CHARACTER);
    if (res == NULL) {
        return NULL;
    }
    assert(count == 0 || PyUnicode_KIND(res) == PyUnicode_2BYTE_KIND);
    Py_UCS2 *outp = PyUnicode_2BYTE_DATA(res);
    for (Py_ssize_t i = 0; i < count; ++i) {
        outp[i] = Py_UNICODE_REPLACEMENT_CHARACTER;
    }
    assert(_PyUnicode_CheckConsistency(res, 1));
    return res;
}


// --- handler: 'strict' ------------------------------------------------------

PyObject *PyCodec_StrictErrors(PyObject *exc)
{
    if (PyExceptionInstance_Check(exc)) {
        PyErr_SetObject(PyExceptionInstance_Class(exc), exc);
    }
    else {
        PyErr_SetString(PyExc_TypeError, "codec must pass exception instance");
    }
    return NULL;
}


// --- handler: 'ignore' ------------------------------------------------------

static PyObject *
_PyCodec_IgnoreError(PyObject *exc, int as_bytes)
{
    Py_ssize_t end;
    if (_PyUnicodeError_GetParams(exc, NULL, NULL, NULL,
                                  &end, NULL, as_bytes) < 0)
    {
        return NULL;
    }
    return Py_BuildValue("(Nn)", Py_GetConstant(Py_CONSTANT_EMPTY_STR), end);
}


PyObject *PyCodec_IgnoreErrors(PyObject *exc)
{
    if (_PyIsUnicodeEncodeError(exc) || _PyIsUnicodeTranslateError(exc)) {
        return _PyCodec_IgnoreError(exc, false);
    }
    else if (_PyIsUnicodeDecodeError(exc)) {
        return _PyCodec_IgnoreError(exc, true);
    }
    else {
        wrong_exception_type(exc);
        return NULL;
    }
}


// --- handler: 'replace' -----------------------------------------------------

static PyObject *
_PyCodec_ReplaceUnicodeEncodeError(PyObject *exc)
{
    Py_ssize_t start, end, slen;
    if (_PyUnicodeError_GetParams(exc, NULL, NULL,
                                  &start, &end, &slen, false) < 0)
    {
        return NULL;
    }
    PyObject *res = PyUnicode_New(slen, '?');
    if (res == NULL) {
        return NULL;
    }
    assert(PyUnicode_KIND(res) == PyUnicode_1BYTE_KIND);
    Py_UCS1 *outp = PyUnicode_1BYTE_DATA(res);
    memset(outp, '?', sizeof(Py_UCS1) * slen);
    assert(_PyUnicode_CheckConsistency(res, 1));
    return Py_BuildValue("(Nn)", res, end);
}


static PyObject *
_PyCodec_ReplaceUnicodeDecodeError(PyObject *exc)
{
    Py_ssize_t end;
    if (PyUnicodeDecodeError_GetEnd(exc, &end) < 0) {
        return NULL;
    }
    PyObject *res = codec_handler_unicode_replacement_character(1);
    if (res == NULL) {
        return NULL;
    }
    return Py_BuildValue("(Nn)", res, end);
}


static PyObject *
_PyCodec_ReplaceUnicodeTranslateError(PyObject *exc)
{
    Py_ssize_t start, end, slen;
    if (_PyUnicodeError_GetParams(exc, NULL, NULL,
                                  &start, &end, &slen, false) < 0)
    {
        return NULL;
    }
    PyObject *res = codec_handler_unicode_replacement_character(slen);
    if (res == NULL) {
        return NULL;
    }
    return Py_BuildValue("(Nn)", res, end);
}


PyObject *PyCodec_ReplaceErrors(PyObject *exc)
{
    if (_PyIsUnicodeEncodeError(exc)) {
        return _PyCodec_ReplaceUnicodeEncodeError(exc);
    }
    else if (_PyIsUnicodeDecodeError(exc)) {
        return _PyCodec_ReplaceUnicodeDecodeError(exc);
    }
    else if (_PyIsUnicodeTranslateError(exc)) {
        return _PyCodec_ReplaceUnicodeTranslateError(exc);
    }
    else {
        wrong_exception_type(exc);
        return NULL;
    }
}


// --- handler: 'xmlcharrefreplace' -------------------------------------------

PyObject *PyCodec_XMLCharRefReplaceErrors(PyObject *exc)
{
    if (!_PyIsUnicodeEncodeError(exc)) {
        wrong_exception_type(exc);
        return NULL;
    }

    PyObject *obj;
    Py_ssize_t objlen, start, end, slen;
    if (_PyUnicodeError_GetParams(exc,
                                  &obj, &objlen,
                                  &start, &end, &slen, false) < 0)
    {
        return NULL;
    }

    // The number of characters that each character 'ch' contributes
    // in the result is 2 + k + 1, where k = min{t >= 1 | 10^t > ch}
    // and will be formatted as "&#" + DIGITS + ";". Since the Unicode
    // range is below 10^7, each "block" requires at most 2 + 7 + 1
    // characters.
    if (slen > PY_SSIZE_T_MAX / (2 + 7 + 1)) {
        end = start + PY_SSIZE_T_MAX / (2 + 7 + 1);
        end = Py_MIN(end, objlen);
        slen = Py_MAX(0, end - start);
    }

    Py_ssize_t ressize = 0;
    for (Py_ssize_t i = start; i < end; ++i) {
        Py_UCS4 ch = PyUnicode_READ_CHAR(obj, i);
        int k = n_decimal_digits_for_codepoint(ch);
        assert(k != 0);
        assert(k <= 7);
        ressize += 2 + k + 1;
    }

    /* allocate replacement */
    PyObject *res = PyUnicode_New(ressize, 127);
    if (res == NULL) {
        Py_DECREF(obj);
        return NULL;
    }
    Py_UCS1 *outp = PyUnicode_1BYTE_DATA(res);
    /* generate replacement */
    for (Py_ssize_t i = start; i < end; ++i) {
        Py_UCS4 ch = PyUnicode_READ_CHAR(obj, i);
        /*
         * Write the decimal representation of 'ch' to the buffer pointed by 'p'
         * using at most 7 characters prefixed by '&#' and suffixed by ';'.
         */
        *outp++ = '&';
        *outp++ = '#';
        Py_UCS1 *digit_end = outp + n_decimal_digits_for_codepoint(ch);
        for (Py_UCS1 *p_digit = digit_end - 1; p_digit >= outp; --p_digit) {
            *p_digit = '0' + (ch % 10);
            ch /= 10;
        }
        assert(ch == 0);
        outp = digit_end;
        *outp++ = ';';
    }
    assert(_PyUnicode_CheckConsistency(res, 1));
    PyObject *restuple = Py_BuildValue("(Nn)", res, end);
    Py_DECREF(obj);
    return restuple;
}


// --- handler: 'backslashreplace' --------------------------------------------

static PyObject *
_PyCodec_BackslashReplaceUnicodeEncodeError(PyObject *exc)
{
    PyObject *obj;
    Py_ssize_t objlen, start, end, slen;
    if (_PyUnicodeError_GetParams(exc,
                                  &obj, &objlen,
                                  &start, &end, &slen, false) < 0)
    {
        return NULL;
    }

    // The number of characters that each character 'ch' contributes
    // in the result is 1 + 1 + k, where k >= min{t >= 1 | 16^t > ch}
    // and will be formatted as "\\" + ('U'|'u'|'x') + HEXDIGITS,
    // where the number of hexdigits is either 2, 4, or 8 (not 6).
    // Since the Unicode range is below 10^7, we choose k = 8 whence
    // each "block" requires at most 1 + 1 + 8 characters.
    if (slen > PY_SSIZE_T_MAX / (1 + 1 + 8)) {
        end = start + PY_SSIZE_T_MAX / (1 + 1 + 8);
        end = Py_MIN(end, objlen);
        slen = Py_MAX(0, end - start);
    }

    Py_ssize_t ressize = 0;
    for (Py_ssize_t i = start; i < end; ++i) {
        Py_UCS4 c = PyUnicode_READ_CHAR(obj, i);
        ressize += codec_handler_unicode_hex_width(c);
    }
    PyObject *res = PyUnicode_New(ressize, 127);
    if (res == NULL) {
        Py_DECREF(obj);
        return NULL;
    }
    Py_UCS1 *outp = PyUnicode_1BYTE_DATA(res);
    for (Py_ssize_t i = start; i < end; ++i) {
        Py_UCS4 c = PyUnicode_READ_CHAR(obj, i);
        codec_handler_write_unicode_hex(&outp, c);
    }
    assert(_PyUnicode_CheckConsistency(res, 1));
    Py_DECREF(obj);
    return Py_BuildValue("(Nn)", res, end);
}


static PyObject *
_PyCodec_BackslashReplaceUnicodeDecodeError(PyObject *exc)
{
    PyObject *obj;
    Py_ssize_t objlen, start, end, slen;
    if (_PyUnicodeError_GetParams(exc,
                                  &obj, &objlen,
                                  &start, &end, &slen, true) < 0)
    {
        return NULL;
    }

    PyObject *res = PyUnicode_New(4 * slen, 127);
    if (res == NULL) {
        Py_DECREF(obj);
        return NULL;
    }

    Py_UCS1 *outp = PyUnicode_1BYTE_DATA(res);
    const unsigned char *p = (const unsigned char *)PyBytes_AS_STRING(obj);
    for (Py_ssize_t i = start; i < end; i++, outp += 4) {
        const unsigned char ch = p[i];
        outp[0] = '\\';
        outp[1] = 'x';
        outp[2] = Py_hexdigits[(ch >> 4) & 0xf];
        outp[3] = Py_hexdigits[ch & 0xf];
    }
    assert(_PyUnicode_CheckConsistency(res, 1));
    Py_DECREF(obj);
    return Py_BuildValue("(Nn)", res, end);
}


static inline PyObject *
_PyCodec_BackslashReplaceUnicodeTranslateError(PyObject *exc)
{
    // Same implementation as for UnicodeEncodeError objects.
    return _PyCodec_BackslashReplaceUnicodeEncodeError(exc);
}


PyObject *PyCodec_BackslashReplaceErrors(PyObject *exc)
{
    if (_PyIsUnicodeEncodeError(exc)) {
        return _PyCodec_BackslashReplaceUnicodeEncodeError(exc);
    }
    else if (_PyIsUnicodeDecodeError(exc)) {
        return _PyCodec_BackslashReplaceUnicodeDecodeError(exc);
    }
    else if (_PyIsUnicodeTranslateError(exc)) {
        return _PyCodec_BackslashReplaceUnicodeTranslateError(exc);
    }
    else {
        wrong_exception_type(exc);
        return NULL;
    }
}


// --- handler: 'namereplace' -------------------------------------------------

PyObject *PyCodec_NameReplaceErrors(PyObject *exc)
{
    if (!_PyIsUnicodeEncodeError(exc)) {
        wrong_exception_type(exc);
        return NULL;
    }

    _PyUnicode_Name_CAPI *ucnhash_capi = _PyUnicode_GetNameCAPI();
    if (ucnhash_capi == NULL) {
        return NULL;
    }

    PyObject *obj;
    Py_ssize_t start, end;
    if (_PyUnicodeError_GetParams(exc,
                                  &obj, NULL,
                                  &start, &end, NULL, false) < 0)
    {
        return NULL;
    }

    char buffer[256]; /* NAME_MAXLEN in unicodename_db.h */
    Py_ssize_t imax = start, ressize = 0, replsize;
    for (; imax < end; ++imax) {
        Py_UCS4 c = PyUnicode_READ_CHAR(obj, imax);
        if (ucnhash_capi->getname(c, buffer, sizeof(buffer), 1)) {
            // If 'c' is recognized by getname(), the corresponding replacement
            // is '\\' + 'N' + '{' + NAME + '}', i.e. 1 + 1 + 1 + len(NAME) + 1
            // characters. Failures of getname() are ignored by the handler.
            replsize = 1 + 1 + 1 + strlen(buffer) + 1;
        }
        else {
            replsize = codec_handler_unicode_hex_width(c);
        }
        if (ressize > PY_SSIZE_T_MAX - replsize) {
            break;
        }
        ressize += replsize;
    }

    PyObject *res = PyUnicode_New(ressize, 127);
    if (res == NULL) {
        Py_DECREF(obj);
        return NULL;
    }

    Py_UCS1 *outp = PyUnicode_1BYTE_DATA(res);
    for (Py_ssize_t i = start; i < imax; ++i) {
        Py_UCS4 c = PyUnicode_READ_CHAR(obj, i);
        if (ucnhash_capi->getname(c, buffer, sizeof(buffer), 1)) {
            *outp++ = '\\';
            *outp++ = 'N';
            *outp++ = '{';
            (void)strcpy((char *)outp, buffer);
            outp += strlen(buffer);
            *outp++ = '}';
        }
        else {
            codec_handler_write_unicode_hex(&outp, c);
        }
    }

    assert(outp == PyUnicode_1BYTE_DATA(res) + ressize);
    assert(_PyUnicode_CheckConsistency(res, 1));
    PyObject *restuple = Py_BuildValue("(Nn)", res, imax);
    Py_DECREF(obj);
    return restuple;
}


#define ENC_UNKNOWN     -1
#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_impl(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++;
        if (encoding[0] == '8' && encoding[1] == '\0') {
            *bytelength = 3;
            return ENC_UTF8;
        }
        else if (encoding[0] == '1' && encoding[1] == '6') {
            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;
            }
        }
    }
    else if (strcmp(encoding, "cp65001") == 0) {
        *bytelength = 3;
        return ENC_UTF8;
    }
    return ENC_UNKNOWN;
}


static int
get_standard_encoding(PyObject *encoding, int *code, int *bytelength)
{
    const char *encoding_cstr = PyUnicode_AsUTF8(encoding);
    if (encoding_cstr == NULL) {
        return -1;
    }
    *code = get_standard_encoding_impl(encoding_cstr, bytelength);
    return 0;
}


// --- handler: 'surrogatepass' -----------------------------------------------

static PyObject *
_PyCodec_SurrogatePassUnicodeEncodeError(PyObject *exc)
{
    PyObject *encoding = PyUnicodeEncodeError_GetEncoding(exc);
    if (encoding == NULL) {
        return NULL;
    }
    int code, bytelength;
    int rc = get_standard_encoding(encoding, &code, &bytelength);
    Py_DECREF(encoding);
    if (rc < 0) {
        return NULL;
    }
    if (code == ENC_UNKNOWN) {
        goto bail;
    }

    PyObject *obj;
    Py_ssize_t objlen, start, end, slen;
    if (_PyUnicodeError_GetParams(exc,
                                  &obj, &objlen,
                                  &start, &end, &slen, false) < 0)
    {
        return NULL;
    }

    if (slen > PY_SSIZE_T_MAX / bytelength) {
        end = start + PY_SSIZE_T_MAX / bytelength;
        end = Py_MIN(end, objlen);
        slen = Py_MAX(0, end - start);
    }

    PyObject *res = PyBytes_FromStringAndSize(NULL, bytelength * slen);
    if (res == NULL) {
        Py_DECREF(obj);
        return NULL;
    }

    unsigned char *outp = (unsigned char *)PyBytes_AsString(res);
    for (Py_ssize_t i = start; i < end; i++) {
        Py_UCS4 ch = PyUnicode_READ_CHAR(obj, i);
        if (!Py_UNICODE_IS_SURROGATE(ch)) {
            /* Not a surrogate, fail with original exception */
            Py_DECREF(obj);
            Py_DECREF(res);
            goto bail;
        }
        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;
            }
        }
    }

    Py_DECREF(obj);
    PyObject *restuple = Py_BuildValue("(Nn)", res, end);
    return restuple;

bail:
    PyErr_SetObject(PyExceptionInstance_Class(exc), exc);
    return NULL;
}


static PyObject *
_PyCodec_SurrogatePassUnicodeDecodeError(PyObject *exc)
{
    PyObject *encoding = PyUnicodeDecodeError_GetEncoding(exc);
    if (encoding == NULL) {
        return NULL;
    }
    int code, bytelength;
    int rc = get_standard_encoding(encoding, &code, &bytelength);
    Py_DECREF(encoding);
    if (rc < 0) {
        return NULL;
    }
    if (code == ENC_UNKNOWN) {
        goto bail;
    }

    PyObject *obj;
    Py_ssize_t objlen, start, end, slen;
    if (_PyUnicodeError_GetParams(exc,
                                  &obj, &objlen,
                                  &start, &end, &slen, true) < 0)
    {
        return NULL;
    }

    /* Try decoding a single surrogate character. If
       there are more, let the codec call us again. */
    Py_UCS4 ch = 0;
    const unsigned char *p = (const unsigned char *)PyBytes_AS_STRING(obj);
    p += start;

    if (objlen - 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;
            }
        }
    }
    Py_DECREF(obj);
    if (!Py_UNICODE_IS_SURROGATE(ch)) {
        goto bail;
    }

    PyObject *res = PyUnicode_FromOrdinal(ch);
    if (res == NULL) {
        return NULL;
    }
    return Py_BuildValue("(Nn)", res, start + bytelength);

bail:
    PyErr_SetObject(PyExceptionInstance_Class(exc), exc);
    return NULL;
}


/* This handler is declared static until someone demonstrates
   a need to call it directly. */
static PyObject *
PyCodec_SurrogatePassErrors(PyObject *exc)
{
    if (_PyIsUnicodeEncodeError(exc)) {
        return _PyCodec_SurrogatePassUnicodeEncodeError(exc);
    }
    else if (_PyIsUnicodeDecodeError(exc)) {
        return _PyCodec_SurrogatePassUnicodeDecodeError(exc);
    }
    else {
        wrong_exception_type(exc);
        return NULL;
    }
}


// --- handler: 'surrogateescape' ---------------------------------------------

static PyObject *
_PyCodec_SurrogateEscapeUnicodeEncodeError(PyObject *exc)
{
    PyObject *obj;
    Py_ssize_t start, end, slen;
    if (_PyUnicodeError_GetParams(exc,
                                  &obj, NULL,
                                  &start, &end, &slen, false) < 0)
    {
        return NULL;
    }

    PyObject *res = PyBytes_FromStringAndSize(NULL, slen);
    if (res == NULL) {
        Py_DECREF(obj);
        return NULL;
    }

    char *outp = PyBytes_AsString(res);
    for (Py_ssize_t i = start; i < end; i++) {
        Py_UCS4 ch = PyUnicode_READ_CHAR(obj, i);
        if (ch < 0xdc80 || ch > 0xdcff) {
            /* Not a UTF-8b surrogate, fail with original exception. */
            Py_DECREF(obj);
            Py_DECREF(res);
            PyErr_SetObject(PyExceptionInstance_Class(exc), exc);
            return NULL;
        }
        *outp++ = ch - 0xdc00;
    }
    Py_DECREF(obj);

    return Py_BuildValue("(Nn)", res, end);
}


static PyObject *
_PyCodec_SurrogateEscapeUnicodeDecodeError(PyObject *exc)
{
    PyObject *obj;
    Py_ssize_t start, end, slen;
    if (_PyUnicodeError_GetParams(exc,
                                  &obj, NULL,
                                  &start, &end, &slen, true) < 0)
    {
        return NULL;
    }

    Py_UCS2 ch[4]; /* decode up to 4 bad bytes. */
    int consumed = 0;
    const unsigned char *p = (const unsigned char *)PyBytes_AS_STRING(obj);
    while (consumed < 4 && consumed < slen) {
        /* Refuse to escape ASCII bytes. */
        if (p[start + consumed] < 128) {
            break;
        }
        ch[consumed] = 0xdc00 + p[start + consumed];
        consumed++;
    }
    Py_DECREF(obj);

    if (consumed == 0) {
        /* Codec complained about ASCII byte. */
        PyErr_SetObject(PyExceptionInstance_Class(exc), exc);
        return NULL;
    }

    PyObject *str = PyUnicode_FromKindAndData(PyUnicode_2BYTE_KIND, ch, consumed);
    if (str == NULL) {
        return NULL;
    }
    return Py_BuildValue("(Nn)", str, start + consumed);
}


static PyObject *
PyCodec_SurrogateEscapeErrors(PyObject *exc)
{
    if (_PyIsUnicodeEncodeError(exc)) {
        return _PyCodec_SurrogateEscapeUnicodeEncodeError(exc);
    }
    else if (_PyIsUnicodeDecodeError(exc)) {
        return _PyCodec_SurrogateEscapeUnicodeDecodeError(exc);
    }
    else {
        wrong_exception_type(exc);
        return NULL;
    }
}


// --- Codecs registry handlers -----------------------------------------------

static inline PyObject *
strict_errors(PyObject *Py_UNUSED(self), PyObject *exc)
{
    return PyCodec_StrictErrors(exc);
}


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


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


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


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


static inline PyObject *
namereplace_errors(PyObject *Py_UNUSED(self), PyObject *exc)
{
    return PyCodec_NameReplaceErrors(exc);
}


static inline PyObject *
surrogatepass_errors(PyObject *Py_UNUSED(self), PyObject *exc)
{
    return PyCodec_SurrogatePassErrors(exc);
}


static inline PyObject *
surrogateescape_errors(PyObject *Py_UNUSED(self), PyObject *exc)
{
    return PyCodec_SurrogateEscapeErrors(exc);
}


PyStatus
_PyCodec_InitRegistry(PyInterpreterState *interp)
{
    static struct {
        const char *name;
        PyMethodDef def;
    } methods[] =
    {
        {
            "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, "
                          "which replaces malformed data with a backslashed "
                          "escape sequence.")
            }
        },
        {
            "namereplace",
            {
                "namereplace_errors",
                namereplace_errors,
                METH_O,
                PyDoc_STR("Implements the 'namereplace' error handling, "
                          "which replaces an unencodable character with a "
                          "\\N{...} escape sequence.")
            }
        },
        {
            "surrogatepass",
            {
                "surrogatepass",
                surrogatepass_errors,
                METH_O
            }
        },
        {
            "surrogateescape",
            {
                "surrogateescape",
                surrogateescape_errors,
                METH_O
            }
        }
    };
    // ensure that the built-in error handlers' names are kept in sync
    assert(Py_ARRAY_LENGTH(methods) == Py_ARRAY_LENGTH(codecs_builtin_error_handlers));

    assert(interp->codecs.initialized == 0);
    interp->codecs.search_path = PyList_New(0);
    if (interp->codecs.search_path == NULL) {
        return PyStatus_NoMemory();
    }
    interp->codecs.search_cache = PyDict_New();
    if (interp->codecs.search_cache == NULL) {
        return PyStatus_NoMemory();
    }
    interp->codecs.error_registry = PyDict_New();
    if (interp->codecs.error_registry == NULL) {
        return PyStatus_NoMemory();
    }
    for (size_t i = 0; i < Py_ARRAY_LENGTH(methods); ++i) {
        PyObject *func = PyCFunction_NewEx(&methods[i].def, NULL, NULL);
        if (func == NULL) {
            return PyStatus_NoMemory();
        }

        int res = PyDict_SetItemString(interp->codecs.error_registry,
                                       methods[i].name, func);
        Py_DECREF(func);
        if (res < 0) {
            return PyStatus_Error("Failed to insert into codec error registry");
        }
    }

    interp->codecs.initialized = 1;

    // Importing `encodings' will call back into this module to register codec
    // search functions, so this is done after everything else is initialized.
    PyObject *mod = PyImport_ImportModule("encodings");
    if (mod == NULL) {
        return PyStatus_Error("Failed to import encodings module");
    }
    Py_DECREF(mod);

    return PyStatus_Ok();
}

void
_PyCodec_Fini(PyInterpreterState *interp)
{
    Py_CLEAR(interp->codecs.search_path);
    Py_CLEAR(interp->codecs.search_cache);
    Py_CLEAR(interp->codecs.error_registry);
    interp->codecs.initialized = 0;
}
