LCOV - code coverage report
Current view: | top level - Objects - unicodeobject.c (source / functions) |  |  | Hit | Total | Coverage
Test: | CPython 3.12 LCOV report [commit 5e6661bce9] |  | Lines: | 2528 | 6618 | 38.2 %
Date: | 2023-03-20 08:15:36 |  | Functions: | 202 | 316 | 63.9 %
|  |  | Branches: | 1373 | 4463 | 30.8 %

               Branch data     Line data    Source code
           1                 :            : /*
           2                 :            :
           3                 :            : Unicode implementation based on original code by Fredrik Lundh,
           4                 :            : modified by Marc-Andre Lemburg <mal@lemburg.com>.
           5                 :            :
           6                 :            : Major speed upgrades to the method implementations at the Reykjavik
           7                 :            : NeedForSpeed sprint, by Fredrik Lundh and Andrew Dalke.
           8                 :            :
           9                 :            : Copyright (c) Corporation for National Research Initiatives.
          10                 :            :
          11                 :            : --------------------------------------------------------------------
          12                 :            : The original string type implementation is:
          13                 :            :
          14                 :            :   Copyright (c) 1999 by Secret Labs AB
          15                 :            :   Copyright (c) 1999 by Fredrik Lundh
          16                 :            :
          17                 :            : By obtaining, using, and/or copying this software and/or its
          18                 :            : associated documentation, you agree that you have read, understood,
          19                 :            : and will comply with the following terms and conditions:
          20                 :            :
          21                 :            : Permission to use, copy, modify, and distribute this software and its
          22                 :            : associated documentation for any purpose and without fee is hereby
          23                 :            : granted, provided that the above copyright notice appears in all
          24                 :            : copies, and that both that copyright notice and this permission notice
          25                 :            : appear in supporting documentation, and that the name of Secret Labs
          26                 :            : AB or the author not be used in advertising or publicity pertaining to
          27                 :            : distribution of the software without specific, written prior
          28                 :            : permission.
          29                 :            :
          30                 :            : SECRET LABS AB AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO
          31                 :            : THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
          32                 :            : FITNESS.  IN NO EVENT SHALL SECRET LABS AB OR THE AUTHOR BE LIABLE FOR
          33                 :            : ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
          34                 :            : WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
          35                 :            : ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
          36                 :            : OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
          37                 :            : --------------------------------------------------------------------
          38                 :            :
          39                 :            : */
          40                 :            :
          41                 :            : #define PY_SSIZE_T_CLEAN
          42                 :            : #include "Python.h"
          43                 :            : #include "pycore_abstract.h"      // _PyIndex_Check()
          44                 :            : #include "pycore_atomic_funcs.h"  // _Py_atomic_size_get()
          45                 :            : #include "pycore_bytesobject.h"   // _PyBytes_Repeat()
          46                 :            : #include "pycore_bytes_methods.h" // _Py_bytes_lower()
          47                 :            : #include "pycore_format.h"        // F_LJUST
          48                 :            : #include "pycore_initconfig.h"    // _PyStatus_OK()
          49                 :            : #include "pycore_interp.h"        // PyInterpreterState.fs_codec
          50                 :            : #include "pycore_long.h"          // _PyLong_FormatWriter()
          51                 :            : #include "pycore_object.h"        // _PyObject_GC_TRACK(), _Py_FatalRefcountError()
          52                 :            : #include "pycore_pathconfig.h"    // _Py_DumpPathConfig()
          53                 :            : #include "pycore_pylifecycle.h"   // _Py_SetFileSystemEncoding()
          54                 :            : #include "pycore_pystate.h"       // _PyInterpreterState_GET()
          55                 :            : #include "pycore_ucnhash.h"       // _PyUnicode_Name_CAPI
          56                 :            : #include "pycore_unicodeobject.h" // struct _Py_unicode_state
          57                 :            : #include "pycore_unicodeobject_generated.h"  // _PyUnicode_InitStaticStrings()
          58                 :            : #include "stringlib/eq.h"         // unicode_eq()
          59                 :            :
          60                 :            : #ifdef MS_WINDOWS
          61                 :            : #include <windows.h>
          62                 :            : #endif
          63                 :            :
          64                 :            : #ifdef HAVE_NON_UNICODE_WCHAR_T_REPRESENTATION
          65                 :            : #  include "pycore_fileutils.h"   // _Py_LocaleUsesNonUnicodeWchar()
          66                 :            : #endif
          67                 :            :
          68                 :            : /* Uncomment to display statistics on interned strings at exit
          69                 :            :    in _PyUnicode_ClearInterned(). */
          70                 :            : /* #define INTERNED_STATS 1 */
          71                 :            :
          72                 :            :
          73                 :            : /*[clinic input]
          74                 :            : class str "PyObject *" "&PyUnicode_Type"
          75                 :            : [clinic start generated code]*/
          76                 :            : /*[clinic end generated code: output=da39a3ee5e6b4b0d input=4884c934de622cf6]*/
          77                 :            :
          78                 :            : /*[python input]
          79                 :            : class Py_UCS4_converter(CConverter):
          80                 :            :     type = 'Py_UCS4'
          81                 :            :     converter = 'convert_uc'
          82                 :            :
          83                 :            :     def converter_init(self):
          84                 :            :         if self.default is not unspecified:
          85                 :            :             self.c_default = ascii(self.default)
          86                 :            :             if len(self.c_default) > 4 or self.c_default[0] != "'":
          87                 :            :                 self.c_default = hex(ord(self.default))
          88                 :            :
          89                 :            : [python start generated code]*/
          90                 :            : /*[python end generated code: output=da39a3ee5e6b4b0d input=88f5dd06cd8e7a61]*/
          91                 :            :
          92                 :            : /* --- Globals ------------------------------------------------------------
          93                 :            :
          94                 :            : NOTE: In the interpreter's initialization phase, some globals are currently
          95                 :            :       initialized dynamically as needed. In the process Unicode objects may
          96                 :            :       be created before the Unicode type is ready.
          97                 :            :
          98                 :            : */
          99                 :            :
         100                 :            :
         101                 :            : #ifdef __cplusplus
         102                 :            : extern "C" {
         103                 :            : #endif
         104                 :            :
         105                 :            : // Maximum code point of Unicode 6.0: 0x10ffff (1,114,111).
         106                 :            : // The value must be the same in fileutils.c.
         107                 :            : #define MAX_UNICODE 0x10ffff
         108                 :            :
         109                 :            : #ifdef Py_DEBUG
         110                 :            : #  define _PyUnicode_CHECK(op) _PyUnicode_CheckConsistency(op, 0)
         111                 :            : #else
         112                 :            : #  define _PyUnicode_CHECK(op) PyUnicode_Check(op)
         113                 :            : #endif
         114                 :            :
         115                 :            : #define _PyUnicode_UTF8(op)                             \
         116                 :            :     (_PyCompactUnicodeObject_CAST(op)->utf8)
         117                 :            : #define PyUnicode_UTF8(op)                              \
         118                 :            :     (assert(_PyUnicode_CHECK(op)),                      \
         119                 :            :      PyUnicode_IS_COMPACT_ASCII(op) ?                   \
         120                 :            :          ((char*)(_PyASCIIObject_CAST(op) + 1)) :       \
         121                 :            :          _PyUnicode_UTF8(op))
         122                 :            : #define _PyUnicode_UTF8_LENGTH(op)                      \
         123                 :            :     (_PyCompactUnicodeObject_CAST(op)->utf8_length)
         124                 :            : #define PyUnicode_UTF8_LENGTH(op)                       \
         125                 :            :     (assert(_PyUnicode_CHECK(op)),                      \
         126                 :            :      PyUnicode_IS_COMPACT_ASCII(op) ?                   \
         127                 :            :          _PyASCIIObject_CAST(op)->length :              \
         128                 :            :          _PyUnicode_UTF8_LENGTH(op))
         129                 :            :
         130                 :            : #define _PyUnicode_LENGTH(op)                           \
         131                 :            :     (_PyASCIIObject_CAST(op)->length)
         132                 :            : #define _PyUnicode_STATE(op)                            \
         133                 :            :     (_PyASCIIObject_CAST(op)->state)
         134                 :            : #define _PyUnicode_HASH(op)                             \
         135                 :            :     (_PyASCIIObject_CAST(op)->hash)
         136                 :            : #define _PyUnicode_KIND(op)                             \
         137                 :            :     (assert(_PyUnicode_CHECK(op)),                      \
         138                 :            :      _PyASCIIObject_CAST(op)->state.kind)
         139                 :            : #define _PyUnicode_GET_LENGTH(op)                       \
         140                 :            :     (assert(_PyUnicode_CHECK(op)),                      \
         141                 :            :      _PyASCIIObject_CAST(op)->length)
         142                 :            : #define _PyUnicode_DATA_ANY(op)                         \
         143                 :            :     (_PyUnicodeObject_CAST(op)->data.any)
         144                 :            :
         145                 :            : #define _PyUnicode_SHARE_UTF8(op)                       \
         146                 :            :     (assert(_PyUnicode_CHECK(op)),                      \
         147                 :            :      assert(!PyUnicode_IS_COMPACT_ASCII(op)),           \
         148                 :            :      (_PyUnicode_UTF8(op) == PyUnicode_DATA(op)))
         149                 :            :
         150                 :            : /* true if the Unicode object has an allocated UTF-8 memory block
         151                 :            :    (not shared with other data) */
         152                 :            : #define _PyUnicode_HAS_UTF8_MEMORY(op)                  \
         153                 :            :     ((!PyUnicode_IS_COMPACT_ASCII(op)                   \
         154                 :            :       && _PyUnicode_UTF8(op)                            \
         155                 :            :       && _PyUnicode_UTF8(op) != PyUnicode_DATA(op)))
         156                 :            :
         157                 :            : /* Generic helper macro to convert characters of different types.
         158                 :            :    from_type and to_type have to be valid type names, begin and end
         159                 :            :    are pointers to the source characters which should be of type
         160                 :            :    "from_type *".  to is a pointer of type "to_type *" and points to the
         161                 :            :    buffer where the result characters are written to. */
         162                 :            : #define _PyUnicode_CONVERT_BYTES(from_type, to_type, begin, end, to) \
         163                 :            :     do {                                                \
         164                 :            :         to_type *_to = (to_type *)(to);                 \
         165                 :            :         const from_type *_iter = (const from_type *)(begin);\
         166                 :            :         const from_type *_end = (const from_type *)(end);\
         167                 :            :         Py_ssize_t n = (_end) - (_iter);                \
         168                 :            :         const from_type *_unrolled_end =                \
         169                 :            :             _iter + _Py_SIZE_ROUND_DOWN(n, 4);          \
         170                 :            :         while (_iter < (_unrolled_end)) {               \
         171                 :            :             _to[0] = (to_type) _iter[0];                \
         172                 :            :             _to[1] = (to_type) _iter[1];                \
         173                 :            :             _to[2] = (to_type) _iter[2];                \
         174                 :            :             _to[3] = (to_type) _iter[3];                \
         175                 :            :             _iter += 4; _to += 4;                       \
         176                 :            :         }                                               \
         177                 :            :         while (_iter < (_end))                          \
         178                 :            :             *_to++ = (to_type) *_iter++;                \
         179                 :            :     } while (0)
         180                 :            :
         181                 :            : #define LATIN1(ch)  \
         182                 :            :     (ch < 128 \
         183                 :            :      ? (PyObject*)&_Py_SINGLETON(strings).ascii[ch] \
         184                 :            :      : (PyObject*)&_Py_SINGLETON(strings).latin1[ch - 128])
         185                 :            :
         186                 :            : #ifdef MS_WINDOWS
         187                 :            :    /* On Windows, overallocate by 50% is the best factor */
         188                 :            : #  define OVERALLOCATE_FACTOR 2
         189                 :            : #else
         190                 :            :    /* On Linux, overallocate by 25% is the best factor */
         191                 :            : #  define OVERALLOCATE_FACTOR 4
         192                 :            : #endif
         193                 :            :
         194                 :            : /* Forward declaration */
         195                 :            : static inline int
         196                 :            : _PyUnicodeWriter_WriteCharInline(_PyUnicodeWriter *writer, Py_UCS4 ch);
         197                 :            : static inline void
         198                 :            : _PyUnicodeWriter_InitWithBuffer(_PyUnicodeWriter *writer, PyObject *buffer);
         199                 :            : static PyObject *
         200                 :            : unicode_encode_utf8(PyObject *unicode, _Py_error_handler error_handler,
         201                 :            :                     const char *errors);
         202                 :            : static PyObject *
         203                 :            : unicode_decode_utf8(const char *s, Py_ssize_t size,
         204                 :            :                     _Py_error_handler error_handler, const char *errors,
         205                 :            :                     Py_ssize_t *consumed);
         206                 :            : #ifdef Py_DEBUG
         207                 :            : static inline int unicode_is_finalizing(void);
         208                 :            : static int unicode_is_singleton(PyObject *unicode);
         209                 :            : #endif
         210                 :            :
         211                 :            :
         212                 :            : // Return a borrowed reference to the empty string singleton.
         213                 :     402640 : static inline PyObject* unicode_get_empty(void)
         214                 :            : {
         215                 :            :     _Py_DECLARE_STR(empty, "");
         216                 :     402640 :     return &_Py_STR(empty);
         217                 :            : }
         218                 :            :
         219                 :            :
         220                 :            : // Return a strong reference to the empty string singleton.
         221                 :     293422 : static inline PyObject* unicode_new_empty(void)
         222                 :            : {
         223                 :     293422 :     PyObject *empty = unicode_get_empty();
         224                 :     293422 :     return Py_NewRef(empty);
         225                 :            : }
         226                 :            :
         227                 :            : /* This dictionary holds all interned unicode strings.  Note that references
         228                 :            :    to strings in this dictionary are *not* counted in the string's ob_refcnt.
         229                 :            :    When the interned string reaches a refcnt of 0 the string deallocation
         230                 :            :    function will delete the reference from this dictionary.
         231                 :            :    Another way to look at this is that to say that the actual reference
         232                 :            :    count of a string is:  s->ob_refcnt + (s->state ? 2 : 0)
         233                 :            : */
         234                 :    5344934 : static inline PyObject *get_interned_dict(void)
         235                 :            : {
         236                 :    5344934 :     return _Py_CACHED_OBJECT(interned_strings);
         237                 :            : }
         238                 :            :
         239                 :         54 : static inline void set_interned_dict(PyObject *dict)
         240                 :            : {
         241                 :         54 :     _Py_CACHED_OBJECT(interned_strings) = dict;
         242                 :         54 : }
         243                 :            :
         244                 :            : #define _Py_RETURN_UNICODE_EMPTY()   \
         245                 :            :     do {                             \
         246                 :            :         return unicode_new_empty();  \
         247                 :            :     } while (0)
         248                 :            :
         249                 :            : static inline void
         250                 :     119385 : unicode_fill(int kind, void *data, Py_UCS4 value,
         251                 :            :              Py_ssize_t start, Py_ssize_t length)
         252                 :            : {
         253                 :            :     assert(0 <= start);
         254   [ +  -  -  - ]:     119385 :     switch (kind) {
         255                 :     119385 :     case PyUnicode_1BYTE_KIND: {
         256                 :            :         assert(value <= 0xff);
         257                 :     119385 :         Py_UCS1 ch = (unsigned char)value;
         258                 :     119385 :         Py_UCS1 *to = (Py_UCS1 *)data + start;
         259                 :     119385 :         memset(to, ch, length);
         260                 :     119385 :         break;
         261                 :            :     }
         262                 :          0 :     case PyUnicode_2BYTE_KIND: {
         263                 :            :         assert(value <= 0xffff);
         264                 :          0 :         Py_UCS2 ch = (Py_UCS2)value;
         265                 :          0 :         Py_UCS2 *to = (Py_UCS2 *)data + start;
         266                 :          0 :         const Py_UCS2 *end = to + length;
         267         [ #  # ]:          0 :         for (; to < end; ++to) *to = ch;
         268                 :          0 :         break;
         269                 :            :     }
         270                 :          0 :     case PyUnicode_4BYTE_KIND: {
         271                 :            :         assert(value <= MAX_UNICODE);
         272                 :          0 :         Py_UCS4 ch = value;
         273                 :          0 :         Py_UCS4 * to = (Py_UCS4 *)data + start;
         274                 :          0 :         const Py_UCS4 *end = to + length;
         275         [ #  # ]:          0 :         for (; to < end; ++to) *to = ch;
         276                 :          0 :         break;
         277                 :            :     }
         278                 :          0 :     default: Py_UNREACHABLE();
         279                 :            :     }
         280                 :     119385 : }
         281                 :            :
         282                 :            :
         283                 :            : /* Fast detection of the most frequent whitespace characters */
         284                 :            : const unsigned char _Py_ascii_whitespace[] = {
         285                 :            :     0, 0, 0, 0, 0, 0, 0, 0,
         286                 :            : /*     case 0x0009: * CHARACTER TABULATION */
         287                 :            : /*     case 0x000A: * LINE FEED */
         288                 :            : /*     case 0x000B: * LINE TABULATION */
         289                 :            : /*     case 0x000C: * FORM FEED */
         290                 :            : /*     case 0x000D: * CARRIAGE RETURN */
         291                 :            :     0, 1, 1, 1, 1, 1, 0, 0,
         292                 :            :     0, 0, 0, 0, 0, 0, 0, 0,
         293                 :            : /*     case 0x001C: * FILE SEPARATOR */
         294                 :            : /*     case 0x001D: * GROUP SEPARATOR */
         295                 :            : /*     case 0x001E: * RECORD SEPARATOR */
         296                 :            : /*     case 0x001F: * UNIT SEPARATOR */
         297                 :            :     0, 0, 0, 0, 1, 1, 1, 1,
         298                 :            : /*     case 0x0020: * SPACE */
         299                 :            :     1, 0, 0, 0, 0, 0, 0, 0,
         300                 :            :     0, 0, 0, 0, 0, 0, 0, 0,
         301                 :            :     0, 0, 0, 0, 0, 0, 0, 0,
         302                 :            :     0, 0, 0, 0, 0, 0, 0, 0,
         303                 :            :
         304                 :            :     0, 0, 0, 0, 0, 0, 0, 0,
         305                 :            :     0, 0, 0, 0, 0, 0, 0, 0,
         306                 :            :     0, 0, 0, 0, 0, 0, 0, 0,
         307                 :            :     0, 0, 0, 0, 0, 0, 0, 0,
         308                 :            :     0, 0, 0, 0, 0, 0, 0, 0,
         309                 :            :     0, 0, 0, 0, 0, 0, 0, 0,
         310                 :            :     0, 0, 0, 0, 0, 0, 0, 0,
         311                 :            :     0, 0, 0, 0, 0, 0, 0, 0
         312                 :            : };
         313                 :            :
         314                 :            : /* forward */
         315                 :            : static PyObject* get_latin1_char(unsigned char ch);
         316                 :            : static int unicode_modifiable(PyObject *unicode);
         317                 :            :
         318                 :            :
         319                 :            : static PyObject *
         320                 :            : _PyUnicode_FromUCS1(const Py_UCS1 *s, Py_ssize_t size);
         321                 :            : static PyObject *
         322                 :            : _PyUnicode_FromUCS2(const Py_UCS2 *s, Py_ssize_t size);
         323                 :            : static PyObject *
         324                 :            : _PyUnicode_FromUCS4(const Py_UCS4 *s, Py_ssize_t size);
         325                 :            :
         326                 :            : static PyObject *
         327                 :            : unicode_encode_call_errorhandler(const char *errors,
         328                 :            :        PyObject **errorHandler,const char *encoding, const char *reason,
         329                 :            :        PyObject *unicode, PyObject **exceptionObject,
         330                 :            :        Py_ssize_t startpos, Py_ssize_t endpos, Py_ssize_t *newpos);
         331                 :            :
         332                 :            : static void
         333                 :            : raise_encode_exception(PyObject **exceptionObject,
         334                 :            :                        const char *encoding,
         335                 :            :                        PyObject *unicode,
         336                 :            :                        Py_ssize_t startpos, Py_ssize_t endpos,
         337                 :            :                        const char *reason);
         338                 :            :
         339                 :            : /* Same for linebreaks */
         340                 :            : static const unsigned char ascii_linebreak[] = {
         341                 :            :     0, 0, 0, 0, 0, 0, 0, 0,
         342                 :            : /*         0x000A, * LINE FEED */
         343                 :            : /*         0x000B, * LINE TABULATION */
         344                 :            : /*         0x000C, * FORM FEED */
         345                 :            : /*         0x000D, * CARRIAGE RETURN */
         346                 :            :     0, 0, 1, 1, 1, 1, 0, 0,
         347                 :            :     0, 0, 0, 0, 0, 0, 0, 0,
         348                 :            : /*         0x001C, * FILE SEPARATOR */
         349                 :            : /*         0x001D, * GROUP SEPARATOR */
         350                 :            : /*         0x001E, * RECORD SEPARATOR */
         351                 :            :     0, 0, 0, 0, 1, 1, 1, 0,
         352                 :            :     0, 0, 0, 0, 0, 0, 0, 0,
         353                 :            :     0, 0, 0, 0, 0, 0, 0, 0,
         354                 :            :     0, 0, 0, 0, 0, 0, 0, 0,
         355                 :            :     0, 0, 0, 0, 0, 0, 0, 0,
         356                 :            :
         357                 :            :     0, 0, 0, 0, 0, 0, 0, 0,
         358                 :            :     0, 0, 0, 0, 0, 0, 0, 0,
         359                 :            :     0, 0, 0, 0, 0, 0, 0, 0,
         360                 :            :     0, 0, 0, 0, 0, 0, 0, 0,
         361                 :            :     0, 0, 0, 0, 0, 0, 0, 0,
         362                 :            :     0, 0, 0, 0, 0, 0, 0, 0,
         363                 :            :     0, 0, 0, 0, 0, 0, 0, 0,
         364                 :            :     0, 0, 0, 0, 0, 0, 0, 0
         365                 :            : };
         366                 :            :
         367                 :            : static int convert_uc(PyObject *obj, void *addr);
         368                 :            :
         369                 :            : struct encoding_map;
         370                 :            : #include "clinic/unicodeobject.c.h"
         371                 :            :
         372                 :            : _Py_error_handler
         373                 :        819 : _Py_GetErrorHandler(const char *errors)
         374                 :            : {
         375   [ +  +  -  + ]:        819 :     if (errors == NULL || strcmp(errors, "strict") == 0) {
         376                 :         30 :         return _Py_ERROR_STRICT;
         377                 :            :     }
         378         [ +  + ]:        789 :     if (strcmp(errors, "surrogateescape") == 0) {
         379                 :        788 :         return _Py_ERROR_SURROGATEESCAPE;
         380                 :            :     }
         381         [ -  + ]:          1 :     if (strcmp(errors, "replace") == 0) {
         382                 :          0 :         return _Py_ERROR_REPLACE;
         383                 :            :     }
         384         [ -  + ]:          1 :     if (strcmp(errors, "ignore") == 0) {
         385                 :          0 :         return _Py_ERROR_IGNORE;
         386                 :            :     }
         387         [ -  + ]:          1 :     if (strcmp(errors, "backslashreplace") == 0) {
         388                 :          0 :         return _Py_ERROR_BACKSLASHREPLACE;
         389                 :            :     }
         390         [ +  - ]:          1 :     if (strcmp(errors, "surrogatepass") == 0) {
         391                 :          1 :         return _Py_ERROR_SURROGATEPASS;
         392                 :            :     }
         393         [ #  # ]:          0 :     if (strcmp(errors, "xmlcharrefreplace") == 0) {
         394                 :          0 :         return _Py_ERROR_XMLCHARREFREPLACE;
         395                 :            :     }
         396                 :          0 :     return _Py_ERROR_OTHER;
         397                 :            : }
         398                 :            :
         399                 :            :
         400                 :            : static _Py_error_handler
         401                 :       8819 : get_error_handler_wide(const wchar_t *errors)
         402                 :            : {
         403   [ +  -  -  + ]:       8819 :     if (errors == NULL || wcscmp(errors, L"strict") == 0) {
         404                 :          0 :         return _Py_ERROR_STRICT;
         405                 :            :     }
         406         [ +  - ]:       8819 :     if (wcscmp(errors, L"surrogateescape") == 0) {
         407                 :       8819 :         return _Py_ERROR_SURROGATEESCAPE;
         408                 :            :     }
         409         [ #  # ]:          0 :     if (wcscmp(errors, L"replace") == 0) {
         410                 :          0 :         return _Py_ERROR_REPLACE;
         411                 :            :     }
         412         [ #  # ]:          0 :     if (wcscmp(errors, L"ignore") == 0) {
         413                 :          0 :         return _Py_ERROR_IGNORE;
         414                 :            :     }
         415         [ #  # ]:          0 :     if (wcscmp(errors, L"backslashreplace") == 0) {
         416                 :          0 :         return _Py_ERROR_BACKSLASHREPLACE;
         417                 :            :     }
         418         [ #  # ]:          0 :     if (wcscmp(errors, L"surrogatepass") == 0) {
         419                 :          0 :         return _Py_ERROR_SURROGATEPASS;
         420                 :            :     }
         421         [ #  # ]:          0 :     if (wcscmp(errors, L"xmlcharrefreplace") == 0) {
         422                 :          0 :         return _Py_ERROR_XMLCHARREFREPLACE;
         423                 :            :     }
         424                 :          0 :     return _Py_ERROR_OTHER;
         425                 :            : }
         426                 :            :
         427                 :            :
         428                 :            : static inline int
         429                 :      15987 : unicode_check_encoding_errors(const char *encoding, const char *errors)
         430                 :            : {
         431   [ +  +  +  - ]:      15987 :     if (encoding == NULL && errors == NULL) {
         432                 :          1 :         return 0;
         433                 :            :     }
         434                 :            :
         435                 :      15986 :     PyInterpreterState *interp = _PyInterpreterState_GET();
         436                 :            : #ifndef Py_DEBUG
         437                 :            :     /* In release mode, only check in development mode (-X dev) */
         438         [ +  - ]:      15986 :     if (!_PyInterpreterState_GetConfig(interp)->dev_mode) {
         439                 :      15986 :         return 0;
         440                 :            :     }
         441                 :            : #else
         442                 :            :     /* Always check in debug mode */
         443                 :            : #endif
         444                 :            :
         445                 :            :     /* Avoid calling _PyCodec_Lookup() and PyCodec_LookupError() before the
         446                 :            :        codec registry is ready: before_PyUnicode_InitEncodings() is called. */
         447         [ #  # ]:          0 :     if (!interp->unicode.fs_codec.encoding) {
         448                 :          0 :         return 0;
         449                 :            :     }
         450                 :            :
         451                 :            :     /* Disable checks during Python finalization. For example, it allows to
         452                 :            :        call _PyObject_Dump() during finalization for debugging purpose. */
         453         [ #  # ]:          0 :     if (interp->finalizing) {
         454                 :          0 :         return 0;
         455                 :            :     }
         456                 :            :
         457         [ #  # ]:          0 :     if (encoding != NULL
         458                 :            :         // Fast path for the most common built-in encodings. Even if the codec
         459                 :            :         // is cached, _PyCodec_Lookup() decodes the bytes string from UTF-8 to
         460                 :            :         // create a temporary Unicode string (the key in the cache).
         461         [ #  # ]:          0 :         && strcmp(encoding, "utf-8") != 0
         462         [ #  # ]:          0 :         && strcmp(encoding, "utf8") != 0
         463         [ #  # ]:          0 :         && strcmp(encoding, "ascii") != 0)
         464                 :            :     {
         465                 :          0 :         PyObject *handler = _PyCodec_Lookup(encoding);
         466         [ #  # ]:          0 :         if (handler == NULL) {
         467                 :          0 :             return -1;
         468                 :            :         }
         469                 :          0 :         Py_DECREF(handler);
         470                 :            :     }
         471                 :            :
         472         [ #  # ]:          0 :     if (errors != NULL
         473                 :            :         // Fast path for the most common built-in error handlers.
         474         [ #  # ]:          0 :         && strcmp(errors, "strict") != 0
         475         [ #  # ]:          0 :         && strcmp(errors, "ignore") != 0
         476         [ #  # ]:          0 :         && strcmp(errors, "replace") != 0
         477         [ #  # ]:          0 :         && strcmp(errors, "surrogateescape") != 0
         478         [ #  # ]:          0 :         && strcmp(errors, "surrogatepass") != 0)
         479                 :            :     {
         480                 :          0 :         PyObject *handler = PyCodec_LookupError(errors);
         481         [ #  # ]:          0 :         if (handler == NULL) {
         482                 :          0 :             return -1;
         483                 :            :         }
         484                 :          0 :         Py_DECREF(handler);
         485                 :            :     }
         486                 :          0 :     return 0;
         487                 :            : }
         488                 :            :
         489                 :            :
         490                 :            : int
         491                 :          0 : _PyUnicode_CheckConsistency(PyObject *op, int check_content)
         492                 :            : {
         493                 :            : #define CHECK(expr) \
         494                 :            :     do { if (!(expr)) { _PyObject_ASSERT_FAILED_MSG(op, Py_STRINGIFY(expr)); } } while (0)
         495                 :            :
         496                 :            :     assert(op != NULL);
         497         [ #  # ]:          0 :     CHECK(PyUnicode_Check(op));
         498                 :            :
         499                 :          0 :     PyASCIIObject *ascii = _PyASCIIObject_CAST(op);
         500                 :          0 :     int kind = ascii->state.kind;
         501                 :            :
         502   [ #  #  #  # ]:          0 :     if (ascii->state.ascii == 1 && ascii->state.compact == 1) {
         503         [ #  # ]:          0 :         CHECK(kind == PyUnicode_1BYTE_KIND);
         504                 :            :     }
         505                 :            :     else {
         506                 :          0 :         PyCompactUnicodeObject *compact = _PyCompactUnicodeObject_CAST(op);
         507                 :            :         void *data;
         508                 :            :
         509         [ #  # ]:          0 :         if (ascii->state.compact == 1) {
         510                 :          0 :             data = compact + 1;
         511   [ #  #  #  #  :          0 :             CHECK(kind == PyUnicode_1BYTE_KIND
                       #  # ]
         512                 :            :                                  || kind == PyUnicode_2BYTE_KIND
         513                 :            :                                  || kind == PyUnicode_4BYTE_KIND);
         514         [ #  # ]:          0 :             CHECK(ascii->state.ascii == 0);
         515         [ #  # ]:          0 :             CHECK(compact->utf8 != data);
         516                 :            :         }
         517                 :            :         else {
         518                 :          0 :             PyUnicodeObject *unicode = _PyUnicodeObject_CAST(op);
         519                 :            :
         520                 :          0 :             data = unicode->data.any;
         521   [ #  #  #  #  :          0 :             CHECK(kind == PyUnicode_1BYTE_KIND
                       #  # ]
         522                 :            :                      || kind == PyUnicode_2BYTE_KIND
         523                 :            :                      || kind == PyUnicode_4BYTE_KIND);
         524         [ #  # ]:          0 :             CHECK(ascii->state.compact == 0);
         525         [ #  # ]:          0 :             CHECK(data != NULL);
         526         [ #  # ]:          0 :             if (ascii->state.ascii) {
         527         [ #  # ]:          0 :                 CHECK(compact->utf8 == data);
         528         [ #  # ]:          0 :                 CHECK(compact->utf8_length == ascii->length);
         529                 :            :             }
         530                 :            :             else {
         531         [ #  # ]:          0 :                 CHECK(compact->utf8 != data);
         532                 :            :             }
         533                 :            :         }
         534                 :            :
         535         [ #  # ]:          0 :         if (compact->utf8 == NULL)
         536         [ #  # ]:          0 :             CHECK(compact->utf8_length == 0);
         537                 :            :     }
         538                 :            :
         539                 :            :     /* check that the best kind is used: O(n) operation */
         540         [ #  # ]:          0 :     if (check_content) {
         541                 :            :         Py_ssize_t i;
         542                 :          0 :         Py_UCS4 maxchar = 0;
         543                 :            :         const void *data;
         544                 :            :         Py_UCS4 ch;
         545                 :            :
         546                 :          0 :         data = PyUnicode_DATA(ascii);
         547         [ #  # ]:          0 :         for (i=0; i < ascii->length; i++)
         548                 :            :         {
         549                 :          0 :             ch = PyUnicode_READ(kind, data, i);
         550         [ #  # ]:          0 :             if (ch > maxchar)
         551                 :          0 :                 maxchar = ch;
         552                 :            :         }
         553         [ #  # ]:          0 :         if (kind == PyUnicode_1BYTE_KIND) {
         554         [ #  # ]:          0 :             if (ascii->state.ascii == 0) {
         555         [ #  # ]:          0 :                 CHECK(maxchar >= 128);
         556         [ #  # ]:          0 :                 CHECK(maxchar <= 255);
         557                 :            :             }
         558                 :            :             else
         559         [ #  # ]:          0 :                 CHECK(maxchar < 128);
         560                 :            :         }
         561         [ #  # ]:          0 :         else if (kind == PyUnicode_2BYTE_KIND) {
         562         [ #  # ]:          0 :             CHECK(maxchar >= 0x100);
         563         [ #  # ]:          0 :             CHECK(maxchar <= 0xFFFF);
         564                 :            :         }
         565                 :            :         else {
         566         [ #  # ]:          0 :             CHECK(maxchar >= 0x10000);
         567         [ #  # ]:          0 :             CHECK(maxchar <= MAX_UNICODE);
         568                 :            :         }
         569         [ #  # ]:          0 :         CHECK(PyUnicode_READ(kind, data, ascii->length) == 0);
         570                 :            :     }
         571                 :          0 :     return 1;
         572                 :            :
         573                 :            : #undef CHECK
         574                 :            : }
         575                 :            :
         576                 :            : static PyObject*
         577                 :     313517 : unicode_result(PyObject *unicode)
         578                 :            : {
         579                 :            :     assert(_PyUnicode_CHECK(unicode));
         580                 :            :
         581                 :     313517 :     Py_ssize_t length = PyUnicode_GET_LENGTH(unicode);
         582         [ -  + ]:     313517 :     if (length == 0) {
         583                 :          0 :         PyObject *empty = unicode_get_empty();
         584         [ #  # ]:          0 :         if (unicode != empty) {
         585                 :          0 :             Py_DECREF(unicode);
         586                 :          0 :             Py_INCREF(empty);
         587                 :            :         }
         588                 :          0 :         return empty;
         589                 :            :     }
         590                 :            :
         591         [ +  + ]:     313517 :     if (length == 1) {
         592                 :        703 :         int kind = PyUnicode_KIND(unicode);
         593         [ +  + ]:        703 :         if (kind == PyUnicode_1BYTE_KIND) {
         594                 :        689 :             const Py_UCS1 *data = PyUnicode_1BYTE_DATA(unicode);
         595                 :        689 :             Py_UCS1 ch = data[0];
         596         [ +  + ]:        689 :             PyObject *latin1_char = LATIN1(ch);
         597         [ +  - ]:        689 :             if (unicode != latin1_char) {
         598                 :        689 :                 Py_INCREF(latin1_char);
         599                 :        689 :                 Py_DECREF(unicode);
         600                 :            :             }
         601                 :        689 :             return latin1_char;
         602                 :            :         }
         603                 :            :     }
         604                 :            :
         605                 :            :     assert(_PyUnicode_CheckConsistency(unicode, 1));
         606                 :     312828 :     return unicode;
         607                 :            : }
         608                 :            :
         609                 :            : static PyObject*
         610                 :      68049 : unicode_result_unchanged(PyObject *unicode)
         611                 :            : {
         612         [ +  - ]:      68049 :     if (PyUnicode_CheckExact(unicode)) {
         613                 :      68049 :         return Py_NewRef(unicode);
         614                 :            :     }
         615                 :            :     else
         616                 :            :         /* Subtype -- return genuine unicode string with the same value. */
         617                 :          0 :         return _PyUnicode_Copy(unicode);
         618                 :            : }
         619                 :            :
         620                 :            : /* Implementation of the "backslashreplace" error handler for 8-bit encodings:
         621                 :            :    ASCII, Latin1, UTF-8, etc. */
         622                 :            : static char*
         623                 :          0 : backslashreplace(_PyBytesWriter *writer, char *str,
         624                 :            :                  PyObject *unicode, Py_ssize_t collstart, Py_ssize_t collend)
         625                 :            : {
         626                 :            :     Py_ssize_t size, i;
         627                 :            :     Py_UCS4 ch;
         628                 :            :     int kind;
         629                 :            :     const void *data;
         630                 :            :
         631                 :          0 :     kind = PyUnicode_KIND(unicode);
         632                 :          0 :     data = PyUnicode_DATA(unicode);
         633                 :            :
         634                 :          0 :     size = 0;
         635                 :            :     /* determine replacement size */
         636         [ #  # ]:          0 :     for (i = collstart; i < collend; ++i) {
         637                 :            :         Py_ssize_t incr;
         638                 :            :
         639                 :          0 :         ch = PyUnicode_READ(kind, data, i);
         640         [ #  # ]:          0 :         if (ch < 0x100)
         641                 :          0 :             incr = 2+2;
         642         [ #  # ]:          0 :         else if (ch < 0x10000)
         643                 :          0 :             incr = 2+4;
         644                 :            :         else {
         645                 :            :             assert(ch <= MAX_UNICODE);
         646                 :          0 :             incr = 2+8;
         647                 :            :         }
         648         [ #  # ]:          0 :         if (size > PY_SSIZE_T_MAX - incr) {
         649                 :          0 :             PyErr_SetString(PyExc_OverflowError,
         650                 :            :                             "encoded result is too long for a Python string");
         651                 :          0 :             return NULL;
         652                 :            :         }
         653                 :          0 :         size += incr;
         654                 :            :     }
         655                 :            :
         656                 :          0 :     str = _PyBytesWriter_Prepare(writer, str, size);
         657         [ #  # ]:          0 :     if (str == NULL)
         658                 :          0 :         return NULL;
         659                 :            :
         660                 :            :     /* generate replacement */
         661         [ #  # ]:          0 :     for (i = collstart; i < collend; ++i) {
         662                 :          0 :         ch = PyUnicode_READ(kind, data, i);
         663                 :          0 :         *str++ = '\\';
         664         [ #  # ]:          0 :         if (ch >= 0x00010000) {
         665                 :          0 :             *str++ = 'U';
         666                 :          0 :             *str++ = Py_hexdigits[(ch>>28)&0xf];
         667                 :          0 :             *str++ = Py_hexdigits[(ch>>24)&0xf];
         668                 :          0 :             *str++ = Py_hexdigits[(ch>>20)&0xf];
         669                 :          0 :             *str++ = Py_hexdigits[(ch>>16)&0xf];
         670                 :          0 :             *str++ = Py_hexdigits[(ch>>12)&0xf];
         671                 :          0 :             *str++ = Py_hexdigits[(ch>>8)&0xf];
         672                 :            :         }
         673         [ #  # ]:          0 :         else if (ch >= 0x100) {
         674                 :          0 :             *str++ = 'u';
         675                 :          0 :             *str++ = Py_hexdigits[(ch>>12)&0xf];
         676                 :          0 :             *str++ = Py_hexdigits[(ch>>8)&0xf];
         677                 :            :         }
         678                 :            :         else
         679                 :          0 :             *str++ = 'x';
         680                 :          0 :         *str++ = Py_hexdigits[(ch>>4)&0xf];
         681                 :          0 :         *str++ = Py_hexdigits[ch&0xf];
         682                 :            :     }
         683                 :          0 :     return str;
         684                 :            : }
         685                 :            :
         686                 :            : /* Implementation of the "xmlcharrefreplace" error handler for 8-bit encodings:
         687                 :            :    ASCII, Latin1, UTF-8, etc. */
         688                 :            : static char*
         689                 :          0 : xmlcharrefreplace(_PyBytesWriter *writer, char *str,
         690                 :            :                   PyObject *unicode, Py_ssize_t collstart, Py_ssize_t collend)
         691                 :            : {
         692                 :            :     Py_ssize_t size, i;
         693                 :            :     Py_UCS4 ch;
         694                 :            :     int kind;
         695                 :            :     const void *data;
         696                 :            :
         697                 :          0 :     kind = PyUnicode_KIND(unicode);
         698                 :          0 :     data = PyUnicode_DATA(unicode);
         699                 :            :
         700                 :          0 :     size = 0;
         701                 :            :     /* determine replacement size */
         702         [ #  # ]:          0 :     for (i = collstart; i < collend; ++i) {
         703                 :            :         Py_ssize_t incr;
         704                 :            :
         705                 :          0 :         ch = PyUnicode_READ(kind, data, i);
         706         [ #  # ]:          0 :         if (ch < 10)
         707                 :          0 :             incr = 2+1+1;
         708         [ #  # ]:          0 :         else if (ch < 100)
         709                 :          0 :             incr = 2+2+1;
         710         [ #  # ]:          0 :         else if (ch < 1000)
         711                 :          0 :             incr = 2+3+1;
         712         [ #  # ]:          0 :         else if (ch < 10000)
         713                 :          0 :             incr = 2+4+1;
         714         [ #  # ]:          0 :         else if (ch < 100000)
         715                 :          0 :             incr = 2+5+1;
         716         [ #  # ]:          0 :         else if (ch < 1000000)
         717                 :          0 :             incr = 2+6+1;
         718                 :            :         else {
         719                 :            :             assert(ch <= MAX_UNICODE);
         720                 :          0 :             incr = 2+7+1;
         721                 :            :         }
         722         [ #  # ]:          0 :         if (size > PY_SSIZE_T_MAX - incr) {
         723                 :          0 :             PyErr_SetString(PyExc_OverflowError,
         724                 :            :                             "encoded result is too long for a Python string");
         725                 :          0 :             return NULL;
         726                 :            :         }
         727                 :          0 :         size += incr;
         728                 :            :     }
         729                 :            :
         730                 :          0 :     str = _PyBytesWriter_Prepare(writer, str, size);
         731         [ #  # ]:          0 :     if (str == NULL)
         732                 :          0 :         return NULL;
         733                 :            :
         734                 :            :     /* generate replacement */
         735         [ #  # ]:          0 :     for (i = collstart; i < collend; ++i) {
         736                 :          0 :         size = sprintf(str, "&#%d;", PyUnicode_READ(kind, data, i));
         737         [ #  # ]:          0 :         if (size < 0) {
         738                 :          0 :             return NULL;
         739                 :            :         }
         740                 :          0 :         str += size;
         741                 :            :     }
         742                 :          0 :     return str;
         743                 :            : }
         744                 :            :
         745                 :            : /* --- Bloom Filters ----------------------------------------------------- */
         746                 :            :
         747                 :            : /* stuff to implement simple "bloom filters" for Unicode characters.
         748                 :            :    to keep things simple, we use a single bitmask, using the least 5
         749                 :            :    bits from each unicode characters as the bit index. */
         750                 :            :
         751                 :            : /* the linebreak mask is set up by _PyUnicode_Init() below */
         752                 :            :
         753                 :            : #if LONG_BIT >= 128
         754                 :            : #define BLOOM_WIDTH 128
         755                 :            : #elif LONG_BIT >= 64
         756                 :            : #define BLOOM_WIDTH 64
         757                 :            : #elif LONG_BIT >= 32
         758                 :            : #define BLOOM_WIDTH 32
         759                 :            : #else
         760                 :            : #error "LONG_BIT is smaller than 32"
         761                 :            : #endif
         762                 :            :
         763                 :            : #define BLOOM_MASK unsigned long
         764                 :            :
         765                 :            : static BLOOM_MASK bloom_linebreak = ~(BLOOM_MASK)0;
         766                 :            :
         767                 :            : #define BLOOM(mask, ch)     ((mask &  (1UL << ((ch) & (BLOOM_WIDTH - 1)))))
         768                 :            :
         769                 :            : #define BLOOM_LINEBREAK(ch)                                             \
         770                 :            :     ((ch) < 128U ? ascii_linebreak[(ch)] :                              \
         771                 :            :      (BLOOM(bloom_linebreak, (ch)) && Py_UNICODE_ISLINEBREAK(ch)))
         772                 :            :
         773                 :            : static inline BLOOM_MASK
         774                 :      11432 : make_bloom_mask(int kind, const void* ptr, Py_ssize_t len)
         775                 :            : {
         776                 :            : #define BLOOM_UPDATE(TYPE, MASK, PTR, LEN)             \
         777                 :            :     do {                                               \
         778                 :            :         TYPE *data = (TYPE *)PTR;                      \
         779                 :            :         TYPE *end = data + LEN;                        \
         780                 :            :         Py_UCS4 ch;                                    \
         781                 :            :         for (; data != end; data++) {                  \
         782                 :            :             ch = *data;                                \
         783                 :            :             MASK |= (1UL << (ch & (BLOOM_WIDTH - 1))); \
         784                 :            :         }                                              \
         785                 :            :         break;                                         \
         786                 :            :     } while (0)
         787                 :            :
         788                 :            :     /* calculate simple bloom-style bitmask for a given unicode string */
         789                 :            :
         790                 :            :     BLOOM_MASK mask;
         791                 :            :
         792                 :      11432 :     mask = 0;
         793   [ +  +  -  - ]:      11432 :     switch (kind) {
         794                 :      11403 :     case PyUnicode_1BYTE_KIND:
         795         [ +  + ]:      22829 :         BLOOM_UPDATE(Py_UCS1, mask, ptr, len);
         796                 :      11403 :         break;
         797                 :         29 :     case PyUnicode_2BYTE_KIND:
         798         [ +  + ]:        261 :         BLOOM_UPDATE(Py_UCS2, mask, ptr, len);
         799                 :         29 :         break;
         800                 :          0 :     case PyUnicode_4BYTE_KIND:
         801         [ #  # ]:          0 :         BLOOM_UPDATE(Py_UCS4, mask, ptr, len);
         802                 :          0 :         break;
         803                 :          0 :     default:
         804                 :          0 :         Py_UNREACHABLE();
         805                 :            :     }
         806                 :      11432 :     return mask;
         807                 :            :
         808                 :            : #undef BLOOM_UPDATE
         809                 :            : }
         810                 :            :
         811                 :            : static int
         812                 :     118302 : ensure_unicode(PyObject *obj)
         813                 :            : {
         814         [ -  + ]:     118302 :     if (!PyUnicode_Check(obj)) {
         815                 :          0 :         PyErr_Format(PyExc_TypeError,
         816                 :            :                      "must be str, not %.100s",
         817                 :          0 :                      Py_TYPE(obj)->tp_name);
         818                 :          0 :         return -1;
         819                 :            :     }
         820                 :     118302 :     return 0;
         821                 :            : }
         822                 :            :
         823                 :            : /* Compilation of templated routines */
         824                 :            :
         825                 :            : #define STRINGLIB_GET_EMPTY() unicode_get_empty()
         826                 :            :
         827                 :            : #include "stringlib/asciilib.h"
         828                 :            : #include "stringlib/fastsearch.h"
         829                 :            : #include "stringlib/partition.h"
         830                 :            : #include "stringlib/split.h"
         831                 :            : #include "stringlib/count.h"
         832                 :            : #include "stringlib/find.h"
         833                 :            : #include "stringlib/find_max_char.h"
         834                 :            : #include "stringlib/undef.h"
         835                 :            :
         836                 :            : #include "stringlib/ucs1lib.h"
         837                 :            : #include "stringlib/fastsearch.h"
         838                 :            : #include "stringlib/partition.h"
         839                 :            : #include "stringlib/split.h"
         840                 :            : #include "stringlib/count.h"
         841                 :            : #include "stringlib/find.h"
         842                 :            : #include "stringlib/replace.h"
         843                 :            : #include "stringlib/find_max_char.h"
         844                 :            : #include "stringlib/undef.h"
         845                 :            :
         846                 :            : #include "stringlib/ucs2lib.h"
         847                 :            : #include "stringlib/fastsearch.h"
         848                 :            : #include "stringlib/partition.h"
         849                 :            : #include "stringlib/split.h"
         850                 :            : #include "stringlib/count.h"
         851                 :            : #include "stringlib/find.h"
         852                 :            : #include "stringlib/replace.h"
         853                 :            : #include "stringlib/find_max_char.h"
         854                 :            : #include "stringlib/undef.h"
         855                 :            :
         856                 :            : #include "stringlib/ucs4lib.h"
         857                 :            : #include "stringlib/fastsearch.h"
         858                 :            : #include "stringlib/partition.h"
         859                 :            : #include "stringlib/split.h"
         860                 :            : #include "stringlib/count.h"
         861                 :            : #include "stringlib/find.h"
         862                 :            : #include "stringlib/replace.h"
         863                 :            : #include "stringlib/find_max_char.h"
         864                 :            : #include "stringlib/undef.h"
         865                 :            :
         866                 :            : #undef STRINGLIB_GET_EMPTY
         867                 :            :
         868                 :            : /* --- Unicode Object ----------------------------------------------------- */
         869                 :            :
         870                 :            : static inline Py_ssize_t
         871                 :      19222 : findchar(const void *s, int kind,
         872                 :            :          Py_ssize_t size, Py_UCS4 ch,
         873                 :            :          int direction)
         874                 :            : {
         875   [ +  -  -  - ]:      19222 :     switch (kind) {
         876                 :      19222 :     case PyUnicode_1BYTE_KIND:
         877         [ -  + ]:      19222 :         if ((Py_UCS1) ch != ch)
         878                 :          0 :             return -1;
         879         [ +  + ]:      19222 :         if (direction > 0)
         880                 :      16300 :             return ucs1lib_find_char((const Py_UCS1 *) s, size, (Py_UCS1) ch);
         881                 :            :         else
         882                 :       2922 :             return ucs1lib_rfind_char((const Py_UCS1 *) s, size, (Py_UCS1) ch);
         883                 :          0 :     case PyUnicode_2BYTE_KIND:
         884         [ #  # ]:          0 :         if ((Py_UCS2) ch != ch)
         885                 :          0 :             return -1;
         886         [ #  # ]:          0 :         if (direction > 0)
         887                 :          0 :             return ucs2lib_find_char((const Py_UCS2 *) s, size, (Py_UCS2) ch);
         888                 :            :         else
         889                 :          0 :             return ucs2lib_rfind_char((const Py_UCS2 *) s, size, (Py_UCS2) ch);
         890                 :          0 :     case PyUnicode_4BYTE_KIND:
         891         [ #  # ]:          0 :         if (direction > 0)
         892                 :          0 :             return ucs4lib_find_char((const Py_UCS4 *) s, size, ch);
         893                 :            :         else
         894                 :          0 :             return ucs4lib_rfind_char((const Py_UCS4 *) s, size, ch);
         895                 :          0 :     default:
         896                 :          0 :         Py_UNREACHABLE();
         897                 :            :     }
         898                 :            : }
         899                 :            :
         900                 :            : #ifdef Py_DEBUG
         901                 :            : /* Fill the data of a Unicode string with invalid characters to detect bugs
         902                 :            :    earlier.
         903                 :            :
         904                 :            :    _PyUnicode_CheckConsistency(str, 1) detects invalid characters, at least for
         905                 :            :    ASCII and UCS-4 strings. U+00FF is invalid in ASCII and U+FFFFFFFF is an
         906                 :            :    invalid character in Unicode 6.0. */
         907                 :            : static void
         908                 :            : unicode_fill_invalid(PyObject *unicode, Py_ssize_t old_length)
         909                 :            : {
         910                 :            :     int kind = PyUnicode_KIND(unicode);
         911                 :            :     Py_UCS1 *data = PyUnicode_1BYTE_DATA(unicode);
         912                 :            :     Py_ssize_t length = _PyUnicode_LENGTH(unicode);
         913                 :            :     if (length <= old_length)
         914                 :            :         return;
         915                 :            :     memset(data + old_length * kind, 0xff, (length - old_length) * kind);
         916                 :            : }
         917                 :            : #endif
         918                 :            :
         919                 :            : static PyObject*
         920                 :      80460 : resize_compact(PyObject *unicode, Py_ssize_t length)
         921                 :            : {
         922                 :            :     Py_ssize_t char_size;
         923                 :            :     Py_ssize_t struct_size;
         924                 :            :     Py_ssize_t new_size;
         925                 :            :     PyObject *new_unicode;
         926                 :            : #ifdef Py_DEBUG
         927                 :            :     Py_ssize_t old_length = _PyUnicode_LENGTH(unicode);
         928                 :            : #endif
         929                 :            :
         930                 :            :     assert(unicode_modifiable(unicode));
         931                 :            :     assert(PyUnicode_IS_COMPACT(unicode));
         932                 :            :
         933                 :      80460 :     char_size = PyUnicode_KIND(unicode);
         934         [ +  + ]:      80460 :     if (PyUnicode_IS_ASCII(unicode))
         935                 :      80236 :         struct_size = sizeof(PyASCIIObject);
         936                 :            :     else
         937                 :        224 :         struct_size = sizeof(PyCompactUnicodeObject);
         938                 :            :
         939         [ -  + ]:      80460 :     if (length > ((PY_SSIZE_T_MAX - struct_size) / char_size - 1)) {
         940                 :          0 :         PyErr_NoMemory();
         941                 :          0 :         return NULL;
         942                 :            :     }
         943                 :      80460 :     new_size = (struct_size + (length + 1) * char_size);
         944                 :            :
         945   [ +  +  -  +  :      80460 :     if (_PyUnicode_HAS_UTF8_MEMORY(unicode)) {
                       -  - ]
         946                 :          0 :         PyObject_Free(_PyUnicode_UTF8(unicode));
         947                 :          0 :         _PyUnicode_UTF8(unicode) = NULL;
         948                 :          0 :         _PyUnicode_UTF8_LENGTH(unicode) = 0;
         949                 :            :     }
         950                 :            : #ifdef Py_TRACE_REFS
         951                 :            :     _Py_ForgetReference(unicode);
         952                 :            : #endif
         953                 :            :
         954                 :      80460 :     new_unicode = (PyObject *)PyObject_Realloc(unicode, new_size);
         955         [ -  + ]:      80460 :     if (new_unicode == NULL) {
         956                 :          0 :         _Py_NewReferenceNoTotal(unicode);
         957                 :          0 :         PyErr_NoMemory();
         958                 :          0 :         return NULL;
         959                 :            :     }
         960                 :      80460 :     unicode = new_unicode;
         961                 :      80460 :     _Py_NewReferenceNoTotal(unicode);
         962                 :            :
         963                 :      80460 :     _PyUnicode_LENGTH(unicode) = length;
         964                 :            : #ifdef Py_DEBUG
         965                 :            :     unicode_fill_invalid(unicode, old_length);
         966                 :            : #endif
         967                 :      80460 :     PyUnicode_WRITE(PyUnicode_KIND(unicode), PyUnicode_DATA(unicode),
         968                 :            :                     length, 0);
         969                 :            :     assert(_PyUnicode_CheckConsistency(unicode, 0));
         970                 :      80460 :     return unicode;
         971                 :            : }
         972                 :            :
         973                 :            : static int
         974                 :          0 : resize_inplace(PyObject *unicode, Py_ssize_t length)
         975                 :            : {
         976                 :            :     assert(!PyUnicode_IS_COMPACT(unicode));
         977                 :            :     assert(Py_REFCNT(unicode) == 1);
         978                 :            :
         979                 :            :     Py_ssize_t new_size;
         980                 :            :     Py_ssize_t char_size;
         981                 :            :     int share_utf8;
         982                 :            :     void *data;
         983                 :            : #ifdef Py_DEBUG
         984                 :            :     Py_ssize_t old_length = _PyUnicode_LENGTH(unicode);
         985                 :            : #endif
         986                 :            :
         987                 :          0 :     data = _PyUnicode_DATA_ANY(unicode);
         988                 :          0 :     char_size = PyUnicode_KIND(unicode);
         989                 :          0 :     share_utf8 = _PyUnicode_SHARE_UTF8(unicode);
         990                 :            :
         991         [ #  # ]:          0 :     if (length > (PY_SSIZE_T_MAX / char_size - 1)) {
         992                 :          0 :         PyErr_NoMemory();
         993                 :          0 :         return -1;
         994                 :            :     }
         995                 :          0 :     new_size = (length + 1) * char_size;
         996                 :            :
         997   [ #  #  #  #  :          0 :     if (!share_utf8 && _PyUnicode_HAS_UTF8_MEMORY(unicode))
                 #  #  #  # ]
         998                 :            :     {
         999                 :          0 :         PyObject_Free(_PyUnicode_UTF8(unicode));
        1000                 :          0 :         _PyUnicode_UTF8(unicode) = NULL;
        1001                 :          0 :         _PyUnicode_UTF8_LENGTH(unicode) = 0;
        1002                 :            :     }
        1003                 :            :
        1004                 :          0 :     data = (PyObject *)PyObject_Realloc(data, new_size);
        1005         [ #  # ]:          0 :     if (data == NULL) {
        1006                 :          0 :         PyErr_NoMemory();
        1007                 :          0 :         return -1;
        1008                 :            :     }
        1009                 :          0 :     _PyUnicode_DATA_ANY(unicode) = data;
        1010         [ #  # ]:          0 :     if (share_utf8) {
        1011                 :          0 :         _PyUnicode_UTF8(unicode) = data;
        1012                 :          0 :         _PyUnicode_UTF8_LENGTH(unicode) = length;
        1013                 :            :     }
        1014                 :          0 :     _PyUnicode_LENGTH(unicode) = length;
        1015                 :          0 :     PyUnicode_WRITE(PyUnicode_KIND(unicode), data, length, 0);
        1016                 :            : #ifdef Py_DEBUG
        1017                 :            :     unicode_fill_invalid(unicode, old_length);
        1018                 :            : #endif
        1019                 :            :
        1020                 :            :     /* check for integer overflow */
        1021         [ #  # ]:          0 :     if (length > PY_SSIZE_T_MAX / (Py_ssize_t)sizeof(wchar_t) - 1) {
        1022                 :          0 :         PyErr_NoMemory();
        1023                 :          0 :         return -1;
        1024                 :            :     }
        1025                 :            :     assert(_PyUnicode_CheckConsistency(unicode, 0));
        1026                 :          0 :     return 0;
        1027                 :            : }
        1028                 :            :
        1029                 :            : static PyObject*
        1030                 :          0 : resize_copy(PyObject *unicode, Py_ssize_t length)
        1031                 :            : {
        1032                 :            :     Py_ssize_t copy_length;
        1033                 :            :     PyObject *copy;
        1034                 :            :
        1035                 :          0 :     copy = PyUnicode_New(length, PyUnicode_MAX_CHAR_VALUE(unicode));
        1036         [ #  # ]:          0 :     if (copy == NULL)
        1037                 :          0 :         return NULL;
        1038                 :            :
        1039         [ #  # ]:          0 :     copy_length = Py_MIN(length, PyUnicode_GET_LENGTH(unicode));
        1040                 :          0 :     _PyUnicode_FastCopyCharacters(copy, 0, unicode, 0, copy_length);
        1041                 :          0 :     return copy;
        1042                 :            : }
        1043                 :            :
        1044                 :            : static const char*
        1045                 :          0 : unicode_kind_name(PyObject *unicode)
        1046                 :            : {
        1047                 :            :     /* don't check consistency: unicode_kind_name() is called from
        1048                 :            :        _PyUnicode_Dump() */
        1049         [ #  # ]:          0 :     if (!PyUnicode_IS_COMPACT(unicode))
        1050                 :            :     {
        1051   [ #  #  #  # ]:          0 :         switch (PyUnicode_KIND(unicode))
        1052                 :            :         {
        1053                 :          0 :         case PyUnicode_1BYTE_KIND:
        1054         [ #  # ]:          0 :             if (PyUnicode_IS_ASCII(unicode))
        1055                 :          0 :                 return "legacy ascii";
        1056                 :            :             else
        1057                 :          0 :                 return "legacy latin1";
        1058                 :          0 :         case PyUnicode_2BYTE_KIND:
        1059                 :          0 :             return "legacy UCS2";
        1060                 :          0 :         case PyUnicode_4BYTE_KIND:
        1061                 :          0 :             return "legacy UCS4";
        1062                 :          0 :         default:
        1063                 :          0 :             return "<legacy invalid kind>";
        1064                 :            :         }
        1065                 :            :     }
        1066   [ #  #  #  # ]:          0 :     switch (PyUnicode_KIND(unicode)) {
        1067                 :          0 :     case PyUnicode_1BYTE_KIND:
        1068         [ #  # ]:          0 :         if (PyUnicode_IS_ASCII(unicode))
        1069                 :          0 :             return "ascii";
        1070                 :            :         else
        1071                 :          0 :             return "latin1";
        1072                 :          0 :     case PyUnicode_2BYTE_KIND:
        1073                 :          0 :         return "UCS2";
        1074                 :          0 :     case PyUnicode_4BYTE_KIND:
        1075                 :          0 :         return "UCS4";
        1076                 :          0 :     default:
        1077                 :          0 :         return "<invalid compact kind>";
        1078                 :            :     }
        1079                 :            : }
        1080                 :            :
        1081                 :            : #ifdef Py_DEBUG
        1082                 :            : /* Functions wrapping macros for use in debugger */
        1083                 :            : const char *_PyUnicode_utf8(void *unicode_raw){
        1084                 :            :     PyObject *unicode = _PyObject_CAST(unicode_raw);
        1085                 :            :     return PyUnicode_UTF8(unicode);
        1086                 :            : }
        1087                 :            :
        1088                 :            : const void *_PyUnicode_compact_data(void *unicode_raw) {
        1089                 :            :     PyObject *unicode = _PyObject_CAST(unicode_raw);
        1090                 :            :     return _PyUnicode_COMPACT_DATA(unicode);
        1091                 :            : }
        1092                 :            : const void *_PyUnicode_data(void *unicode_raw) {
        1093                 :            :     PyObject *unicode = _PyObject_CAST(unicode_raw);
        1094                 :            :     printf("obj %p\n", (void*)unicode);
        1095                 :            :     printf("compact %d\n", PyUnicode_IS_COMPACT(unicode));
        1096                 :            :     printf("compact ascii %d\n", PyUnicode_IS_COMPACT_ASCII(unicode));
        1097                 :            :     printf("ascii op %p\n", (void*)(_PyASCIIObject_CAST(unicode) + 1));
        1098                 :            :     printf("compact op %p\n", (void*)(_PyCompactUnicodeObject_CAST(unicode) + 1));
        1099                 :            :     printf("compact data %p\n", _PyUnicode_COMPACT_DATA(unicode));
        1100                 :            :     return PyUnicode_DATA(unicode);
        1101                 :            : }
        1102                 :            :
        1103                 :            : void
        1104                 :            : _PyUnicode_Dump(PyObject *op)
        1105                 :            : {
        1106                 :            :     PyASCIIObject *ascii = _PyASCIIObject_CAST(op);
        1107                 :            :     PyCompactUnicodeObject *compact = _PyCompactUnicodeObject_CAST(op);
        1108                 :            :     PyUnicodeObject *unicode = _PyUnicodeObject_CAST(op);
        1109                 :            :     const void *data;
        1110                 :            :
        1111                 :            :     if (ascii->state.compact)
        1112                 :            :     {
        1113                 :            :         if (ascii->state.ascii)
        1114                 :            :             data = (ascii + 1);
        1115                 :            :         else
        1116                 :            :             data = (compact + 1);
        1117                 :            :     }
        1118                 :            :     else
        1119                 :            :         data = unicode->data.any;
        1120                 :            :     printf("%s: len=%zu, ", unicode_kind_name(op), ascii->length);
        1121                 :            :
        1122                 :            :     if (!ascii->state.ascii) {
        1123                 :            :         printf("utf8=%p (%zu)", (void *)compact->utf8, compact->utf8_length);
        1124                 :            :     }
        1125                 :            :     printf(", data=%p\n", data);
        1126                 :            : }
        1127                 :            : #endif
        1128                 :            :
        1129                 :            :
        1130                 :            : PyObject *
        1131                 :    4856771 : PyUnicode_New(Py_ssize_t size, Py_UCS4 maxchar)
        1132                 :            : {
        1133                 :            :     /* Optimization for empty strings */
        1134         [ +  + ]:    4856771 :     if (size == 0) {
        1135                 :     271731 :         return unicode_new_empty();
        1136                 :            :     }
        1137                 :            :
        1138                 :            :     PyObject *obj;
        1139                 :            :     PyCompactUnicodeObject *unicode;
        1140                 :            :     void *data;
        1141                 :            :     int kind;
        1142                 :            :     int is_ascii;
        1143                 :            :     Py_ssize_t char_size;
        1144                 :            :     Py_ssize_t struct_size;
        1145                 :            :
        1146                 :    4585040 :     is_ascii = 0;
        1147                 :    4585040 :     struct_size = sizeof(PyCompactUnicodeObject);
        1148         [ +  + ]:    4585040 :     if (maxchar < 128) {
        1149                 :    4584551 :         kind = PyUnicode_1BYTE_KIND;
        1150                 :    4584551 :         char_size = 1;
        1151                 :    4584551 :         is_ascii = 1;
        1152                 :    4584551 :         struct_size = sizeof(PyASCIIObject);
        1153                 :            :     }
        1154         [ +  + ]:        489 :     else if (maxchar < 256) {
        1155                 :        156 :         kind = PyUnicode_1BYTE_KIND;
        1156                 :        156 :         char_size = 1;
        1157                 :            :     }
        1158         [ +  + ]:        333 :     else if (maxchar < 65536) {
        1159                 :        310 :         kind = PyUnicode_2BYTE_KIND;
        1160                 :        310 :         char_size = 2;
        1161                 :            :     }
        1162                 :            :     else {
        1163         [ -  + ]:         23 :         if (maxchar > MAX_UNICODE) {
        1164                 :          0 :             PyErr_SetString(PyExc_SystemError,
        1165                 :            :                             "invalid maximum character passed to PyUnicode_New");
        1166                 :          0 :             return NULL;
        1167                 :            :         }
        1168                 :         23 :         kind = PyUnicode_4BYTE_KIND;
        1169                 :         23 :         char_size = 4;
        1170                 :            :     }
        1171                 :            :
        1172                 :            :     /* Ensure we won't overflow the size. */
        1173         [ -  + ]:    4585040 :     if (size < 0) {
        1174                 :          0 :         PyErr_SetString(PyExc_SystemError,
        1175                 :            :                         "Negative size passed to PyUnicode_New");
        1176                 :          0 :         return NULL;
        1177                 :            :     }
        1178         [ -  + ]:    4585040 :     if (size > ((PY_SSIZE_T_MAX - struct_size) / char_size - 1))
        1179                 :          0 :         return PyErr_NoMemory();
        1180                 :            :
        1181                 :            :     /* Duplicated allocation code from _PyObject_New() instead of a call to
        1182                 :            :      * PyObject_New() so we are able to allocate space for the object and
        1183                 :            :      * it's data buffer.
        1184                 :            :      */
        1185                 :    4585040 :     obj = (PyObject *) PyObject_Malloc(struct_size + (size + 1) * char_size);
        1186         [ -  + ]:    4585040 :     if (obj == NULL) {
        1187                 :          0 :         return PyErr_NoMemory();
        1188                 :            :     }
        1189                 :    4585040 :     _PyObject_Init(obj, &PyUnicode_Type);
        1190                 :            :
        1191                 :    4585040 :     unicode = (PyCompactUnicodeObject *)obj;
        1192         [ +  + ]:    4585040 :     if (is_ascii)
        1193                 :    4584551 :         data = ((PyASCIIObject*)obj) + 1;
        1194                 :            :     else
        1195                 :        489 :         data = unicode + 1;
        1196                 :    4585040 :     _PyUnicode_LENGTH(unicode) = size;
        1197                 :    4585040 :     _PyUnicode_HASH(unicode) = -1;
        1198                 :    4585040 :     _PyUnicode_STATE(unicode).interned = 0;
        1199                 :    4585040 :     _PyUnicode_STATE(unicode).kind = kind;
        1200                 :    4585040 :     _PyUnicode_STATE(unicode).compact = 1;
        1201                 :    4585040 :     _PyUnicode_STATE(unicode).ascii = is_ascii;
        1202         [ +  + ]:    4585040 :     if (is_ascii) {
        1203                 :    4584551 :         ((char*)data)[size] = 0;
        1204                 :            :     }
        1205         [ +  + ]:        489 :     else if (kind == PyUnicode_1BYTE_KIND) {
        1206                 :        156 :         ((char*)data)[size] = 0;
        1207                 :        156 :         unicode->utf8 = NULL;
        1208                 :        156 :         unicode->utf8_length = 0;
        1209                 :            :     }
        1210                 :            :     else {
        1211                 :        333 :         unicode->utf8 = NULL;
        1212                 :        333 :         unicode->utf8_length = 0;
        1213         [ +  + ]:        333 :         if (kind == PyUnicode_2BYTE_KIND)
        1214                 :        310 :             ((Py_UCS2*)data)[size] = 0;
        1215                 :            :         else /* kind == PyUnicode_4BYTE_KIND */
        1216                 :         23 :             ((Py_UCS4*)data)[size] = 0;
        1217                 :            :     }
        1218                 :            : #ifdef Py_DEBUG
        1219                 :            :     unicode_fill_invalid((PyObject*)unicode, 0);
        1220                 :            : #endif
        1221                 :            :     assert(_PyUnicode_CheckConsistency((PyObject*)unicode, 0));
        1222                 :    4585040 :     return obj;
        1223                 :            : }
        1224                 :            :
        1225                 :            : #if SIZEOF_WCHAR_T == 2
        1226                 :            : /* Helper function to convert a 16-bits wchar_t representation to UCS4, this
        1227                 :            :    will decode surrogate pairs, the other conversions are implemented as macros
        1228                 :            :    for efficiency.
        1229                 :            :
        1230                 :            :    This function assumes that unicode can hold one more code point than wstr
        1231                 :            :    characters for a terminating null character. */
        1232                 :            : static void
        1233                 :            : unicode_convert_wchar_to_ucs4(const wchar_t *begin, const wchar_t *end,
        1234                 :            :                               PyObject *unicode)
        1235                 :            : {
        1236                 :            :     const wchar_t *iter;
        1237                 :            :     Py_UCS4 *ucs4_out;
        1238                 :            :
        1239                 :            :     assert(unicode != NULL);
        1240                 :            :     assert(_PyUnicode_CHECK(unicode));
        1241                 :            :     assert(_PyUnicode_KIND(unicode) == PyUnicode_4BYTE_KIND);
        1242                 :            :     ucs4_out = PyUnicode_4BYTE_DATA(unicode);
        1243                 :            :
        1244                 :            :     for (iter = begin; iter < end; ) {
        1245                 :            :         assert(ucs4_out < (PyUnicode_4BYTE_DATA(unicode) +
        1246                 :            :                            _PyUnicode_GET_LENGTH(unicode)));
        1247                 :            :         if (Py_UNICODE_IS_HIGH_SURROGATE(iter[0])
        1248                 :            :             && (iter+1) < end
        1249                 :            :             && Py_UNICODE_IS_LOW_SURROGATE(iter[1]))
        1250                 :            :         {
        1251                 :            :             *ucs4_out++ = Py_UNICODE_JOIN_SURROGATES(iter[0], iter[1]);
        1252                 :            :             iter += 2;
        1253                 :            :         }
        1254                 :            :         else {
        1255                 :            :             *ucs4_out++ = *iter;
        1256                 :            :             iter++;
        1257                 :            :         }
        1258                 :            :     }
        1259                 :            :     assert(ucs4_out == (PyUnicode_4BYTE_DATA(unicode) +
        1260                 :            :                         _PyUnicode_GET_LENGTH(unicode)));
        1261                 :            :
        1262                 :            : }
        1263                 :            : #endif
        1264                 :            :
        1265                 :            : static int
        1266                 :        414 : unicode_check_modifiable(PyObject *unicode)
        1267                 :            : {
        1268         [ -  + ]:        414 :     if (!unicode_modifiable(unicode)) {
        1269                 :          0 :         PyErr_SetString(PyExc_SystemError,
        1270                 :            :                         "Cannot modify a string currently used");
        1271                 :          0 :         return -1;
        1272                 :            :     }
        1273                 :        414 :     return 0;
        1274                 :            : }
        1275                 :            :
        1276                 :            : static int
        1277                 :     751770 : _copy_characters(PyObject *to, Py_ssize_t to_start,
        1278                 :            :                  PyObject *from, Py_ssize_t from_start,
        1279                 :            :                  Py_ssize_t how_many, int check_maxchar)
        1280                 :            : {
        1281                 :            :     int from_kind, to_kind;
        1282                 :            :     const void *from_data;
        1283                 :            :     void *to_data;
        1284                 :            :
        1285                 :            :     assert(0 <= how_many);
        1286                 :            :     assert(0 <= from_start);
        1287                 :            :     assert(0 <= to_start);
        1288                 :            :     assert(PyUnicode_Check(from));
        1289                 :            :     assert(from_start + how_many <= PyUnicode_GET_LENGTH(from));
        1290                 :            :
        1291                 :            :     assert(PyUnicode_Check(to));
        1292                 :            :     assert(to_start + how_many <= PyUnicode_GET_LENGTH(to));
        1293                 :            :
        1294         [ +  + ]:     751770 :     if (how_many == 0)
        1295                 :        495 :         return 0;
        1296                 :            :
        1297                 :     751275 :     from_kind = PyUnicode_KIND(from);
        1298                 :     751275 :     from_data = PyUnicode_DATA(from);
        1299                 :     751275 :     to_kind = PyUnicode_KIND(to);
        1300                 :     751275 :     to_data = PyUnicode_DATA(to);
        1301                 :            :
        1302                 :            : #ifdef Py_DEBUG
        1303                 :            :     if (!check_maxchar
        1304                 :            :         && PyUnicode_MAX_CHAR_VALUE(from) > PyUnicode_MAX_CHAR_VALUE(to))
        1305                 :            :     {
        1306                 :            :         Py_UCS4 to_maxchar = PyUnicode_MAX_CHAR_VALUE(to);
        1307                 :            :         Py_UCS4 ch;
        1308                 :            :         Py_ssize_t i;
        1309                 :            :         for (i=0; i < how_many; i++) {
        1310                 :            :             ch = PyUnicode_READ(from_kind, from_data, from_start + i);
        1311                 :            :             assert(ch <= to_maxchar);
        1312                 :            :         }
        1313                 :            :     }
        1314                 :            : #endif
        1315                 :            :
        1316         [ +  + ]:     751275 :     if (from_kind == to_kind) {
        1317         [ +  + ]:     750789 :         if (check_maxchar
        1318   [ -  +  -  - ]:        414 :             && !PyUnicode_IS_ASCII(from) && PyUnicode_IS_ASCII(to))
        1319                 :            :         {
        1320                 :            :             /* Writing Latin-1 characters into an ASCII string requires to
        1321                 :            :                check that all written characters are pure ASCII */
        1322                 :            :             Py_UCS4 max_char;
        1323                 :          0 :             max_char = ucs1lib_find_max_char(from_data,
        1324                 :            :                                              (const Py_UCS1*)from_data + how_many);
        1325         [ #  # ]:          0 :             if (max_char >= 128)
        1326                 :          0 :                 return -1;
        1327                 :            :         }
        1328                 :     750789 :         memcpy((char*)to_data + to_kind * to_start,
        1329                 :     750789 :                   (const char*)from_data + from_kind * from_start,
        1330                 :     750789 :                   to_kind * how_many);
        1331                 :            :     }
        1332         [ +  + ]:        486 :     else if (from_kind == PyUnicode_1BYTE_KIND
        1333         [ +  + ]:        484 :              && to_kind == PyUnicode_2BYTE_KIND)
        1334                 :            :     {
        1335   [ +  +  +  + ]:      65047 :         _PyUnicode_CONVERT_BYTES(
        1336                 :            :             Py_UCS1, Py_UCS2,
        1337                 :            :             PyUnicode_1BYTE_DATA(from) + from_start,
        1338                 :            :             PyUnicode_1BYTE_DATA(from) + from_start + how_many,
        1339                 :            :             PyUnicode_2BYTE_DATA(to) + to_start
        1340                 :            :             );
        1341                 :            :     }
        1342         [ +  + ]:        102 :     else if (from_kind == PyUnicode_1BYTE_KIND
        1343         [ +  - ]:        100 :              && to_kind == PyUnicode_4BYTE_KIND)
        1344                 :            :     {
        1345   [ +  +  +  + ]:       1112 :         _PyUnicode_CONVERT_BYTES(
        1346                 :            :             Py_UCS1, Py_UCS4,
        1347                 :            :             PyUnicode_1BYTE_DATA(from) + from_start,
        1348                 :            :             PyUnicode_1BYTE_DATA(from) + from_start + how_many,
        1349                 :            :             PyUnicode_4BYTE_DATA(to) + to_start
        1350                 :            :             );
        1351                 :            :     }
        1352         [ +  - ]:          2 :     else if (from_kind == PyUnicode_2BYTE_KIND
        1353         [ +  - ]:          2 :              && to_kind == PyUnicode_4BYTE_KIND)
        1354                 :            :     {
        1355   [ +  +  +  + ]:        554 :         _PyUnicode_CONVERT_BYTES(
        1356                 :            :             Py_UCS2, Py_UCS4,
        1357                 :            :             PyUnicode_2BYTE_DATA(from) + from_start,
        1358                 :            :             PyUnicode_2BYTE_DATA(from) + from_start + how_many,
        1359                 :            :             PyUnicode_4BYTE_DATA(to) + to_start
        1360                 :            :             );
        1361                 :            :     }
        1362                 :            :     else {
        1363                 :            :         assert (PyUnicode_MAX_CHAR_VALUE(from) > PyUnicode_MAX_CHAR_VALUE(to));
        1364                 :            :
        1365         [ #  # ]:          0 :         if (!check_maxchar) {
        1366         [ #  # ]:          0 :             if (from_kind == PyUnicode_2BYTE_KIND
        1367         [ #  # ]:          0 :                 && to_kind == PyUnicode_1BYTE_KIND)
        1368                 :            :             {
        1369   [ #  #  #  # ]:          0 :                 _PyUnicode_CONVERT_BYTES(
        1370                 :            :                     Py_UCS2, Py_UCS1,
        1371                 :            :                     PyUnicode_2BYTE_DATA(from) + from_start,
        1372                 :            :                     PyUnicode_2BYTE_DATA(from) + from_start + how_many,
        1373                 :            :                     PyUnicode_1BYTE_DATA(to) + to_start
        1374                 :            :                     );
        1375                 :            :             }
        1376         [ #  # ]:          0 :             else if (from_kind == PyUnicode_4BYTE_KIND
        1377         [ #  # ]:          0 :                      && to_kind == PyUnicode_1BYTE_KIND)
        1378                 :            :             {
        1379   [ #  #  #  # ]:          0 :                 _PyUnicode_CONVERT_BYTES(
        1380                 :            :                     Py_UCS4, Py_UCS1,
        1381                 :            :                     PyUnicode_4BYTE_DATA(from) + from_start,
        1382                 :            :                     PyUnicode_4BYTE_DATA(from) + from_start + how_many,
        1383                 :            :                     PyUnicode_1BYTE_DATA(to) + to_start
        1384                 :            :                     );
        1385                 :            :             }
        1386         [ #  # ]:          0 :             else if (from_kind == PyUnicode_4BYTE_KIND
        1387         [ #  # ]:          0 :                      && to_kind == PyUnicode_2BYTE_KIND)
        1388                 :            :             {
        1389   [ #  #  #  # ]:          0 :                 _PyUnicode_CONVERT_BYTES(
        1390                 :            :                     Py_UCS4, Py_UCS2,
        1391                 :            :                     PyUnicode_4BYTE_DATA(from) + from_start,
        1392                 :            :                     PyUnicode_4BYTE_DATA(from) + from_start + how_many,
        1393                 :            :                     PyUnicode_2BYTE_DATA(to) + to_start
        1394                 :            :                     );
        1395                 :            :             }
        1396                 :            :             else {
        1397                 :          0 :                 Py_UNREACHABLE();
        1398                 :            :             }
        1399                 :            :         }
        1400                 :            :         else {
        1401                 :          0 :             const Py_UCS4 to_maxchar = PyUnicode_MAX_CHAR_VALUE(to);
        1402                 :            :             Py_UCS4 ch;
        1403                 :            :             Py_ssize_t i;
        1404                 :            :
        1405         [ #  # ]:          0 :             for (i=0; i < how_many; i++) {
        1406                 :          0 :                 ch = PyUnicode_READ(from_kind, from_data, from_start + i);
        1407         [ #  # ]:          0 :                 if (ch > to_maxchar)
        1408                 :          0 :                     return -1;
        1409                 :          0 :                 PyUnicode_WRITE(to_kind, to_data, to_start + i, ch);
        1410                 :            :             }
        1411                 :            :         }
        1412                 :            :     }
        1413                 :     751275 :     return 0;
        1414                 :            : }
        1415                 :            :
        1416                 :            : void
        1417                 :     751356 : _PyUnicode_FastCopyCharacters(
        1418                 :            :     PyObject *to, Py_ssize_t to_start,
        1419                 :            :     PyObject *from, Py_ssize_t from_start, Py_ssize_t how_many)
        1420                 :            : {
        1421                 :     751356 :     (void)_copy_characters(to, to_start, from, from_start, how_many, 0);
        1422                 :     751356 : }
        1423                 :            :
        1424                 :            : Py_ssize_t
        1425                 :        414 : PyUnicode_CopyCharacters(PyObject *to, Py_ssize_t to_start,
        1426                 :            :                          PyObject *from, Py_ssize_t from_start,
        1427                 :            :                          Py_ssize_t how_many)
        1428                 :            : {
        1429                 :            :     int err;
        1430                 :            :
        1431   [ +  -  -  + ]:        414 :     if (!PyUnicode_Check(from) || !PyUnicode_Check(to)) {
        1432                 :          0 :         PyErr_BadInternalCall();
        1433                 :          0 :         return -1;
        1434                 :            :     }
        1435                 :            :
        1436         [ -  + ]:        414 :     if ((size_t)from_start > (size_t)PyUnicode_GET_LENGTH(from)) {
        1437                 :          0 :         PyErr_SetString(PyExc_IndexError, "string index out of range");
        1438                 :          0 :         return -1;
        1439                 :            :     }
        1440         [ -  + ]:        414 :     if ((size_t)to_start > (size_t)PyUnicode_GET_LENGTH(to)) {
        1441                 :          0 :         PyErr_SetString(PyExc_IndexError, "string index out of range");
        1442                 :          0 :         return -1;
        1443                 :            :     }
        1444         [ -  + ]:        414 :     if (how_many < 0) {
        1445                 :          0 :         PyErr_SetString(PyExc_SystemError, "how_many cannot be negative");
        1446                 :          0 :         return -1;
        1447                 :            :     }
        1448         [ +  - ]:        414 :     how_many = Py_MIN(PyUnicode_GET_LENGTH(from)-from_start, how_many);
        1449         [ -  + ]:        414 :     if (to_start + how_many > PyUnicode_GET_LENGTH(to)) {
        1450                 :          0 :         PyErr_Format(PyExc_SystemError,
        1451                 :            :                      "Cannot write %zi characters at %zi "
        1452                 :            :                      "in a string of %zi characters",
        1453                 :            :                      how_many, to_start, PyUnicode_GET_LENGTH(to));
        1454                 :          0 :         return -1;
        1455                 :            :     }
        1456                 :            :
        1457         [ -  + ]:        414 :     if (how_many == 0)
        1458                 :          0 :         return 0;
        1459                 :            :
        1460         [ -  + ]:        414 :     if (unicode_check_modifiable(to))
        1461                 :          0 :         return -1;
        1462                 :            :
        1463                 :        414 :     err = _copy_characters(to, to_start, from, from_start, how_many, 1);
        1464         [ -  + ]:        414 :     if (err) {
        1465                 :          0 :         PyErr_Format(PyExc_SystemError,
        1466                 :            :                      "Cannot copy %s characters "
        1467                 :            :                      "into a string of %s characters",
        1468                 :            :                      unicode_kind_name(from),
        1469                 :            :                      unicode_kind_name(to));
        1470                 :          0 :         return -1;
        1471                 :            :     }
        1472                 :        414 :     return how_many;
        1473                 :            : }
        1474                 :            :
        1475                 :            : /* Find the maximum code point and count the number of surrogate pairs so a
        1476                 :            :    correct string length can be computed before converting a string to UCS4.
        1477                 :            :    This function counts single surrogates as a character and not as a pair.
        1478                 :            :
        1479                 :            :    Return 0 on success, or -1 on error. */
        1480                 :            : static int
        1481                 :      10829 : find_maxchar_surrogates(const wchar_t *begin, const wchar_t *end,
        1482                 :            :                         Py_UCS4 *maxchar, Py_ssize_t *num_surrogates)
        1483                 :            : {
        1484                 :            :     const wchar_t *iter;
        1485                 :            :     Py_UCS4 ch;
        1486                 :            :
        1487                 :            :     assert(num_surrogates != NULL && maxchar != NULL);
        1488                 :      10829 :     *num_surrogates = 0;
        1489                 :      10829 :     *maxchar = 0;
        1490                 :            :
        1491         [ +  + ]:     159272 :     for (iter = begin; iter < end; ) {
        1492                 :            : #if SIZEOF_WCHAR_T == 2
        1493                 :            :         if (Py_UNICODE_IS_HIGH_SURROGATE(iter[0])
        1494                 :            :             && (iter+1) < end
        1495                 :            :             && Py_UNICODE_IS_LOW_SURROGATE(iter[1]))
        1496                 :            :         {
        1497                 :            :             ch = Py_UNICODE_JOIN_SURROGATES(iter[0], iter[1]);
        1498                 :            :             ++(*num_surrogates);
        1499                 :            :             iter += 2;
        1500                 :            :         }
        1501                 :            :         else
        1502                 :            : #endif
        1503                 :            :         {
        1504                 :     148443 :             ch = *iter;
        1505                 :     148443 :             iter++;
        1506                 :            :         }
        1507         [ +  + ]:     148443 :         if (ch > *maxchar) {
        1508                 :      36353 :             *maxchar = ch;
        1509         [ -  + ]:      36353 :             if (*maxchar > MAX_UNICODE) {
        1510                 :          0 :                 PyErr_Format(PyExc_ValueError,
        1511                 :            :                              "character U+%x is not in range [U+0000; U+%x]",
        1512                 :            :                              ch, MAX_UNICODE);
        1513                 :          0 :                 return -1;
        1514                 :            :             }
        1515                 :            :         }
        1516                 :            :     }
        1517                 :      10829 :     return 0;
        1518                 :            : }
        1519                 :            :
        1520                 :            : static void
        1521                 :    4578950 : unicode_dealloc(PyObject *unicode)
        1522                 :            : {
        1523                 :            : #ifdef Py_DEBUG
        1524                 :            :     if (!unicode_is_finalizing() && unicode_is_singleton(unicode)) {
        1525                 :            :         _Py_FatalRefcountError("deallocating an Unicode singleton");
        1526                 :            :     }
        1527                 :            : #endif
        1528                 :    4578950 :     PyObject *interned = get_interned_dict();
        1529         [ +  + ]:    4578950 :     if (PyUnicode_CHECK_INTERNED(unicode)) {
        1530                 :            :         /* Revive the dead object temporarily. PyDict_DelItem() removes two
        1531                 :            :            references (key and value) which were ignored by
        1532                 :            :            PyUnicode_InternInPlace(). Use refcnt=3 rather than refcnt=2
        1533                 :            :            to prevent calling unicode_dealloc() again. Adjust refcnt after
        1534                 :            :            PyDict_DelItem(). */
        1535                 :            :         assert(Py_REFCNT(unicode) == 0);
        1536                 :      91891 :         Py_SET_REFCNT(unicode, 3);
        1537         [ -  + ]:      91891 :         if (PyDict_DelItem(interned, unicode) != 0) {
        1538                 :          0 :             _PyErr_WriteUnraisableMsg("deletion of interned string failed",
        1539                 :            :                                       NULL);
        1540                 :            :         }
        1541                 :            :         assert(Py_REFCNT(unicode) == 1);
        1542                 :      91891 :         Py_SET_REFCNT(unicode, 0);
        1543                 :            :     }
        1544                 :            :
        1545   [ +  +  +  +  :    4578950 :     if (_PyUnicode_HAS_UTF8_MEMORY(unicode)) {
                       -  + ]
        1546                 :          0 :         PyObject_Free(_PyUnicode_UTF8(unicode));
        1547                 :            :     }
        1548   [ +  +  +  - ]:    4578950 :     if (!PyUnicode_IS_COMPACT(unicode) && _PyUnicode_DATA_ANY(unicode)) {
        1549                 :         28 :         PyObject_Free(_PyUnicode_DATA_ANY(unicode));
        1550                 :            :     }
        1551                 :            :
        1552                 :    4578950 :     Py_TYPE(unicode)->tp_free(unicode);
        1553                 :    4578950 : }
        1554                 :            :
        1555                 :            : #ifdef Py_DEBUG
        1556                 :            : static int
        1557                 :            : unicode_is_singleton(PyObject *unicode)
        1558                 :            : {
        1559                 :            :     if (unicode == &_Py_STR(empty)) {
        1560                 :            :         return 1;
        1561                 :            :     }
        1562                 :            :
        1563                 :            :     PyASCIIObject *ascii = _PyASCIIObject_CAST(unicode);
        1564                 :            :     if (ascii->length == 1) {
        1565                 :            :         Py_UCS4 ch = PyUnicode_READ_CHAR(unicode, 0);
        1566                 :            :         if (ch < 256 && LATIN1(ch) == unicode) {
        1567                 :            :             return 1;
        1568                 :            :         }
        1569                 :            :     }
        1570                 :            :     return 0;
        1571                 :            : }
        1572                 :            : #endif
        1573                 :            :
        1574                 :            : static int
        1575                 :      14401 : unicode_modifiable(PyObject *unicode)
        1576                 :            : {
        1577                 :            :     assert(_PyUnicode_CHECK(unicode));
        1578         [ +  + ]:      14401 :     if (Py_REFCNT(unicode) != 1)
        1579                 :       1753 :         return 0;
        1580         [ -  + ]:      12648 :     if (_PyUnicode_HASH(unicode) != -1)
        1581                 :          0 :         return 0;
        1582         [ -  + ]:      12648 :     if (PyUnicode_CHECK_INTERNED(unicode))
        1583                 :          0 :         return 0;
        1584         [ -  + ]:      12648 :     if (!PyUnicode_CheckExact(unicode))
        1585                 :          0 :         return 0;
        1586                 :            : #ifdef Py_DEBUG
        1587                 :            :     /* singleton refcount is greater than 1 */
        1588                 :            :     assert(!unicode_is_singleton(unicode));
        1589                 :            : #endif
        1590                 :      12648 :     return 1;
        1591                 :            : }
        1592                 :            :
        1593                 :            : static int
        1594                 :       6116 : unicode_resize(PyObject **p_unicode, Py_ssize_t length)
        1595                 :            : {
        1596                 :            :     PyObject *unicode;
        1597                 :            :     Py_ssize_t old_length;
        1598                 :            :
        1599                 :            :     assert(p_unicode != NULL);
        1600                 :       6116 :     unicode = *p_unicode;
        1601                 :            :
        1602                 :            :     assert(unicode != NULL);
        1603                 :            :     assert(PyUnicode_Check(unicode));
        1604                 :            :     assert(0 <= length);
        1605                 :            :
        1606                 :       6116 :     old_length = PyUnicode_GET_LENGTH(unicode);
        1607         [ -  + ]:       6116 :     if (old_length == length)
        1608                 :          0 :         return 0;
        1609                 :            :
        1610         [ -  + ]:       6116 :     if (length == 0) {
        1611                 :          0 :         PyObject *empty = unicode_new_empty();
        1612                 :          0 :         Py_SETREF(*p_unicode, empty);
        1613                 :          0 :         return 0;
        1614                 :            :     }
        1615                 :            :
        1616         [ -  + ]:       6116 :     if (!unicode_modifiable(unicode)) {
        1617                 :          0 :         PyObject *copy = resize_copy(unicode, length);
        1618         [ #  # ]:          0 :         if (copy == NULL)
        1619                 :          0 :             return -1;
        1620                 :          0 :         Py_SETREF(*p_unicode, copy);
        1621                 :          0 :         return 0;
        1622                 :            :     }
        1623                 :            :
        1624         [ +  - ]:       6116 :     if (PyUnicode_IS_COMPACT(unicode)) {
        1625                 :       6116 :         PyObject *new_unicode = resize_compact(unicode, length);
        1626         [ -  + ]:       6116 :         if (new_unicode == NULL)
        1627                 :          0 :             return -1;
        1628                 :       6116 :         *p_unicode = new_unicode;
        1629                 :       6116 :         return 0;
        1630                 :            :     }
        1631                 :          0 :     return resize_inplace(unicode, length);
        1632                 :            : }
        1633                 :            :
        1634                 :            : int
        1635                 :          0 : PyUnicode_Resize(PyObject **p_unicode, Py_ssize_t length)
        1636                 :            : {
        1637                 :            :     PyObject *unicode;
        1638         [ #  # ]:          0 :     if (p_unicode == NULL) {
        1639                 :          0 :         PyErr_BadInternalCall();
        1640                 :          0 :         return -1;
        1641                 :            :     }
        1642                 :          0 :     unicode = *p_unicode;
        1643   [ #  #  #  #  :          0 :     if (unicode == NULL || !PyUnicode_Check(unicode) || length < 0)
                       #  # ]
        1644                 :            :     {
        1645                 :          0 :         PyErr_BadInternalCall();
        1646                 :          0 :         return -1;
        1647                 :            :     }
        1648                 :          0 :     return unicode_resize(p_unicode, length);
        1649                 :            : }
        1650                 :            :
        1651                 :            : /* Copy an ASCII or latin1 char* string into a Python Unicode string.
        1652                 :            :
        1653                 :            :    WARNING: The function doesn't copy the terminating null character and
        1654                 :            :    doesn't check the maximum character (may write a latin1 character in an
        1655                 :            :    ASCII string). */
        1656                 :            : static void
        1657                 :          0 : unicode_write_cstr(PyObject *unicode, Py_ssize_t index,
        1658                 :            :                    const char *str, Py_ssize_t len)
        1659                 :            : {
        1660                 :          0 :     int kind = PyUnicode_KIND(unicode);
        1661                 :          0 :     const void *data = PyUnicode_DATA(unicode);
        1662                 :          0 :     const char *end = str + len;
        1663                 :            :
        1664                 :            :     assert(index + len <= PyUnicode_GET_LENGTH(unicode));
        1665   [ #  #  #  # ]:          0 :     switch (kind) {
        1666                 :          0 :     case PyUnicode_1BYTE_KIND: {
        1667                 :            : #ifdef Py_DEBUG
        1668                 :            :         if (PyUnicode_IS_ASCII(unicode)) {
        1669                 :            :             Py_UCS4 maxchar = ucs1lib_find_max_char(
        1670                 :            :                 (const Py_UCS1*)str,
        1671                 :            :                 (const Py_UCS1*)str + len);
        1672                 :            :             assert(maxchar < 128);
        1673                 :            :         }
        1674                 :            : #endif
        1675                 :          0 :         memcpy((char *) data + index, str, len);
        1676                 :          0 :         break;
        1677                 :            :     }
        1678                 :          0 :     case PyUnicode_2BYTE_KIND: {
        1679                 :          0 :         Py_UCS2 *start = (Py_UCS2 *)data + index;
        1680                 :          0 :         Py_UCS2 *ucs2 = start;
        1681                 :            :
        1682         [ #  # ]:          0 :         for (; str < end; ++ucs2, ++str)
        1683                 :          0 :             *ucs2 = (Py_UCS2)*str;
        1684                 :            :
        1685                 :            :         assert((ucs2 - start) <= PyUnicode_GET_LENGTH(unicode));
        1686                 :          0 :         break;
        1687                 :            :     }
        1688                 :          0 :     case PyUnicode_4BYTE_KIND: {
        1689                 :          0 :         Py_UCS4 *start = (Py_UCS4 *)data + index;
        1690                 :          0 :         Py_UCS4 *ucs4 = start;
        1691                 :            :
        1692         [ #  # ]:          0 :         for (; str < end; ++ucs4, ++str)
        1693                 :          0 :             *ucs4 = (Py_UCS4)*str;
        1694                 :            :
        1695                 :            :         assert((ucs4 - start) <= PyUnicode_GET_LENGTH(unicode));
        1696                 :          0 :         break;
        1697                 :            :     }
        1698                 :          0 :     default:
        1699                 :          0 :         Py_UNREACHABLE();
        1700                 :            :     }
        1701                 :          0 : }
        1702                 :            :
        1703                 :            : static PyObject*
        1704                 :     403251 : get_latin1_char(Py_UCS1 ch)
        1705                 :            : {
        1706         [ +  + ]:     403251 :     return Py_NewRef(LATIN1(ch));
        1707                 :            : }
        1708                 :            :
        1709                 :            : static PyObject*
        1710                 :     291041 : unicode_char(Py_UCS4 ch)
        1711                 :            : {
        1712                 :            :     PyObject *unicode;
        1713                 :            :
        1714                 :            :     assert(ch <= MAX_UNICODE);
        1715                 :            :
        1716         [ +  + ]:     291041 :     if (ch < 256) {
        1717                 :     290883 :         return get_latin1_char(ch);
        1718                 :            :     }
        1719                 :            :
        1720                 :        158 :     unicode = PyUnicode_New(1, ch);
        1721         [ -  + ]:        158 :     if (unicode == NULL)
        1722                 :          0 :         return NULL;
        1723                 :            :
        1724                 :            :     assert(PyUnicode_KIND(unicode) != PyUnicode_1BYTE_KIND);
        1725         [ +  + ]:        158 :     if (PyUnicode_KIND(unicode) == PyUnicode_2BYTE_KIND) {
        1726                 :        156 :         PyUnicode_2BYTE_DATA(unicode)[0] = (Py_UCS2)ch;
        1727                 :            :     } else {
        1728                 :            :         assert(PyUnicode_KIND(unicode) == PyUnicode_4BYTE_KIND);
        1729                 :          2 :         PyUnicode_4BYTE_DATA(unicode)[0] = ch;
        1730                 :            :     }
        1731                 :            :     assert(_PyUnicode_CheckConsistency(unicode, 1));
        1732                 :        158 :     return unicode;
        1733                 :            : }
        1734                 :            :
        1735                 :            : PyObject *
        1736                 :      10850 : PyUnicode_FromWideChar(const wchar_t *u, Py_ssize_t size)
        1737                 :            : {
        1738                 :            :     PyObject *unicode;
        1739                 :      10850 :     Py_UCS4 maxchar = 0;
        1740                 :            :     Py_ssize_t num_surrogates;
        1741                 :            :
        1742   [ -  +  -  - ]:      10850 :     if (u == NULL && size != 0) {
        1743                 :          0 :         PyErr_BadInternalCall();
        1744                 :          0 :         return NULL;
        1745                 :            :     }
        1746                 :            :
        1747         [ +  + ]:      10850 :     if (size == -1) {
        1748                 :       1783 :         size = wcslen(u);
        1749                 :            :     }
        1750                 :            :
        1751                 :            :     /* If the Unicode data is known at construction time, we can apply
        1752                 :            :        some optimizations which share commonly used objects. */
        1753                 :            :
        1754                 :            :     /* Optimization for empty strings */
        1755         [ +  + ]:      10850 :     if (size == 0)
        1756                 :          1 :         _Py_RETURN_UNICODE_EMPTY();
        1757                 :            :
        1758                 :            : #ifdef HAVE_NON_UNICODE_WCHAR_T_REPRESENTATION
        1759                 :            :     /* Oracle Solaris uses non-Unicode internal wchar_t form for
        1760                 :            :        non-Unicode locales and hence needs conversion to UCS-4 first. */
        1761                 :            :     if (_Py_LocaleUsesNonUnicodeWchar()) {
        1762                 :            :         wchar_t* converted = _Py_DecodeNonUnicodeWchar(u, size);
        1763                 :            :         if (!converted) {
        1764                 :            :             return NULL;
        1765                 :            :         }
        1766                 :            :         PyObject *unicode = _PyUnicode_FromUCS4(converted, size);
        1767                 :            :         PyMem_Free(converted);
        1768                 :            :         return unicode;
        1769                 :            :     }
        1770                 :            : #endif
        1771                 :            :
        1772                 :            :     /* Single character Unicode objects in the Latin-1 range are
        1773                 :            :        shared when using this constructor */
        1774   [ +  +  +  - ]:      10849 :     if (size == 1 && (Py_UCS4)*u < 256)
        1775                 :         20 :         return get_latin1_char((unsigned char)*u);
        1776                 :            :
        1777                 :            :     /* If not empty and not single character, copy the Unicode data
        1778                 :            :        into the new object */
        1779         [ -  + ]:      10829 :     if (find_maxchar_surrogates(u, u + size,
        1780                 :            :                                 &maxchar, &num_surrogates) == -1)
        1781                 :          0 :         return NULL;
        1782                 :            :
        1783                 :      10829 :     unicode = PyUnicode_New(size - num_surrogates, maxchar);
        1784         [ -  + ]:      10829 :     if (!unicode)
        1785                 :          0 :         return NULL;
        1786                 :            :
        1787   [ +  -  -  - ]:      10829 :     switch (PyUnicode_KIND(unicode)) {
        1788                 :      10829 :     case PyUnicode_1BYTE_KIND:
        1789   [ +  +  +  + ]:      59081 :         _PyUnicode_CONVERT_BYTES(Py_UNICODE, unsigned char,
        1790                 :            :                                 u, u + size, PyUnicode_1BYTE_DATA(unicode));
        1791                 :      10829 :         break;
        1792                 :          0 :     case PyUnicode_2BYTE_KIND:
        1793                 :            : #if Py_UNICODE_SIZE == 2
        1794                 :            :         memcpy(PyUnicode_2BYTE_DATA(unicode), u, size * 2);
        1795                 :            : #else
        1796   [ #  #  #  # ]:          0 :         _PyUnicode_CONVERT_BYTES(Py_UNICODE, Py_UCS2,
        1797                 :            :                                 u, u + size, PyUnicode_2BYTE_DATA(unicode));
        1798                 :            : #endif
        1799                 :          0 :         break;
        1800                 :          0 :     case PyUnicode_4BYTE_KIND:
        1801                 :            : #if SIZEOF_WCHAR_T == 2
        1802                 :            :         /* This is the only case which has to process surrogates, thus
        1803                 :            :            a simple copy loop is not enough and we need a function. */
        1804                 :            :         unicode_convert_wchar_to_ucs4(u, u + size, unicode);
        1805                 :            : #else
        1806                 :            :         assert(num_surrogates == 0);
        1807                 :          0 :         memcpy(PyUnicode_4BYTE_DATA(unicode), u, size * 4);
        1808                 :            : #endif
        1809                 :          0 :         break;
        1810                 :          0 :     default:
        1811                 :          0 :         Py_UNREACHABLE();
        1812                 :            :     }
        1813                 :            :
        1814                 :      10829 :     return unicode_result(unicode);
        1815                 :            : }
        1816                 :            :
        1817                 :            : PyObject *
        1818                 :      12532 : PyUnicode_FromStringAndSize(const char *u, Py_ssize_t size)
        1819                 :            : {
        1820         [ -  + ]:      12532 :     if (size < 0) {
        1821                 :          0 :         PyErr_SetString(PyExc_SystemError,
        1822                 :            :                         "Negative size passed to PyUnicode_FromStringAndSize");
        1823                 :          0 :         return NULL;
        1824                 :            :     }
        1825         [ +  + ]:      12532 :     if (u != NULL) {
        1826                 :      11928 :         return PyUnicode_DecodeUTF8Stateful(u, size, NULL, NULL);
        1827                 :            :     }
        1828         [ -  + ]:        604 :     if (size > 0) {
        1829                 :          0 :         PyErr_SetString(PyExc_SystemError,
        1830                 :            :             "NULL string with positive size with NULL passed to PyUnicode_FromStringAndSize");
        1831                 :          0 :         return NULL;
        1832                 :            :     }
        1833                 :        604 :     return unicode_new_empty();
        1834                 :            : }
        1835                 :            :
        1836                 :            : PyObject *
        1837                 :    1600203 : PyUnicode_FromString(const char *u)
        1838                 :            : {
        1839                 :    1600203 :     size_t size = strlen(u);
        1840         [ -  + ]:    1600203 :     if (size > PY_SSIZE_T_MAX) {
        1841                 :          0 :         PyErr_SetString(PyExc_OverflowError, "input too long");
        1842                 :          0 :         return NULL;
        1843                 :            :     }
        1844                 :    1600203 :     return PyUnicode_DecodeUTF8Stateful(u, (Py_ssize_t)size, NULL, NULL);
        1845                 :            : }
        1846                 :            :
        1847                 :            :
        1848                 :            : PyObject *
        1849                 :          0 : _PyUnicode_FromId(_Py_Identifier *id)
        1850                 :            : {
        1851                 :          0 :     PyInterpreterState *interp = _PyInterpreterState_GET();
        1852                 :          0 :     struct _Py_unicode_ids *ids = &interp->unicode.ids;
        1853                 :            :
        1854                 :          0 :     Py_ssize_t index = _Py_atomic_size_get(&id->index);
        1855         [ #  # ]:          0 :     if (index < 0) {
        1856                 :          0 :         struct _Py_unicode_runtime_ids *rt_ids = &interp->runtime->unicode_state.ids;
        1857                 :            :
        1858                 :          0 :         PyThread_acquire_lock(rt_ids->lock, WAIT_LOCK);
        1859                 :            :         // Check again to detect concurrent access. Another thread can have
        1860                 :            :         // initialized the index while this thread waited for the lock.
        1861                 :          0 :         index = _Py_atomic_size_get(&id->index);
        1862         [ #  # ]:          0 :         if (index < 0) {
        1863                 :            :             assert(rt_ids->next_index < PY_SSIZE_T_MAX);
        1864                 :          0 :             index = rt_ids->next_index;
        1865                 :          0 :             rt_ids->next_index++;
        1866                 :          0 :             _Py_atomic_size_set(&id->index, index);
        1867                 :            :         }
        1868                 :          0 :         PyThread_release_lock(rt_ids->lock);
        1869                 :            :     }
        1870                 :            :     assert(index >= 0);
        1871                 :            :
        1872                 :            :     PyObject *obj;
        1873         [ #  # ]:          0 :     if (index < ids->size) {
        1874                 :          0 :         obj = ids->array[index];
        1875         [ #  # ]:          0 :         if (obj) {
        1876                 :            :             // Return a borrowed reference
        1877                 :          0 :             return obj;
        1878                 :            :         }
        1879                 :            :     }
        1880                 :            :
        1881                 :          0 :     obj = PyUnicode_DecodeUTF8Stateful(id->string, strlen(id->string),
        1882                 :            :                                        NULL, NULL);
        1883         [ #  # ]:          0 :     if (!obj) {
        1884                 :          0 :         return NULL;
        1885                 :            :     }
        1886                 :          0 :     PyUnicode_InternInPlace(&obj);
        1887                 :            :
        1888         [ #  # ]:          0 :     if (index >= ids->size) {
        1889                 :            :         // Overallocate to reduce the number of realloc
        1890                 :          0 :         Py_ssize_t new_size = Py_MAX(index * 2, 16);
        1891                 :          0 :         Py_ssize_t item_size = sizeof(ids->array[0]);
        1892                 :          0 :         PyObject **new_array = PyMem_Realloc(ids->array, new_size * item_size);
        1893         [ #  # ]:          0 :         if (new_array == NULL) {
        1894                 :          0 :             PyErr_NoMemory();
        1895                 :          0 :             return NULL;
        1896                 :            :         }
        1897                 :          0 :         memset(&new_array[ids->size], 0, (new_size - ids->size) * item_size);
        1898                 :          0 :         ids->array = new_array;
        1899                 :          0 :         ids->size = new_size;
        1900                 :            :     }
        1901                 :            :
        1902                 :            :     // The array stores a strong reference
        1903                 :          0 :     ids->array[index] = obj;
        1904                 :            :
        1905                 :            :     // Return a borrowed reference
        1906                 :          0 :     return obj;
        1907                 :            : }
        1908                 :            :
        1909                 :            :
        1910                 :            : static void
        1911                 :         25 : unicode_clear_identifiers(struct _Py_unicode_state *state)
        1912                 :            : {
        1913                 :         25 :     struct _Py_unicode_ids *ids = &state->ids;
        1914         [ -  + ]:         25 :     for (Py_ssize_t i=0; i < ids->size; i++) {
        1915                 :          0 :         Py_XDECREF(ids->array[i]);
        1916                 :            :     }
        1917                 :         25 :     ids->size = 0;
        1918                 :         25 :     PyMem_Free(ids->array);
        1919                 :         25 :     ids->array = NULL;
        1920                 :            :     // Don't reset _PyRuntime next_index: _Py_Identifier.id remains valid
        1921                 :            :     // after Py_Finalize().
        1922                 :         25 : }
        1923                 :            :
        1924                 :            :
        1925                 :            : /* Internal function, doesn't check maximum character */
        1926                 :            :
        1927                 :            : PyObject*
        1928                 :     797174 : _PyUnicode_FromASCII(const char *buffer, Py_ssize_t size)
        1929                 :            : {
        1930                 :     797174 :     const unsigned char *s = (const unsigned char *)buffer;
        1931                 :            :     PyObject *unicode;
        1932         [ +  + ]:     797174 :     if (size == 1) {
        1933                 :            : #ifdef Py_DEBUG
        1934                 :            :         assert((unsigned char)s[0] < 128);
        1935                 :            : #endif
        1936                 :      76295 :         return get_latin1_char(s[0]);
        1937                 :            :     }
        1938                 :     720879 :     unicode = PyUnicode_New(size, 127);
        1939         [ -  + ]:     720879 :     if (!unicode)
        1940                 :          0 :         return NULL;
        1941                 :     720879 :     memcpy(PyUnicode_1BYTE_DATA(unicode), s, size);
        1942                 :            :     assert(_PyUnicode_CheckConsistency(unicode, 1));
        1943                 :     720879 :     return unicode;
        1944                 :            : }
        1945                 :            :
        1946                 :            : static Py_UCS4
        1947                 :          0 : kind_maxchar_limit(int kind)
        1948                 :            : {
        1949   [ #  #  #  # ]:          0 :     switch (kind) {
        1950                 :          0 :     case PyUnicode_1BYTE_KIND:
        1951                 :          0 :         return 0x80;
        1952                 :          0 :     case PyUnicode_2BYTE_KIND:
        1953                 :          0 :         return 0x100;
        1954                 :          0 :     case PyUnicode_4BYTE_KIND:
        1955                 :          0 :         return 0x10000;
        1956                 :          0 :     default:
        1957                 :          0 :         Py_UNREACHABLE();
        1958                 :            :     }
        1959                 :            : }
        1960                 :            :
        1961                 :            : static PyObject*
        1962                 :     130347 : _PyUnicode_FromUCS1(const Py_UCS1* u, Py_ssize_t size)
        1963                 :            : {
        1964                 :            :     PyObject *res;
        1965                 :            :     unsigned char max_char;
        1966                 :            :
        1967         [ +  + ]:     130347 :     if (size == 0) {
        1968                 :        290 :         _Py_RETURN_UNICODE_EMPTY();
        1969                 :            :     }
        1970                 :            :     assert(size > 0);
        1971         [ +  + ]:     130057 :     if (size == 1) {
        1972                 :       5094 :         return get_latin1_char(u[0]);
        1973                 :            :     }
        1974                 :            :
        1975                 :     124963 :     max_char = ucs1lib_find_max_char(u, u + size);
        1976                 :     124963 :     res = PyUnicode_New(size, max_char);
        1977         [ -  + ]:     124963 :     if (!res)
        1978                 :          0 :         return NULL;
        1979                 :     124963 :     memcpy(PyUnicode_1BYTE_DATA(res), u, size);
        1980                 :            :     assert(_PyUnicode_CheckConsistency(res, 1));
        1981                 :     124963 :     return res;
        1982                 :            : }
        1983                 :            :
        1984                 :            : static PyObject*
        1985                 :       2424 : _PyUnicode_FromUCS2(const Py_UCS2 *u, Py_ssize_t size)
        1986                 :            : {
        1987                 :            :     PyObject *res;
        1988                 :            :     Py_UCS2 max_char;
        1989                 :            :
        1990         [ -  + ]:       2424 :     if (size == 0)
        1991                 :          0 :         _Py_RETURN_UNICODE_EMPTY();
        1992                 :            :     assert(size > 0);
        1993         [ +  + ]:       2424 :     if (size == 1)
        1994                 :        338 :         return unicode_char(u[0]);
        1995                 :            :
        1996                 :       2086 :     max_char = ucs2lib_find_max_char(u, u + size);
        1997                 :       2086 :     res = PyUnicode_New(size, max_char);
        1998         [ -  + ]:       2086 :     if (!res)
        1999                 :          0 :         return NULL;
        2000         [ +  + ]:       2086 :     if (max_char >= 256)
        2001                 :         26 :         memcpy(PyUnicode_2BYTE_DATA(res), u, sizeof(Py_UCS2)*size);
        2002                 :            :     else {
        2003   [ +  +  +  + ]:      21957 :         _PyUnicode_CONVERT_BYTES(
        2004                 :            :             Py_UCS2, Py_UCS1, u, u + size, PyUnicode_1BYTE_DATA(res));
        2005                 :            :     }
        2006                 :            :     assert(_PyUnicode_CheckConsistency(res, 1));
        2007                 :       2086 :     return res;
        2008                 :            : }
        2009                 :            :
        2010                 :            : static PyObject*
        2011                 :         46 : _PyUnicode_FromUCS4(const Py_UCS4 *u, Py_ssize_t size)
        2012                 :            : {
        2013                 :            :     PyObject *res;
        2014                 :            :     Py_UCS4 max_char;
        2015                 :            :
        2016         [ +  + ]:         46 :     if (size == 0)
        2017                 :          9 :         _Py_RETURN_UNICODE_EMPTY();
        2018                 :            :     assert(size > 0);
        2019         [ -  + ]:         37 :     if (size == 1)
        2020                 :          0 :         return unicode_char(u[0]);
        2021                 :            :
        2022                 :         37 :     max_char = ucs4lib_find_max_char(u, u + size);
        2023                 :         37 :     res = PyUnicode_New(size, max_char);
        2024         [ -  + ]:         37 :     if (!res)
        2025                 :          0 :         return NULL;
        2026         [ +  - ]:         37 :     if (max_char < 256)
        2027   [ +  +  +  + ]:         97 :         _PyUnicode_CONVERT_BYTES(Py_UCS4, Py_UCS1, u, u + size,
        2028                 :            :                                  PyUnicode_1BYTE_DATA(res));
        2029         [ #  # ]:          0 :     else if (max_char < 0x10000)
        2030   [ #  #  #  # ]:          0 :         _PyUnicode_CONVERT_BYTES(Py_UCS4, Py_UCS2, u, u + size,
        2031                 :            :                                  PyUnicode_2BYTE_DATA(res));
        2032                 :            :     else
        2033                 :          0 :         memcpy(PyUnicode_4BYTE_DATA(res), u, sizeof(Py_UCS4)*size);
        2034                 :            :     assert(_PyUnicode_CheckConsistency(res, 1));
        2035                 :         37 :     return res;
        2036                 :            : }
        2037                 :            :
        2038                 :            : PyObject*
        2039                 :     132802 : PyUnicode_FromKindAndData(int kind, const void *buffer, Py_ssize_t size)
        2040                 :            : {
        2041         [ -  + ]:     132802 :     if (size < 0) {
        2042                 :          0 :         PyErr_SetString(PyExc_ValueError, "size must be positive");
        2043                 :          0 :         return NULL;
        2044                 :            :     }
        2045   [ +  +  +  - ]:     132802 :     switch (kind) {
        2046                 :     130332 :     case PyUnicode_1BYTE_KIND:
        2047                 :     130332 :         return _PyUnicode_FromUCS1(buffer, size);
        2048                 :       2424 :     case PyUnicode_2BYTE_KIND:
        2049                 :       2424 :         return _PyUnicode_FromUCS2(buffer, size);
        2050                 :         46 :     case PyUnicode_4BYTE_KIND:
        2051                 :         46 :         return _PyUnicode_FromUCS4(buffer, size);
        2052                 :          0 :     default:
        2053                 :          0 :         PyErr_SetString(PyExc_SystemError, "invalid kind");
        2054                 :          0 :         return NULL;
        2055                 :            :     }
        2056                 :            : }
        2057                 :            :
        2058                 :            : Py_UCS4
        2059                 :        170 : _PyUnicode_FindMaxChar(PyObject *unicode, Py_ssize_t start, Py_ssize_t end)
        2060                 :            : {
        2061                 :            :     int kind;
        2062                 :            :     const void *startptr, *endptr;
        2063                 :            :
        2064                 :            :     assert(0 <= start);
        2065                 :            :     assert(end <= PyUnicode_GET_LENGTH(unicode));
        2066                 :            :     assert(start <= end);
        2067                 :            :
        2068   [ +  -  -  + ]:        170 :     if (start == 0 && end == PyUnicode_GET_LENGTH(unicode))
        2069                 :          0 :         return PyUnicode_MAX_CHAR_VALUE(unicode);
        2070                 :            :
        2071         [ -  + ]:        170 :     if (start == end)
        2072                 :          0 :         return 127;
        2073                 :            :
        2074         [ +  - ]:        170 :     if (PyUnicode_IS_ASCII(unicode))
        2075                 :        170 :         return 127;
        2076                 :            :
        2077                 :          0 :     kind = PyUnicode_KIND(unicode);
        2078                 :          0 :     startptr = PyUnicode_DATA(unicode);
        2079                 :          0 :     endptr = (char *)startptr + end * kind;
        2080                 :          0 :     startptr = (char *)startptr + start * kind;
        2081   [ #  #  #  # ]:          0 :     switch(kind) {
        2082                 :          0 :     case PyUnicode_1BYTE_KIND:
        2083                 :          0 :         return ucs1lib_find_max_char(startptr, endptr);
        2084                 :          0 :     case PyUnicode_2BYTE_KIND:
        2085                 :          0 :         return ucs2lib_find_max_char(startptr, endptr);
        2086                 :          0 :     case PyUnicode_4BYTE_KIND:
        2087                 :          0 :         return ucs4lib_find_max_char(startptr, endptr);
        2088                 :          0 :     default:
        2089                 :          0 :         Py_UNREACHABLE();
        2090                 :            :     }
        2091                 :            : }
        2092                 :            :
        2093                 :            : /* Ensure that a string uses the most efficient storage, if it is not the
        2094                 :            :    case: create a new string with of the right kind. Write NULL into *p_unicode
        2095                 :            :    on error. */
        2096                 :            : static void
        2097                 :          0 : unicode_adjust_maxchar(PyObject **p_unicode)
        2098                 :            : {
        2099                 :            :     PyObject *unicode, *copy;
        2100                 :            :     Py_UCS4 max_char;
        2101                 :            :     Py_ssize_t len;
        2102                 :            :     int kind;
        2103                 :            :
        2104                 :            :     assert(p_unicode != NULL);
        2105                 :          0 :     unicode = *p_unicode;
        2106         [ #  # ]:          0 :     if (PyUnicode_IS_ASCII(unicode))
        2107                 :          0 :         return;
        2108                 :            :
        2109                 :          0 :     len = PyUnicode_GET_LENGTH(unicode);
        2110                 :          0 :     kind = PyUnicode_KIND(unicode);
        2111         [ #  # ]:          0 :     if (kind == PyUnicode_1BYTE_KIND) {
        2112                 :          0 :         const Py_UCS1 *u = PyUnicode_1BYTE_DATA(unicode);
        2113                 :          0 :         max_char = ucs1lib_find_max_char(u, u + len);
        2114         [ #  # ]:          0 :         if (max_char >= 128)
        2115                 :          0 :             return;
        2116                 :            :     }
        2117         [ #  # ]:          0 :     else if (kind == PyUnicode_2BYTE_KIND) {
        2118                 :          0 :         const Py_UCS2 *u = PyUnicode_2BYTE_DATA(unicode);
        2119                 :          0 :         max_char = ucs2lib_find_max_char(u, u + len);
        2120         [ #  # ]:          0 :         if (max_char >= 256)
        2121                 :          0 :             return;
        2122                 :            :     }
        2123         [ #  # ]:          0 :     else if (kind == PyUnicode_4BYTE_KIND) {
        2124                 :          0 :         const Py_UCS4 *u = PyUnicode_4BYTE_DATA(unicode);
        2125                 :          0 :         max_char = ucs4lib_find_max_char(u, u + len);
        2126         [ #  # ]:          0 :         if (max_char >= 0x10000)
        2127                 :          0 :             return;
        2128                 :            :     }
        2129                 :            :     else
        2130                 :          0 :         Py_UNREACHABLE();
        2131                 :            :
        2132                 :          0 :     copy = PyUnicode_New(len, max_char);
        2133         [ #  # ]:          0 :     if (copy != NULL)
        2134                 :          0 :         _PyUnicode_FastCopyCharacters(copy, 0, unicode, 0, len);
        2135                 :          0 :     Py_DECREF(unicode);
        2136                 :          0 :     *p_unicode = copy;
        2137                 :            : }
        2138                 :            :
        2139                 :            : PyObject*
        2140                 :          0 : _PyUnicode_Copy(PyObject *unicode)
        2141                 :            : {
        2142                 :            :     Py_ssize_t length;
        2143                 :            :     PyObject *copy;
        2144                 :            :
        2145         [ #  # ]:          0 :     if (!PyUnicode_Check(unicode)) {
        2146                 :          0 :         PyErr_BadInternalCall();
        2147                 :          0 :         return NULL;
        2148                 :            :     }
        2149                 :            :
        2150                 :          0 :     length = PyUnicode_GET_LENGTH(unicode);
        2151                 :          0 :     copy = PyUnicode_New(length, PyUnicode_MAX_CHAR_VALUE(unicode));
        2152         [ #  # ]:          0 :     if (!copy)
        2153                 :          0 :         return NULL;
        2154                 :            :     assert(PyUnicode_KIND(copy) == PyUnicode_KIND(unicode));
        2155                 :            :
        2156                 :          0 :     memcpy(PyUnicode_DATA(copy), PyUnicode_DATA(unicode),
        2157                 :          0 :               length * PyUnicode_KIND(unicode));
        2158                 :            :     assert(_PyUnicode_CheckConsistency(copy, 1));
        2159                 :          0 :     return copy;
        2160                 :            : }
        2161                 :            :
        2162                 :            :
        2163                 :            : /* Widen Unicode objects to larger buffers. Don't write terminating null
        2164                 :            :    character. Return NULL on error. */
        2165                 :            :
        2166                 :            : static void*
        2167                 :          0 : unicode_askind(int skind, void const *data, Py_ssize_t len, int kind)
        2168                 :            : {
        2169                 :            :     void *result;
        2170                 :            :
        2171                 :            :     assert(skind < kind);
        2172      [ #  #  # ]:          0 :     switch (kind) {
        2173                 :          0 :     case PyUnicode_2BYTE_KIND:
        2174         [ #  # ]:          0 :         result = PyMem_New(Py_UCS2, len);
        2175         [ #  # ]:          0 :         if (!result)
        2176                 :          0 :             return PyErr_NoMemory();
        2177                 :            :         assert(skind == PyUnicode_1BYTE_KIND);
        2178   [ #  #  #  # ]:          0 :         _PyUnicode_CONVERT_BYTES(
        2179                 :            :             Py_UCS1, Py_UCS2,
        2180                 :            :             (const Py_UCS1 *)data,
        2181                 :            :             ((const Py_UCS1 *)data) + len,
        2182                 :            :             result);
        2183                 :          0 :         return result;
        2184                 :          0 :     case PyUnicode_4BYTE_KIND:
        2185         [ #  # ]:          0 :         result = PyMem_New(Py_UCS4, len);
        2186         [ #  # ]:          0 :         if (!result)
        2187                 :          0 :             return PyErr_NoMemory();
        2188         [ #  # ]:          0 :         if (skind == PyUnicode_2BYTE_KIND) {
        2189   [ #  #  #  # ]:          0 :             _PyUnicode_CONVERT_BYTES(
        2190                 :            :                 Py_UCS2, Py_UCS4,
        2191                 :            :                 (const Py_UCS2 *)data,
        2192                 :            :                 ((const Py_UCS2 *)data) + len,
        2193                 :            :                 result);
        2194                 :            :         }
        2195                 :            :         else {
        2196                 :            :             assert(skind == PyUnicode_1BYTE_KIND);
        2197   [ #  #  #  # ]:          0 :             _PyUnicode_CONVERT_BYTES(
        2198                 :            :                 Py_UCS1, Py_UCS4,
        2199                 :            :                 (const Py_UCS1 *)data,
        2200                 :            :                 ((const Py_UCS1 *)data) + len,
        2201                 :            :                 result);
        2202                 :            :         }
        2203                 :          0 :         return result;
        2204                 :          0 :     default:
        2205                 :          0 :         Py_UNREACHABLE();
        2206                 :            :         return NULL;
        2207                 :            :     }
        2208                 :            : }
        2209                 :            :
        2210                 :            : static Py_UCS4*
        2211                 :         75 : as_ucs4(PyObject *string, Py_UCS4 *target, Py_ssize_t targetsize,
        2212                 :            :         int copy_null)
        2213                 :            : {
        2214                 :            :     int kind;
        2215                 :            :     const void *data;
        2216                 :            :     Py_ssize_t len, targetlen;
        2217                 :         75 :     kind = PyUnicode_KIND(string);
        2218                 :         75 :     data = PyUnicode_DATA(string);
        2219                 :         75 :     len = PyUnicode_GET_LENGTH(string);
        2220                 :         75 :     targetlen = len;
        2221         [ -  + ]:         75 :     if (copy_null)
        2222                 :          0 :         targetlen++;
        2223         [ -  + ]:         75 :     if (!target) {
        2224         [ #  # ]:          0 :         target = PyMem_New(Py_UCS4, targetlen);
        2225         [ #  # ]:          0 :         if (!target) {
        2226                 :          0 :             PyErr_NoMemory();
        2227                 :          0 :             return NULL;
        2228                 :            :         }
        2229                 :            :     }
        2230                 :            :     else {
        2231         [ -  + ]:         75 :         if (targetsize < targetlen) {
        2232                 :          0 :             PyErr_Format(PyExc_SystemError,
        2233                 :            :                          "string is longer than the buffer");
        2234   [ #  #  #  # ]:          0 :             if (copy_null && 0 < targetsize)
        2235                 :          0 :                 target[0] = 0;
        2236                 :          0 :             return NULL;
        2237                 :            :         }
        2238                 :            :     }
        2239         [ +  - ]:         75 :     if (kind == PyUnicode_1BYTE_KIND) {
        2240                 :         75 :         const Py_UCS1 *start = (const Py_UCS1 *) data;
        2241   [ +  +  +  + ]:        217 :         _PyUnicode_CONVERT_BYTES(Py_UCS1, Py_UCS4, start, start + len, target);
        2242                 :            :     }
        2243         [ #  # ]:          0 :     else if (kind == PyUnicode_2BYTE_KIND) {
        2244                 :          0 :         const Py_UCS2 *start = (const Py_UCS2 *) data;
        2245   [ #  #  #  # ]:          0 :         _PyUnicode_CONVERT_BYTES(Py_UCS2, Py_UCS4, start, start + len, target);
        2246                 :            :     }
        2247         [ #  # ]:          0 :     else if (kind == PyUnicode_4BYTE_KIND) {
        2248                 :          0 :         memcpy(target, data, len * sizeof(Py_UCS4));
        2249                 :            :     }
        2250                 :            :     else {
        2251                 :          0 :         Py_UNREACHABLE();
        2252                 :            :     }
        2253         [ -  + ]:         75 :     if (copy_null)
        2254                 :          0 :         target[len] = 0;
        2255                 :         75 :     return target;
        2256                 :            : }
        2257                 :            :
        2258                 :            : Py_UCS4*
        2259                 :         75 : PyUnicode_AsUCS4(PyObject *string, Py_UCS4 *target, Py_ssize_t targetsize,
        2260                 :            :                  int copy_null)
        2261                 :            : {
        2262   [ +  -  -  + ]:         75 :     if (target == NULL || targetsize < 0) {
        2263                 :          0 :         PyErr_BadInternalCall();
        2264                 :          0 :         return NULL;
        2265                 :            :     }
        2266                 :         75 :     return as_ucs4(string, target, targetsize, copy_null);
        2267                 :            : }
        2268                 :            :
        2269                 :            : Py_UCS4*
        2270                 :          0 : PyUnicode_AsUCS4Copy(PyObject *string)
        2271                 :            : {
        2272                 :          0 :     return as_ucs4(string, NULL, 0, 1);
        2273                 :            : }
        2274                 :            :
        2275                 :            : /* maximum number of characters required for output of %lld or %p.
        2276                 :            :    We need at most ceil(log10(256)*SIZEOF_LONG_LONG) digits,
        2277                 :            :    plus 1 for the sign.  53/22 is an upper bound for log10(256). */
        2278                 :            : #define MAX_LONG_LONG_CHARS (2 + (SIZEOF_LONG_LONG*53-1) / 22)
        2279                 :            :
        2280                 :            : static int
        2281                 :      29681 : unicode_fromformat_write_str(_PyUnicodeWriter *writer, PyObject *str,
        2282                 :            :                              Py_ssize_t width, Py_ssize_t precision)
        2283                 :            : {
        2284                 :            :     Py_ssize_t length, fill, arglen;
        2285                 :            :     Py_UCS4 maxchar;
        2286                 :            :
        2287                 :      29681 :     length = PyUnicode_GET_LENGTH(str);
        2288   [ +  +  +  + ]:      29681 :     if ((precision == -1 || precision >= length)
        2289         [ +  - ]:      29655 :         && width <= length)
        2290                 :      29655 :         return _PyUnicodeWriter_WriteStr(writer, str);
        2291                 :            :
        2292         [ +  - ]:         26 :     if (precision != -1)
        2293                 :         26 :         length = Py_MIN(precision, length);
        2294                 :            :
        2295                 :         26 :     arglen = Py_MAX(length, width);
        2296         [ -  + ]:         26 :     if (PyUnicode_MAX_CHAR_VALUE(str) > writer->maxchar)
        2297                 :          0 :         maxchar = _PyUnicode_FindMaxChar(str, 0, length);
        2298                 :            :     else
        2299                 :         26 :         maxchar = writer->maxchar;
        2300                 :            :
        2301   [ +  -  +  -  :         26 :     if (_PyUnicodeWriter_Prepare(writer, arglen, maxchar) == -1)
                 +  -  -  + ]
        2302                 :          0 :         return -1;
        2303                 :            :
        2304         [ -  + ]:         26 :     if (width > length) {
        2305                 :          0 :         fill = width - length;
        2306         [ #  # ]:          0 :         if (PyUnicode_Fill(writer->buffer, writer->pos, fill, ' ') == -1)
        2307                 :          0 :             return -1;
        2308                 :          0 :         writer->pos += fill;
        2309                 :            :     }
        2310                 :            :
        2311                 :         26 :     _PyUnicode_FastCopyCharacters(writer->buffer, writer->pos,
        2312                 :            :                                   str, 0, length);
        2313                 :         26 :     writer->pos += length;
        2314                 :         26 :     return 0;
        2315                 :            : }
        2316                 :            :
        2317                 :            : static int
        2318                 :      10808 : unicode_fromformat_write_cstr(_PyUnicodeWriter *writer, const char *str,
        2319                 :            :                               Py_ssize_t width, Py_ssize_t precision)
        2320                 :            : {
        2321                 :            :     /* UTF-8 */
        2322                 :            :     Py_ssize_t length;
        2323                 :            :     PyObject *unicode;
        2324                 :            :     int res;
        2325                 :            :
        2326         [ +  + ]:      10808 :     if (precision == -1) {
        2327                 :        396 :         length = strlen(str);
        2328                 :            :     }
        2329                 :            :     else {
        2330                 :      10412 :         length = 0;
        2331   [ +  -  +  + ]:      84686 :         while (length < precision && str[length]) {
        2332                 :      74274 :             length++;
        2333                 :            :         }
        2334                 :            :     }
        2335                 :      10808 :     unicode = PyUnicode_DecodeUTF8Stateful(str, length, "replace", NULL);
        2336         [ -  + ]:      10808 :     if (unicode == NULL)
        2337                 :          0 :         return -1;
        2338                 :            :
        2339                 :      10808 :     res = unicode_fromformat_write_str(writer, unicode, width, -1);
        2340                 :      10808 :     Py_DECREF(unicode);
        2341                 :      10808 :     return res;
        2342                 :            : }
        2343                 :            :
        2344                 :            : static const char*
        2345                 :      31100 : unicode_fromformat_arg(_PyUnicodeWriter *writer,
        2346                 :            :                        const char *f, va_list *vargs)
        2347                 :            : {
        2348                 :            :     const char *p;
        2349                 :            :     Py_ssize_t len;
        2350                 :            :     int zeropad;
        2351                 :            :     Py_ssize_t width;
        2352                 :            :     Py_ssize_t precision;
        2353                 :            :     int longflag;
        2354                 :            :     int longlongflag;
        2355                 :            :     int size_tflag;
        2356                 :            :     Py_ssize_t fill;
        2357                 :            :
        2358                 :      31100 :     p = f;
        2359                 :      31100 :     f++;
        2360         [ -  + ]:      31100 :     if (*f == '%') {
        2361         [ #  # ]:          0 :         if (_PyUnicodeWriter_WriteCharInline(writer, '%') < 0)
        2362                 :          0 :             return NULL;
        2363                 :          0 :         f++;
        2364                 :          0 :         return f;
        2365                 :            :     }
        2366                 :            :
        2367                 :      31100 :     zeropad = 0;
        2368         [ -  + ]:      31100 :     if (*f == '0') {
        2369                 :          0 :         zeropad = 1;
        2370                 :          0 :         f++;
        2371                 :            :     }
        2372                 :            :
        2373                 :            :     /* parse the width.precision part, e.g. "%2.5s" => width=2, precision=5 */
        2374                 :      31100 :     width = -1;
        2375         [ -  + ]:      31100 :     if (Py_ISDIGIT((unsigned)*f)) {
        2376                 :          0 :         width = *f - '0';
        2377                 :          0 :         f++;
        2378         [ #  # ]:          0 :         while (Py_ISDIGIT((unsigned)*f)) {
        2379         [ #  # ]:          0 :             if (width > (PY_SSIZE_T_MAX - ((int)*f - '0')) / 10) {
        2380                 :          0 :                 PyErr_SetString(PyExc_ValueError,
        2381                 :            :                                 "width too big");
        2382                 :          0 :                 return NULL;
        2383                 :            :             }
        2384                 :          0 :             width = (width * 10) + (*f - '0');
        2385                 :          0 :             f++;
        2386                 :            :         }
        2387                 :            :     }
        2388                 :      31100 :     precision = -1;
        2389         [ +  + ]:      31100 :     if (*f == '.') {
        2390                 :      11172 :         f++;
        2391         [ +  - ]:      11172 :         if (Py_ISDIGIT((unsigned)*f)) {
        2392                 :      11172 :             precision = (*f - '0');
        2393                 :      11172 :             f++;
        2394         [ +  + ]:      24795 :             while (Py_ISDIGIT((unsigned)*f)) {
        2395         [ -  + ]:      13623 :                 if (precision > (PY_SSIZE_T_MAX - ((int)*f - '0')) / 10) {
        2396                 :          0 :                     PyErr_SetString(PyExc_ValueError,
        2397                 :            :                                     "precision too big");
        2398                 :          0 :                     return NULL;
        2399                 :            :                 }
        2400                 :      13623 :                 precision = (precision * 10) + (*f - '0');
        2401                 :      13623 :                 f++;
        2402                 :            :             }
        2403                 :            :         }
        2404                 :            :     }
        2405                 :            :
        2406                 :            :     /* Handle %ld, %lu, %lld and %llu. */
        2407                 :      31100 :     longflag = 0;
        2408                 :      31100 :     longlongflag = 0;
        2409                 :      31100 :     size_tflag = 0;
        2410         [ +  + ]:      31100 :     if (*f == 'l') {
        2411   [ +  +  +  -  :          3 :         if (f[1] == 'd' || f[1] == 'u' || f[1] == 'i') {
                       -  + ]
        2412                 :          1 :             longflag = 1;
        2413                 :          1 :             ++f;
        2414                 :            :         }
        2415         [ +  - ]:          2 :         else if (f[1] == 'l' &&
        2416   [ -  +  -  -  :          2 :                  (f[2] == 'd' || f[2] == 'u' || f[2] == 'i')) {
                       -  - ]
        2417                 :          2 :             longlongflag = 1;
        2418                 :          2 :             f += 2;
        2419                 :            :         }
        2420                 :            :     }
        2421                 :            :     /* handle the size_t flag. */
        2422   [ +  +  -  +  :      31097 :     else if (*f == 'z' && (f[1] == 'd' || f[1] == 'u' || f[1] == 'i')) {
                 -  -  -  - ]
        2423                 :         64 :         size_tflag = 1;
        2424                 :         64 :         ++f;
        2425                 :            :     }
        2426                 :            :
        2427   [ +  -  +  + ]:      31100 :     if (f[0] != '\0' && f[1] == '\0')
        2428                 :       1462 :         writer->overallocate = 0;
        2429                 :            :
        2430   [ +  +  +  +  :      31100 :     switch (*f) {
              +  -  +  +  -
                          - ]
        2431                 :         70 :     case 'c':
        2432                 :            :     {
        2433                 :         70 :         int ordinal = va_arg(*vargs, int);
        2434   [ +  -  -  + ]:         70 :         if (ordinal < 0 || ordinal > MAX_UNICODE) {
        2435                 :          0 :             PyErr_SetString(PyExc_OverflowError,
        2436                 :            :                             "character argument not in range(0x110000)");
        2437                 :          0 :             return NULL;
        2438                 :            :         }
        2439         [ -  + ]:         70 :         if (_PyUnicodeWriter_WriteCharInline(writer, ordinal) < 0)
        2440                 :          0 :             return NULL;
        2441                 :         70 :         break;
        2442                 :            :     }
        2443                 :            :
        2444                 :       1348 :     case 'i':
        2445                 :            :     case 'd':
        2446                 :            :     case 'u':
        2447                 :            :     case 'x':
        2448                 :            :     {
        2449                 :            :         /* used by sprintf */
        2450                 :            :         char buffer[MAX_LONG_LONG_CHARS];
        2451                 :            :         Py_ssize_t arglen;
        2452                 :            :
        2453         [ -  + ]:       1348 :         if (*f == 'u') {
        2454         [ #  # ]:          0 :             if (longflag) {
        2455                 :          0 :                 len = sprintf(buffer, "%lu", va_arg(*vargs, unsigned long));
        2456                 :            :             }
        2457         [ #  # ]:          0 :             else if (longlongflag) {
        2458                 :          0 :                 len = sprintf(buffer, "%llu", va_arg(*vargs, unsigned long long));
        2459                 :            :             }
        2460         [ #  # ]:          0 :             else if (size_tflag) {
        2461                 :          0 :                 len = sprintf(buffer, "%zu", va_arg(*vargs, size_t));
        2462                 :            :             }
        2463                 :            :             else {
        2464                 :          0 :                 len = sprintf(buffer, "%u", va_arg(*vargs, unsigned int));
        2465                 :            :             }
        2466                 :            :         }
        2467         [ -  + ]:       1348 :         else if (*f == 'x') {
        2468                 :          0 :             len = sprintf(buffer, "%x", va_arg(*vargs, int));
        2469                 :            :         }
        2470                 :            :         else {
        2471         [ +  + ]:       1348 :             if (longflag) {
        2472                 :          1 :                 len = sprintf(buffer, "%li", va_arg(*vargs, long));
        2473                 :            :             }
        2474         [ +  + ]:       1347 :             else if (longlongflag) {
        2475                 :          2 :                 len = sprintf(buffer, "%lli", va_arg(*vargs, long long));
        2476                 :            :             }
        2477         [ +  + ]:       1345 :             else if (size_tflag) {
        2478                 :         64 :                 len = sprintf(buffer, "%zi", va_arg(*vargs, Py_ssize_t));
        2479                 :            :             }
        2480                 :            :             else {
        2481                 :       1281 :                 len = sprintf(buffer, "%i", va_arg(*vargs, int));
        2482                 :            :             }
        2483                 :            :         }
        2484                 :            :         assert(len >= 0);
        2485                 :            :
        2486                 :       1348 :         int negative = (buffer[0] == '-');
        2487                 :       1348 :         len -= negative;
        2488                 :            :
        2489                 :       1348 :         precision = Py_MAX(precision, len);
        2490                 :       1348 :         width = Py_MAX(width, precision + negative);
        2491                 :            :
        2492                 :       1348 :         arglen = Py_MAX(precision, width);
        2493   [ +  -  -  +  :       1348 :         if (_PyUnicodeWriter_Prepare(writer, arglen, 127) == -1)
                 -  -  -  - ]
        2494                 :          0 :             return NULL;
        2495                 :            :
        2496         [ -  + ]:       1348 :         if (width > precision) {
        2497   [ #  #  #  # ]:          0 :             if (negative && zeropad) {
        2498         [ #  # ]:          0 :                 if (_PyUnicodeWriter_WriteChar(writer, '-') == -1)
        2499                 :          0 :                     return NULL;
        2500                 :            :             }
        2501                 :            :
        2502         [ #  # ]:          0 :             Py_UCS4 fillchar = zeropad?'0':' ';
        2503                 :          0 :             fill = width - precision - negative;
        2504         [ #  # ]:          0 :             if (PyUnicode_Fill(writer->buffer, writer->pos, fill, fillchar) == -1)
        2505                 :          0 :                 return NULL;
        2506                 :          0 :             writer->pos += fill;
        2507                 :            :
        2508   [ #  #  #  # ]:          0 :             if (negative && !zeropad) {
        2509         [ #  # ]:          0 :                 if (_PyUnicodeWriter_WriteChar(writer, '-') == -1)
        2510                 :          0 :                     return NULL;
        2511                 :            :             }
        2512                 :            :         }
        2513                 :            :
        2514         [ -  + ]:       1348 :         if (precision > len) {
        2515                 :          0 :             fill = precision - len;
        2516         [ #  # ]:          0 :             if (PyUnicode_Fill(writer->buffer, writer->pos, fill, '0') == -1)
        2517                 :          0 :                 return NULL;
        2518                 :          0 :             writer->pos += fill;
        2519                 :            :         }
        2520                 :            :
        2521         [ -  + ]:       1348 :         if (_PyUnicodeWriter_WriteASCIIString(writer, &buffer[negative], len) < 0)
        2522                 :          0 :             return NULL;
        2523                 :       1348 :         break;
        2524                 :            :     }
        2525                 :            :
        2526                 :          1 :     case 'p':
        2527                 :            :     {
        2528                 :            :         char number[MAX_LONG_LONG_CHARS];
        2529                 :            :
        2530                 :          1 :         len = sprintf(number, "%p", va_arg(*vargs, void*));
        2531                 :            :         assert(len >= 0);
        2532                 :            :
        2533                 :            :         /* %p is ill-defined:  ensure leading 0x. */
        2534         [ -  + ]:          1 :         if (number[1] == 'X')
        2535                 :          0 :             number[1] = 'x';
        2536         [ -  + ]:          1 :         else if (number[1] != 'x') {
        2537                 :          0 :             memmove(number + 2, number,
        2538                 :          0 :                     strlen(number) + 1);
        2539                 :          0 :             number[0] = '0';
        2540                 :          0 :             number[1] = 'x';
        2541                 :          0 :             len += 2;
        2542                 :            :         }
        2543                 :            :
        2544         [ -  + ]:          1 :         if (_PyUnicodeWriter_WriteASCIIString(writer, number, len) < 0)
        2545                 :          0 :             return NULL;
        2546                 :          1 :         break;
        2547                 :            :     }
        2548                 :            :
        2549                 :      10808 :     case 's':
        2550                 :            :     {
        2551                 :            :         /* UTF-8 */
        2552                 :      10808 :         const char *s = va_arg(*vargs, const char*);
        2553         [ -  + ]:      10808 :         if (unicode_fromformat_write_cstr(writer, s, width, precision) < 0)
        2554                 :          0 :             return NULL;
        2555                 :      10808 :         break;
        2556                 :            :     }
        2557                 :            :
        2558                 :      17990 :     case 'U':
        2559                 :            :     {
        2560                 :      17990 :         PyObject *obj = va_arg(*vargs, PyObject *);
        2561                 :            :         assert(obj && _PyUnicode_CHECK(obj));
        2562                 :            :
        2563         [ -  + ]:      17990 :         if (unicode_fromformat_write_str(writer, obj, width, precision) == -1)
        2564                 :          0 :             return NULL;
        2565                 :      17990 :         break;
        2566                 :            :     }
        2567                 :            :
        2568                 :          0 :     case 'V':
        2569                 :            :     {
        2570                 :          0 :         PyObject *obj = va_arg(*vargs, PyObject *);
        2571                 :          0 :         const char *str = va_arg(*vargs, const char *);
        2572         [ #  # ]:          0 :         if (obj) {
        2573                 :            :             assert(_PyUnicode_CHECK(obj));
        2574         [ #  # ]:          0 :             if (unicode_fromformat_write_str(writer, obj, width, precision) == -1)
        2575                 :          0 :                 return NULL;
        2576                 :            :         }
        2577                 :            :         else {
        2578                 :            :             assert(str != NULL);
        2579         [ #  # ]:          0 :             if (unicode_fromformat_write_cstr(writer, str, width, precision) < 0)
        2580                 :          0 :                 return NULL;
        2581                 :            :         }
        2582                 :          0 :         break;
        2583                 :            :     }
        2584                 :            :
        2585                 :         67 :     case 'S':
        2586                 :            :     {
        2587                 :         67 :         PyObject *obj = va_arg(*vargs, PyObject *);
        2588                 :            :         PyObject *str;
        2589                 :            :         assert(obj);
        2590                 :         67 :         str = PyObject_Str(obj);
        2591         [ -  + ]:         67 :         if (!str)
        2592                 :          0 :             return NULL;
        2593         [ -  + ]:         67 :         if (unicode_fromformat_write_str(writer, str, width, precision) == -1) {
        2594                 :          0 :             Py_DECREF(str);
        2595                 :          0 :             return NULL;
        2596                 :            :         }
        2597                 :         67 :         Py_DECREF(str);
        2598                 :         67 :         break;
        2599                 :            :     }
        2600                 :            :
        2601                 :        816 :     case 'R':
        2602                 :            :     {
        2603                 :        816 :         PyObject *obj = va_arg(*vargs, PyObject *);
        2604                 :            :         PyObject *repr;
        2605                 :            :         assert(obj);
        2606                 :        816 :         repr = PyObject_Repr(obj);
        2607         [ -  + ]:        816 :         if (!repr)
        2608                 :          0 :             return NULL;
        2609         [ -  + ]:        816 :         if (unicode_fromformat_write_str(writer, repr, width, precision) == -1) {
        2610                 :          0 :             Py_DECREF(repr);
        2611                 :          0 :             return NULL;
        2612                 :            :         }
        2613                 :        816 :         Py_DECREF(repr);
        2614                 :        816 :         break;
        2615                 :            :     }
        2616                 :            :
        2617                 :          0 :     case 'A':
        2618                 :            :     {
        2619                 :          0 :         PyObject *obj = va_arg(*vargs, PyObject *);
        2620                 :            :         PyObject *ascii;
        2621                 :            :         assert(obj);
        2622                 :          0 :         ascii = PyObject_ASCII(obj);
        2623         [ #  # ]:          0 :         if (!ascii)
        2624                 :          0 :             return NULL;
        2625         [ #  # ]:          0 :         if (unicode_fromformat_write_str(writer, ascii, width, precision) == -1) {
        2626                 :          0 :             Py_DECREF(ascii);
        2627                 :          0 :             return NULL;
        2628                 :            :         }
        2629                 :          0 :         Py_DECREF(ascii);
        2630                 :          0 :         break;
        2631                 :            :     }
        2632                 :            :
        2633                 :          0 :     default:
        2634                 :          0 :         PyErr_Format(PyExc_SystemError, "invalid format string: %s", p);
        2635                 :          0 :         return NULL;
        2636                 :            :     }
        2637                 :            :
        2638                 :      31100 :     f++;
        2639                 :      31100 :     return f;
        2640                 :            : }
        2641                 :            :
        2642                 :            : PyObject *
        2643                 :      16604 : PyUnicode_FromFormatV(const char *format, va_list vargs)
        2644                 :            : {
        2645                 :            :     va_list vargs2;
        2646                 :            :     const char *f;
        2647                 :            :     _PyUnicodeWriter writer;
        2648                 :            :
        2649                 :      16604 :     _PyUnicodeWriter_Init(&writer);
        2650                 :      16604 :     writer.min_length = strlen(format) + 100;
        2651                 :      16604 :     writer.overallocate = 1;
        2652                 :            :
        2653                 :            :     // Copy varags to be able to pass a reference to a subfunction.
        2654                 :      16604 :     va_copy(vargs2, vargs);
        2655                 :            :
        2656         [ +  + ]:      93582 :     for (f = format; *f; ) {
        2657         [ +  + ]:      76978 :         if (*f == '%') {
        2658                 :      31100 :             f = unicode_fromformat_arg(&writer, f, &vargs2);
        2659         [ -  + ]:      31100 :             if (f == NULL)
        2660                 :          0 :                 goto fail;
        2661                 :            :         }
        2662                 :            :         else {
        2663                 :            :             const char *p;
        2664                 :            :             Py_ssize_t len;
        2665                 :            :
        2666                 :      45878 :             p = f;
        2667                 :            :             do
        2668                 :            :             {
        2669         [ -  + ]:     499739 :                 if ((unsigned char)*p > 127) {
        2670                 :          0 :                     PyErr_Format(PyExc_ValueError,
        2671                 :            :                         "PyUnicode_FromFormatV() expects an ASCII-encoded format "
        2672                 :            :                         "string, got a non-ASCII byte: 0x%02x",
        2673                 :          0 :                         (unsigned char)*p);
        2674                 :          0 :                     goto fail;
        2675                 :            :                 }
        2676                 :     499739 :                 p++;
        2677                 :            :             }
        2678   [ +  +  +  + ]:     499739 :             while (*p != '\0' && *p != '%');
        2679                 :      45878 :             len = p - f;
        2680                 :            :
        2681         [ +  + ]:      45878 :             if (*p == '\0')
        2682                 :      15142 :                 writer.overallocate = 0;
        2683                 :            :
        2684         [ -  + ]:      45878 :             if (_PyUnicodeWriter_WriteASCIIString(&writer, f, len) < 0)
        2685                 :          0 :                 goto fail;
        2686                 :            :
        2687                 :      45878 :             f = p;
        2688                 :            :         }
        2689                 :            :     }
        2690                 :      16604 :     va_end(vargs2);
        2691                 :      16604 :     return _PyUnicodeWriter_Finish(&writer);
        2692                 :            :
        2693                 :          0 :   fail:
        2694                 :          0 :     va_end(vargs2);
        2695                 :          0 :     _PyUnicodeWriter_Dealloc(&writer);
        2696                 :          0 :     return NULL;
        2697                 :            : }
        2698                 :            :
        2699                 :            : PyObject *
        2700                 :        748 : PyUnicode_FromFormat(const char *format, ...)
        2701                 :            : {
        2702                 :            :     PyObject* ret;
        2703                 :            :     va_list vargs;
        2704                 :            :
        2705                 :        748 :     va_start(vargs, format);
        2706                 :        748 :     ret = PyUnicode_FromFormatV(format, vargs);
        2707                 :        748 :     va_end(vargs);
        2708                 :        748 :     return ret;
        2709                 :            : }
        2710                 :            :
        2711                 :            : static Py_ssize_t
        2712                 :       2357 : unicode_get_widechar_size(PyObject *unicode)
        2713                 :            : {
        2714                 :            :     Py_ssize_t res;
        2715                 :            :
        2716                 :            :     assert(unicode != NULL);
        2717                 :            :     assert(_PyUnicode_CHECK(unicode));
        2718                 :            :
        2719                 :       2357 :     res = _PyUnicode_LENGTH(unicode);
        2720                 :            : #if SIZEOF_WCHAR_T == 2
        2721                 :            :     if (PyUnicode_KIND(unicode) == PyUnicode_4BYTE_KIND) {
        2722                 :            :         const Py_UCS4 *s = PyUnicode_4BYTE_DATA(unicode);
        2723                 :            :         const Py_UCS4 *end = s + res;
        2724                 :            :         for (; s < end; ++s) {
        2725                 :            :             if (*s > 0xFFFF) {
        2726                 :            :                 ++res;
        2727                 :            :             }
        2728                 :            :         }
        2729                 :            :     }
        2730                 :            : #endif
        2731                 :       2357 :     return res;
        2732                 :            : }
        2733                 :            :
        2734                 :            : static void
        2735                 :       2357 : unicode_copy_as_widechar(PyObject *unicode, wchar_t *w, Py_ssize_t size)
        2736                 :            : {
        2737                 :            :     assert(unicode != NULL);
        2738                 :            :     assert(_PyUnicode_CHECK(unicode));
        2739                 :            :
        2740         [ -  + ]:       2357 :     if (PyUnicode_KIND(unicode) == sizeof(wchar_t)) {
        2741                 :          0 :         memcpy(w, PyUnicode_DATA(unicode), size * sizeof(wchar_t));
        2742                 :          0 :         return;
        2743                 :            :     }
        2744                 :            :
        2745         [ +  - ]:       2357 :     if (PyUnicode_KIND(unicode) == PyUnicode_1BYTE_KIND) {
        2746                 :       2357 :         const Py_UCS1 *s = PyUnicode_1BYTE_DATA(unicode);
        2747         [ +  + ]:      73332 :         for (; size--; ++s, ++w) {
        2748                 :      70975 :             *w = *s;
        2749                 :            :         }
        2750                 :            :     }
        2751                 :            :     else {
        2752                 :            : #if SIZEOF_WCHAR_T == 4
        2753                 :            :         assert(PyUnicode_KIND(unicode) == PyUnicode_2BYTE_KIND);
        2754                 :          0 :         const Py_UCS2 *s = PyUnicode_2BYTE_DATA(unicode);
        2755         [ #  # ]:          0 :         for (; size--; ++s, ++w) {
        2756                 :          0 :             *w = *s;
        2757                 :            :         }
        2758                 :            : #else
        2759                 :            :         assert(PyUnicode_KIND(unicode) == PyUnicode_4BYTE_KIND);
        2760                 :            :         const Py_UCS4 *s = PyUnicode_4BYTE_DATA(unicode);
        2761                 :            :         for (; size--; ++s, ++w) {
        2762                 :            :             Py_UCS4 ch = *s;
        2763                 :            :             if (ch > 0xFFFF) {
        2764                 :            :                 assert(ch <= MAX_UNICODE);
        2765                 :            :                 /* encode surrogate pair in this case */
        2766                 :            :                 *w++ = Py_UNICODE_HIGH_SURROGATE(ch);
        2767                 :            :                 if (!size--)
        2768                 :            :                     break;
        2769                 :            :                 *w = Py_UNICODE_LOW_SURROGATE(ch);
        2770                 :            :             }
        2771                 :            :             else {
        2772                 :            :                 *w = ch;
        2773                 :            :             }
        2774                 :            :         }
        2775                 :            : #endif
        2776                 :            :     }
        2777                 :            : }
        2778                 :            :
        2779                 :            : #ifdef HAVE_WCHAR_H
        2780                 :            :
        2781                 :            : /* Convert a Unicode object to a wide character string.
        2782                 :            :
        2783                 :            :    - If w is NULL: return the number of wide characters (including the null
        2784                 :            :      character) required to convert the unicode object. Ignore size argument.
        2785                 :            :
        2786                 :            :    - Otherwise: return the number of wide characters (excluding the null
        2787                 :            :      character) written into w. Write at most size wide characters (including
        2788                 :            :      the null character). */
        2789                 :            : Py_ssize_t
        2790                 :          0 : PyUnicode_AsWideChar(PyObject *unicode,
        2791                 :            :                      wchar_t *w,
        2792                 :            :                      Py_ssize_t size)
        2793                 :            : {
        2794                 :            :     Py_ssize_t res;
        2795                 :            :
        2796         [ #  # ]:          0 :     if (unicode == NULL) {
        2797                 :          0 :         PyErr_BadInternalCall();
        2798                 :          0 :         return -1;
        2799                 :            :     }
        2800         [ #  # ]:          0 :     if (!PyUnicode_Check(unicode)) {
        2801                 :          0 :         PyErr_BadArgument();
        2802                 :          0 :         return -1;
        2803                 :            :     }
        2804                 :            :
        2805                 :          0 :     res = unicode_get_widechar_size(unicode);
        2806         [ #  # ]:          0 :     if (w == NULL) {
        2807                 :          0 :         return res + 1;
        2808                 :            :     }
        2809                 :            :
        2810         [ #  # ]:          0 :     if (size > res) {
        2811                 :          0 :         size = res + 1;
        2812                 :            :     }
        2813                 :            :     else {
        2814                 :          0 :         res = size;
        2815                 :            :     }
        2816                 :          0 :     unicode_copy_as_widechar(unicode, w, size);
        2817                 :            :
        2818                 :            : #ifdef HAVE_NON_UNICODE_WCHAR_T_REPRESENTATION
        2819                 :            :     /* Oracle Solaris uses non-Unicode internal wchar_t form for
        2820                 :            :        non-Unicode locales and hence needs conversion first. */
        2821                 :            :     if (_Py_LocaleUsesNonUnicodeWchar()) {
        2822                 :            :         if (_Py_EncodeNonUnicodeWchar_InPlace(w, size) < 0) {
        2823                 :            :             return -1;
        2824                 :            :         }
        2825                 :            :     }
        2826                 :            : #endif
        2827                 :            :
        2828                 :          0 :     return res;
        2829                 :            : }
        2830                 :            :
        2831                 :            : wchar_t*
        2832                 :       2357 : PyUnicode_AsWideCharString(PyObject *unicode,
        2833                 :            :                            Py_ssize_t *size)
        2834                 :            : {
        2835                 :            :     wchar_t *buffer;
        2836                 :            :     Py_ssize_t buflen;
        2837                 :            :
        2838         [ -  + ]:       2357 :     if (unicode == NULL) {
        2839                 :          0 :         PyErr_BadInternalCall();
        2840                 :          0 :         return NULL;
        2841                 :            :     }
        2842         [ -  + ]:       2357 :     if (!PyUnicode_Check(unicode)) {
        2843                 :          0 :         PyErr_BadArgument();
        2844                 :          0 :         return NULL;
        2845                 :            :     }
        2846                 :            :
        2847                 :       2357 :     buflen = unicode_get_widechar_size(unicode);
        2848         [ +  - ]:       2357 :     buffer = (wchar_t *) PyMem_New(wchar_t, (buflen + 1));
        2849         [ -  + ]:       2357 :     if (buffer == NULL) {
        2850                 :          0 :         PyErr_NoMemory();
        2851                 :          0 :         return NULL;
        2852                 :            :     }
        2853                 :       2357 :     unicode_copy_as_widechar(unicode, buffer, buflen + 1);
        2854                 :            :
        2855                 :            : #ifdef HAVE_NON_UNICODE_WCHAR_T_REPRESENTATION
        2856                 :            :     /* Oracle Solaris uses non-Unicode internal wchar_t form for
        2857                 :            :        non-Unicode locales and hence needs conversion first. */
        2858                 :            :     if (_Py_LocaleUsesNonUnicodeWchar()) {
        2859                 :            :         if (_Py_EncodeNonUnicodeWchar_InPlace(buffer, (buflen + 1)) < 0) {
        2860                 :            :             return NULL;
        2861                 :            :         }
        2862                 :            :     }
        2863                 :            : #endif
        2864                 :            :
        2865         [ +  + ]:       2357 :     if (size != NULL) {
        2866                 :       1404 :         *size = buflen;
        2867                 :            :     }
        2868         [ -  + ]:        953 :     else if (wcslen(buffer) != (size_t)buflen) {
        2869                 :          0 :         PyMem_Free(buffer);
        2870                 :          0 :         PyErr_SetString(PyExc_ValueError,
        2871                 :            :                         "embedded null character");
        2872                 :          0 :         return NULL;
        2873                 :            :     }
        2874                 :       2357 :     return buffer;
        2875                 :            : }
        2876                 :            :
        2877                 :            : #endif /* HAVE_WCHAR_H */
        2878                 :            :
        2879                 :            : int
        2880                 :          0 : _PyUnicode_WideCharString_Converter(PyObject *obj, void *ptr)
        2881                 :            : {
        2882                 :          0 :     wchar_t **p = (wchar_t **)ptr;
        2883         [ #  # ]:          0 :     if (obj == NULL) {
        2884                 :          0 :         PyMem_Free(*p);
        2885                 :          0 :         *p = NULL;
        2886                 :          0 :         return 1;
        2887                 :            :     }
        2888         [ #  # ]:          0 :     if (PyUnicode_Check(obj)) {
        2889                 :          0 :         *p = PyUnicode_AsWideCharString(obj, NULL);
        2890         [ #  # ]:          0 :         if (*p == NULL) {
        2891                 :          0 :             return 0;
        2892                 :            :         }
        2893                 :          0 :         return Py_CLEANUP_SUPPORTED;
        2894                 :            :     }
        2895                 :          0 :     PyErr_Format(PyExc_TypeError,
        2896                 :            :                  "argument must be str, not %.50s",
        2897                 :          0 :                  Py_TYPE(obj)->tp_name);
        2898                 :          0 :     return 0;
        2899                 :            : }
        2900                 :            :
        2901                 :            : int
        2902                 :          0 : _PyUnicode_WideCharString_Opt_Converter(PyObject *obj, void *ptr)
        2903                 :            : {
        2904                 :          0 :     wchar_t **p = (wchar_t **)ptr;
        2905         [ #  # ]:          0 :     if (obj == NULL) {
        2906                 :          0 :         PyMem_Free(*p);
        2907                 :          0 :         *p = NULL;
        2908                 :          0 :         return 1;
        2909                 :            :     }
        2910         [ #  # ]:          0 :     if (obj == Py_None) {
        2911                 :          0 :         *p = NULL;
        2912                 :          0 :         return 1;
        2913                 :            :     }
        2914         [ #  # ]:          0 :     if (PyUnicode_Check(obj)) {
        2915                 :          0 :         *p = PyUnicode_AsWideCharString(obj, NULL);
        2916         [ #  # ]:          0 :         if (*p == NULL) {
        2917                 :          0 :             return 0;
        2918                 :            :         }
        2919                 :          0 :         return Py_CLEANUP_SUPPORTED;
        2920                 :            :     }
        2921                 :          0 :     PyErr_Format(PyExc_TypeError,
        2922                 :            :                  "argument must be str or None, not %.50s",
        2923                 :          0 :                  Py_TYPE(obj)->tp_name);
        2924                 :          0 :     return 0;
        2925                 :            : }
        2926                 :            :
        2927                 :            : PyObject *
        2928                 :     268367 : PyUnicode_FromOrdinal(int ordinal)
        2929                 :            : {
        2930   [ +  -  -  + ]:     268367 :     if (ordinal < 0 || ordinal > MAX_UNICODE) {
        2931                 :          0 :         PyErr_SetString(PyExc_ValueError,
        2932                 :            :                         "chr() arg not in range(0x110000)");
        2933                 :          0 :         return NULL;
        2934                 :            :     }
        2935                 :            :
        2936                 :     268367 :     return unicode_char((Py_UCS4)ordinal);
        2937                 :            : }
        2938                 :            :
        2939                 :            : PyObject *
        2940                 :       6571 : PyUnicode_FromObject(PyObject *obj)
        2941                 :            : {
        2942                 :            :     /* XXX Perhaps we should make this API an alias of
        2943                 :            :        PyObject_Str() instead ?! */
        2944         [ +  - ]:       6571 :     if (PyUnicode_CheckExact(obj)) {
        2945                 :       6571 :         return Py_NewRef(obj);
        2946                 :            :     }
        2947         [ #  # ]:          0 :     if (PyUnicode_Check(obj)) {
        2948                 :            :         /* For a Unicode subtype that's not a Unicode object,
        2949                 :            :            return a true Unicode object with the same data. */
        2950                 :          0 :         return _PyUnicode_Copy(obj);
        2951                 :            :     }
        2952                 :          0 :     PyErr_Format(PyExc_TypeError,
        2953                 :            :                  "Can't convert '%.100s' object to str implicitly",
        2954                 :          0 :                  Py_TYPE(obj)->tp_name);
        2955                 :          0 :     return NULL;
        2956                 :            : }
        2957                 :            :
        2958                 :            : PyObject *
        2959                 :       7182 : PyUnicode_FromEncodedObject(PyObject *obj,
        2960                 :            :                             const char *encoding,
        2961                 :            :                             const char *errors)
        2962                 :            : {
        2963                 :            :     Py_buffer buffer;
        2964                 :            :     PyObject *v;
        2965                 :            :
        2966         [ -  + ]:       7182 :     if (obj == NULL) {
        2967                 :          0 :         PyErr_BadInternalCall();
        2968                 :          0 :         return NULL;
        2969                 :            :     }
        2970                 :            :
        2971                 :            :     /* Decoding bytes objects is the most common case and should be fast */
        2972         [ +  - ]:       7182 :     if (PyBytes_Check(obj)) {
        2973         [ +  + ]:       7182 :         if (PyBytes_GET_SIZE(obj) == 0) {
        2974         [ -  + ]:         37 :             if (unicode_check_encoding_errors(encoding, errors) < 0) {
        2975                 :          0 :                 return NULL;
        2976                 :            :             }
        2977                 :         37 :             _Py_RETURN_UNICODE_EMPTY();
        2978                 :            :         }
        2979                 :      14290 :         return PyUnicode_Decode(
        2980                 :       7145 :                 PyBytes_AS_STRING(obj), PyBytes_GET_SIZE(obj),
        2981                 :            :                 encoding, errors);
        2982                 :            :     }
        2983                 :            :
        2984         [ #  # ]:          0 :     if (PyUnicode_Check(obj)) {
        2985                 :          0 :         PyErr_SetString(PyExc_TypeError,
        2986                 :            :                         "decoding str is not supported");
        2987                 :          0 :         return NULL;
        2988                 :            :     }
        2989                 :            :
        2990                 :            :     /* Retrieve a bytes buffer view through the PEP 3118 buffer interface */
        2991         [ #  # ]:          0 :     if (PyObject_GetBuffer(obj, &buffer, PyBUF_SIMPLE) < 0) {
        2992                 :          0 :         PyErr_Format(PyExc_TypeError,
        2993                 :            :                      "decoding to str: need a bytes-like object, %.80s found",
        2994                 :          0 :                      Py_TYPE(obj)->tp_name);
        2995                 :          0 :         return NULL;
        2996                 :            :     }
        2997                 :            :
        2998         [ #  # ]:          0 :     if (buffer.len == 0) {
        2999                 :          0 :         PyBuffer_Release(&buffer);
        3000         [ #  # ]:          0 :         if (unicode_check_encoding_errors(encoding, errors) < 0) {
        3001                 :          0 :             return NULL;
        3002                 :            :         }
        3003                 :          0 :         _Py_RETURN_UNICODE_EMPTY();
        3004                 :            :     }
        3005                 :            :
        3006                 :          0 :     v = PyUnicode_Decode((char*) buffer.buf, buffer.len, encoding, errors);
        3007                 :          0 :     PyBuffer_Release(&buffer);
        3008                 :          0 :     return v;
        3009                 :            : }
        3010                 :            :
        3011                 :            : /* Normalize an encoding name: similar to encodings.normalize_encoding(), but
        3012                 :            :    also convert to lowercase. Return 1 on success, or 0 on error (encoding is
        3013                 :            :    longer than lower_len-1). */
        3014                 :            : int
        3015                 :      16802 : _Py_normalize_encoding(const char *encoding,
        3016                 :            :                        char *lower,
        3017                 :            :                        size_t lower_len)
        3018                 :            : {
        3019                 :            :     const char *e;
        3020                 :            :     char *l;
        3021                 :            :     char *l_end;
        3022                 :            :     int punct;
        3023                 :            :
        3024                 :            :     assert(encoding != NULL);
        3025                 :            :
        3026                 :      16802 :     e = encoding;
        3027                 :      16802 :     l = lower;
        3028                 :      16802 :     l_end = &lower[lower_len - 1];
        3029                 :      16802 :     punct = 0;
        3030                 :      84743 :     while (1) {
        3031                 :     101545 :         char c = *e;
        3032         [ +  + ]:     101545 :         if (c == 0) {
        3033                 :      16802 :             break;
        3034                 :            :         }
        3035                 :            :
        3036   [ +  +  +  + ]:      84743 :         if (Py_ISALNUM(c) || c == '.') {
        3037   [ +  +  +  - ]:      82840 :             if (punct && l != lower) {
        3038         [ -  + ]:       1903 :                 if (l == l_end) {
        3039                 :          0 :                     return 0;
        3040                 :            :                 }
        3041                 :       1903 :                 *l++ = '_';
        3042                 :            :             }
        3043                 :      82840 :             punct = 0;
        3044                 :            :
        3045         [ -  + ]:      82840 :             if (l == l_end) {
        3046                 :          0 :                 return 0;
        3047                 :            :             }
        3048                 :      82840 :             *l++ = Py_TOLOWER(c);
        3049                 :            :         }
        3050                 :            :         else {
        3051                 :       1903 :             punct = 1;
        3052                 :            :         }
        3053                 :            :
        3054                 :      84743 :         e++;
        3055                 :            :     }
        3056                 :      16802 :     *l = '\0';
        3057                 :      16802 :     return 1;
        3058                 :            : }
        3059                 :            :
        3060                 :            : PyObject *
        3061                 :      10466 : PyUnicode_Decode(const char *s,
        3062                 :            :                  Py_ssize_t size,
        3063                 :            :                  const char *encoding,
        3064                 :            :                  const char *errors)
        3065                 :            : {
        3066                 :      10466 :     PyObject *buffer = NULL, *unicode;
        3067                 :            :     Py_buffer info;
        3068                 :            :     char buflower[11];   /* strlen("iso-8859-1\0") == 11, longest shortcut */
        3069                 :            :
        3070         [ -  + ]:      10466 :     if (unicode_check_encoding_errors(encoding, errors) < 0) {
        3071                 :          0 :         return NULL;
        3072                 :            :     }
        3073                 :            :
        3074         [ -  + ]:      10466 :     if (size == 0) {
        3075                 :          0 :         _Py_RETURN_UNICODE_EMPTY();
        3076                 :            :     }
        3077                 :            :
        3078         [ -  + ]:      10466 :     if (encoding == NULL) {
        3079                 :          0 :         return PyUnicode_DecodeUTF8Stateful(s, size, errors, NULL);
        3080                 :            :     }
        3081                 :            :
        3082                 :            :     /* Shortcuts for common default encodings */
        3083         [ +  - ]:      10466 :     if (_Py_normalize_encoding(encoding, buflower, sizeof(buflower))) {
        3084                 :      10466 :         char *lower = buflower;
        3085                 :            :
        3086                 :            :         /* Fast paths */
        3087   [ +  +  +  -  :      10466 :         if (lower[0] == 'u' && lower[1] == 't' && lower[2] == 'f') {
                       +  - ]
        3088                 :        650 :             lower += 3;
        3089         [ +  + ]:        650 :             if (*lower == '_') {
        3090                 :            :                 /* Match "utf8" and "utf_8" */
        3091                 :        644 :                 lower++;
        3092                 :            :             }
        3093                 :            :
        3094   [ +  -  +  - ]:        650 :             if (lower[0] == '8' && lower[1] == 0) {
        3095                 :        650 :                 return PyUnicode_DecodeUTF8Stateful(s, size, errors, NULL);
        3096                 :            :             }
        3097   [ #  #  #  #  :          0 :             else if (lower[0] == '1' && lower[1] == '6' && lower[2] == 0) {
                       #  # ]
        3098                 :          0 :                 return PyUnicode_DecodeUTF16(s, size, errors, 0);
        3099                 :            :             }
        3100   [ #  #  #  #  :          0 :             else if (lower[0] == '3' && lower[1] == '2' && lower[2] == 0) {
                       #  # ]
        3101                 :          0 :                 return PyUnicode_DecodeUTF32(s, size, errors, 0);
        3102                 :            :             }
        3103                 :            :         }
        3104                 :            :         else {
        3105         [ +  + ]:       9816 :             if (strcmp(lower, "ascii") == 0
        3106         [ -  + ]:          5 :                 || strcmp(lower, "us_ascii") == 0) {
        3107                 :       9811 :                 return PyUnicode_DecodeASCII(s, size, errors);
        3108                 :            :             }
        3109                 :            :     #ifdef MS_WINDOWS
        3110                 :            :             else if (strcmp(lower, "mbcs") == 0) {
        3111                 :            :                 return PyUnicode_DecodeMBCS(s, size, errors);
        3112                 :            :             }
        3113                 :            :     #endif
        3114         [ -  + ]:          5 :             else if (strcmp(lower, "latin1") == 0
        3115         [ #  # ]:          0 :                      || strcmp(lower, "latin_1") == 0
        3116         [ #  # ]:          0 :                      || strcmp(lower, "iso_8859_1") == 0
        3117         [ #  # ]:          0 :                      || strcmp(lower, "iso8859_1") == 0) {
        3118                 :          5 :                 return PyUnicode_DecodeLatin1(s, size, errors);
        3119                 :            :             }
        3120                 :            :         }
        3121                 :            :     }
        3122                 :            :
        3123                 :            :     /* Decode via the codec registry */
        3124                 :          0 :     buffer = NULL;
        3125         [ #  # ]:          0 :     if (PyBuffer_FillInfo(&info, NULL, (void *)s, size, 1, PyBUF_FULL_RO) < 0)
        3126                 :          0 :         goto onError;
        3127                 :          0 :     buffer = PyMemoryView_FromBuffer(&info);
        3128         [ #  # ]:          0 :     if (buffer == NULL)
        3129                 :          0 :         goto onError;
        3130                 :          0 :     unicode = _PyCodec_DecodeText(buffer, encoding, errors);
        3131         [ #  # ]:          0 :     if (unicode == NULL)
        3132                 :          0 :         goto onError;
        3133         [ #  # ]:          0 :     if (!PyUnicode_Check(unicode)) {
        3134                 :          0 :         PyErr_Format(PyExc_TypeError,
        3135                 :            :                      "'%.400s' decoder returned '%.400s' instead of 'str'; "
        3136                 :            :                      "use codecs.decode() to decode to arbitrary types",
        3137                 :            :                      encoding,
        3138                 :          0 :                      Py_TYPE(unicode)->tp_name);
        3139                 :          0 :         Py_DECREF(unicode);
        3140                 :          0 :         goto onError;
        3141                 :            :     }
        3142                 :          0 :     Py_DECREF(buffer);
        3143                 :          0 :     return unicode_result(unicode);
        3144                 :            :
        3145                 :          0 :   onError:
        3146                 :          0 :     Py_XDECREF(buffer);
        3147                 :          0 :     return NULL;
        3148                 :            : }
        3149                 :            :
        3150                 :            : PyObject *
        3151                 :          0 : PyUnicode_AsDecodedObject(PyObject *unicode,
        3152                 :            :                           const char *encoding,
        3153                 :            :                           const char *errors)
        3154                 :            : {
        3155         [ #  # ]:          0 :     if (!PyUnicode_Check(unicode)) {
        3156                 :          0 :         PyErr_BadArgument();
        3157                 :          0 :         return NULL;
        3158                 :            :     }
        3159                 :            :
        3160         [ #  # ]:          0 :     if (PyErr_WarnEx(PyExc_DeprecationWarning,
        3161                 :            :                      "PyUnicode_AsDecodedObject() is deprecated; "
        3162                 :            :                      "use PyCodec_Decode() to decode from str", 1) < 0)
        3163                 :          0 :         return NULL;
        3164                 :            :
        3165         [ #  # ]:          0 :     if (encoding == NULL)
        3166                 :          0 :         encoding = PyUnicode_GetDefaultEncoding();
        3167                 :            :
        3168                 :            :     /* Decode via the codec registry */
        3169                 :          0 :     return PyCodec_Decode(unicode, encoding, errors);
        3170                 :            : }
        3171                 :            :
        3172                 :            : PyObject *
        3173                 :          0 : PyUnicode_AsDecodedUnicode(PyObject *unicode,
        3174                 :            :                            const char *encoding,
        3175                 :            :                            const char *errors)
        3176                 :            : {
        3177                 :            :     PyObject *v;
        3178                 :            :
        3179         [ #  # ]:          0 :     if (!PyUnicode_Check(unicode)) {
        3180                 :          0 :         PyErr_BadArgument();
        3181                 :          0 :         goto onError;
        3182                 :            :     }
        3183                 :            :
        3184         [ #  # ]:          0 :     if (PyErr_WarnEx(PyExc_DeprecationWarning,
        3185                 :            :                      "PyUnicode_AsDecodedUnicode() is deprecated; "
        3186                 :            :                      "use PyCodec_Decode() to decode from str to str", 1) < 0)
        3187                 :          0 :         return NULL;
        3188                 :            :
        3189         [ #  # ]:          0 :     if (encoding == NULL)
        3190                 :          0 :         encoding = PyUnicode_GetDefaultEncoding();
        3191                 :            :
        3192                 :            :     /* Decode via the codec registry */
        3193                 :          0 :     v = PyCodec_Decode(unicode, encoding, errors);
        3194         [ #  # ]:          0 :     if (v == NULL)
        3195                 :          0 :         goto onError;
        3196         [ #  # ]:          0 :     if (!PyUnicode_Check(v)) {
        3197                 :          0 :         PyErr_Format(PyExc_TypeError,
        3198                 :            :                      "'%.400s' decoder returned '%.400s' instead of 'str'; "
        3199                 :            :                      "use codecs.decode() to decode to arbitrary types",
        3200                 :            :                      encoding,
        3201                 :          0 :                      Py_TYPE(unicode)->tp_name);
        3202                 :          0 :         Py_DECREF(v);
        3203                 :          0 :         goto onError;
        3204                 :            :     }
        3205                 :          0 :     return unicode_result(v);
        3206                 :            :
        3207                 :          0 :   onError:
        3208                 :          0 :     return NULL;
        3209                 :            : }
        3210                 :            :
        3211                 :            : PyObject *
        3212                 :          0 : PyUnicode_AsEncodedObject(PyObject *unicode,
        3213                 :            :                           const char *encoding,
        3214                 :            :                           const char *errors)
        3215                 :            : {
        3216                 :            :     PyObject *v;
        3217                 :            :
        3218         [ #  # ]:          0 :     if (!PyUnicode_Check(unicode)) {
        3219                 :          0 :         PyErr_BadArgument();
        3220                 :          0 :         goto onError;
        3221                 :            :     }
        3222                 :            :
        3223         [ #  # ]:          0 :     if (PyErr_WarnEx(PyExc_DeprecationWarning,
        3224                 :            :                      "PyUnicode_AsEncodedObject() is deprecated; "
        3225                 :            :                      "use PyUnicode_AsEncodedString() to encode from str to bytes "
        3226                 :            :                      "or PyCodec_Encode() for generic encoding", 1) < 0)
        3227                 :          0 :         return NULL;
        3228                 :            :
        3229         [ #  # ]:          0 :     if (encoding == NULL)
        3230                 :          0 :         encoding = PyUnicode_GetDefaultEncoding();
        3231                 :            :
        3232                 :            :     /* Encode via the codec registry */
        3233                 :          0 :     v = PyCodec_Encode(unicode, encoding, errors);
        3234         [ #  # ]:          0 :     if (v == NULL)
        3235                 :          0 :         goto onError;
        3236                 :          0 :     return v;
        3237                 :            :
        3238                 :          0 :   onError:
        3239                 :          0 :     return NULL;
        3240                 :            : }
        3241                 :            :
        3242                 :            :
        3243                 :            : static PyObject *
        3244                 :        713 : unicode_encode_locale(PyObject *unicode, _Py_error_handler error_handler,
        3245                 :            :                       int current_locale)
        3246                 :            : {
        3247                 :            :     Py_ssize_t wlen;
        3248                 :        713 :     wchar_t *wstr = PyUnicode_AsWideCharString(unicode, &wlen);
        3249         [ -  + ]:        713 :     if (wstr == NULL) {
        3250                 :          0 :         return NULL;
        3251                 :            :     }
        3252                 :            :
        3253         [ -  + ]:        713 :     if ((size_t)wlen != wcslen(wstr)) {
        3254                 :          0 :         PyErr_SetString(PyExc_ValueError, "embedded null character");
        3255                 :          0 :         PyMem_Free(wstr);
        3256                 :          0 :         return NULL;
        3257                 :            :     }
        3258                 :            :
        3259                 :            :     char *str;
        3260                 :            :     size_t error_pos;
        3261                 :            :     const char *reason;
        3262                 :        713 :     int res = _Py_EncodeLocaleEx(wstr, &str, &error_pos, &reason,
        3263                 :            :                                  current_locale, error_handler);
        3264                 :        713 :     PyMem_Free(wstr);
        3265                 :            :
        3266         [ -  + ]:        713 :     if (res != 0) {
        3267         [ #  # ]:          0 :         if (res == -2) {
        3268                 :            :             PyObject *exc;
        3269                 :          0 :             exc = PyObject_CallFunction(PyExc_UnicodeEncodeError, "sOnns",
        3270                 :            :                     "locale", unicode,
        3271                 :            :                     (Py_ssize_t)error_pos,
        3272                 :          0 :                     (Py_ssize_t)(error_pos+1),
        3273                 :            :                     reason);
        3274         [ #  # ]:          0 :             if (exc != NULL) {
        3275                 :          0 :                 PyCodec_StrictErrors(exc);
        3276                 :          0 :                 Py_DECREF(exc);
        3277                 :            :             }
        3278                 :            :         }
        3279         [ #  # ]:          0 :         else if (res == -3) {
        3280                 :          0 :             PyErr_SetString(PyExc_ValueError, "unsupported error handler");
        3281                 :            :         }
        3282                 :            :         else {
        3283                 :          0 :             PyErr_NoMemory();
        3284                 :            :         }
        3285                 :          0 :         return NULL;
        3286                 :            :     }
        3287                 :            :
        3288                 :        713 :     PyObject *bytes = PyBytes_FromString(str);
        3289                 :        713 :     PyMem_RawFree(str);
        3290                 :        713 :     return bytes;
        3291                 :            : }
        3292                 :            :
        3293                 :            : PyObject *
        3294                 :          1 : PyUnicode_EncodeLocale(PyObject *unicode, const char *errors)
        3295                 :            : {
        3296                 :          1 :     _Py_error_handler error_handler = _Py_GetErrorHandler(errors);
        3297                 :          1 :     return unicode_encode_locale(unicode, error_handler, 1);
        3298                 :            : }
        3299                 :            :
        3300                 :            : PyObject *
        3301                 :       5409 : PyUnicode_EncodeFSDefault(PyObject *unicode)
        3302                 :            : {
        3303                 :       5409 :     PyInterpreterState *interp = _PyInterpreterState_GET();
        3304                 :       5409 :     struct _Py_unicode_fs_codec *fs_codec = &interp->unicode.fs_codec;
        3305         [ +  + ]:       5409 :     if (fs_codec->utf8) {
        3306                 :       2474 :         return unicode_encode_utf8(unicode,
        3307                 :            :                                    fs_codec->error_handler,
        3308                 :       2474 :                                    fs_codec->errors);
        3309                 :            :     }
        3310                 :            : #ifndef _Py_FORCE_UTF8_FS_ENCODING
        3311         [ +  + ]:       2935 :     else if (fs_codec->encoding) {
        3312                 :       2223 :         return PyUnicode_AsEncodedString(unicode,
        3313                 :       2223 :                                          fs_codec->encoding,
        3314                 :       2223 :                                          fs_codec->errors);
        3315                 :            :     }
        3316                 :            : #endif
        3317                 :            :     else {
        3318                 :            :         /* Before _PyUnicode_InitEncodings() is called, the Python codec
        3319                 :            :            machinery is not ready and so cannot be used:
        3320                 :            :            use wcstombs() in this case. */
        3321                 :        712 :         const PyConfig *config = _PyInterpreterState_GetConfig(interp);
        3322                 :        712 :         const wchar_t *filesystem_errors = config->filesystem_errors;
        3323                 :            :         assert(filesystem_errors != NULL);
        3324                 :        712 :         _Py_error_handler errors = get_error_handler_wide(filesystem_errors);
        3325                 :            :         assert(errors != _Py_ERROR_UNKNOWN);
        3326                 :            : #ifdef _Py_FORCE_UTF8_FS_ENCODING
        3327                 :            :         return unicode_encode_utf8(unicode, errors, NULL);
        3328                 :            : #else
        3329                 :        712 :         return unicode_encode_locale(unicode, errors, 0);
        3330                 :            : #endif
        3331                 :            :     }
        3332                 :            : }
        3333                 :            :
        3334                 :            : PyObject *
        3335                 :       5484 : PyUnicode_AsEncodedString(PyObject *unicode,
        3336                 :            :                           const char *encoding,
        3337                 :            :                           const char *errors)
        3338                 :            : {
        3339                 :            :     PyObject *v;
        3340                 :            :     char buflower[11];   /* strlen("iso_8859_1\0") == 11, longest shortcut */
        3341                 :            :
        3342         [ -  + ]:       5484 :     if (!PyUnicode_Check(unicode)) {
        3343                 :          0 :         PyErr_BadArgument();
        3344                 :          0 :         return NULL;
        3345                 :            :     }
        3346                 :            :
        3347         [ -  + ]:       5484 :     if (unicode_check_encoding_errors(encoding, errors) < 0) {
        3348                 :          0 :         return NULL;
        3349                 :            :     }
        3350                 :            :
        3351         [ +  + ]:       5484 :     if (encoding == NULL) {
        3352                 :          1 :         return _PyUnicode_AsUTF8String(unicode, errors);
        3353                 :            :     }
        3354                 :            :
        3355                 :            :     /* Shortcuts for common default encodings */
        3356         [ +  - ]:       5483 :     if (_Py_normalize_encoding(encoding, buflower, sizeof(buflower))) {
        3357                 :       5483 :         char *lower = buflower;
        3358                 :            :
        3359                 :            :         /* Fast paths */
        3360   [ +  +  +  -  :       5483 :         if (lower[0] == 'u' && lower[1] == 't' && lower[2] == 'f') {
                       +  - ]
        3361                 :        452 :             lower += 3;
        3362         [ +  + ]:        452 :             if (*lower == '_') {
        3363                 :            :                 /* Match "utf8" and "utf_8" */
        3364                 :        428 :                 lower++;
        3365                 :            :             }
        3366                 :            :
        3367   [ +  -  +  - ]:        452 :             if (lower[0] == '8' && lower[1] == 0) {
        3368                 :        452 :                 return _PyUnicode_AsUTF8String(unicode, errors);
        3369                 :            :             }
        3370   [ #  #  #  #  :          0 :             else if (lower[0] == '1' && lower[1] == '6' && lower[2] == 0) {
                       #  # ]
        3371                 :          0 :                 return _PyUnicode_EncodeUTF16(unicode, errors, 0);
        3372                 :            :             }
        3373   [ #  #  #  #  :          0 :             else if (lower[0] == '3' && lower[1] == '2' && lower[2] == 0) {
                       #  # ]
        3374                 :          0 :                 return _PyUnicode_EncodeUTF32(unicode, errors, 0);
        3375                 :            :             }
        3376                 :            :         }
        3377                 :            :         else {
        3378         [ -  + ]:       5031 :             if (strcmp(lower, "ascii") == 0
        3379         [ #  # ]:          0 :                 || strcmp(lower, "us_ascii") == 0) {
        3380                 :       5031 :                 return _PyUnicode_AsASCIIString(unicode, errors);
        3381                 :            :             }
        3382                 :            : #ifdef MS_WINDOWS
        3383                 :            :             else if (strcmp(lower, "mbcs") == 0) {
        3384                 :            :                 return PyUnicode_EncodeCodePage(CP_ACP, unicode, errors);
        3385                 :            :             }
        3386                 :            : #endif
        3387         [ #  # ]:          0 :             else if (strcmp(lower, "latin1") == 0 ||
        3388         [ #  # ]:          0 :                      strcmp(lower, "latin_1") == 0 ||
        3389         [ #  # ]:          0 :                      strcmp(lower, "iso_8859_1") == 0 ||
        3390         [ #  # ]:          0 :                      strcmp(lower, "iso8859_1") == 0) {
        3391                 :          0 :                 return _PyUnicode_AsLatin1String(unicode, errors);
        3392                 :            :             }
        3393                 :            :         }
        3394                 :            :     }
        3395                 :            :
        3396                 :            :     /* Encode via the codec registry */
        3397                 :          0 :     v = _PyCodec_EncodeText(unicode, encoding, errors);
        3398         [ #  # ]:          0 :     if (v == NULL)
        3399                 :          0 :         return NULL;
        3400                 :            :
        3401                 :            :     /* The normal path */
        3402         [ #  # ]:          0 :     if (PyBytes_Check(v))
        3403                 :          0 :         return v;
        3404                 :            :
        3405                 :            :     /* If the codec returns a buffer, raise a warning and convert to bytes */
        3406         [ #  # ]:          0 :     if (PyByteArray_Check(v)) {
        3407                 :            :         int error;
        3408                 :            :         PyObject *b;
        3409                 :            :
        3410                 :          0 :         error = PyErr_WarnFormat(PyExc_RuntimeWarning, 1,
        3411                 :            :             "encoder %s returned bytearray instead of bytes; "
        3412                 :            :             "use codecs.encode() to encode to arbitrary types",
        3413                 :            :             encoding);
        3414         [ #  # ]:          0 :         if (error) {
        3415                 :          0 :             Py_DECREF(v);
        3416                 :          0 :             return NULL;
        3417                 :            :         }
        3418                 :            :
        3419                 :          0 :         b = PyBytes_FromStringAndSize(PyByteArray_AS_STRING(v),
        3420                 :            :                                       PyByteArray_GET_SIZE(v));
        3421                 :          0 :         Py_DECREF(v);
        3422                 :          0 :         return b;
        3423                 :            :     }
        3424                 :            :
        3425                 :          0 :     PyErr_Format(PyExc_TypeError,
        3426                 :            :                  "'%.400s' encoder returned '%.400s' instead of 'bytes'; "
        3427                 :            :                  "use codecs.encode() to encode to arbitrary types",
        3428                 :            :                  encoding,
        3429                 :          0 :                  Py_TYPE(v)->tp_name);
        3430                 :          0 :     Py_DECREF(v);
        3431                 :          0 :     return NULL;
        3432                 :            : }
        3433                 :            :
        3434                 :            : PyObject *
        3435                 :          0 : PyUnicode_AsEncodedUnicode(PyObject *unicode,
        3436                 :            :                            const char *encoding,
        3437                 :            :                            const char *errors)
        3438                 :            : {
        3439                 :            :     PyObject *v;
        3440                 :            :
        3441         [ #  # ]:          0 :     if (!PyUnicode_Check(unicode)) {
        3442                 :          0 :         PyErr_BadArgument();
        3443                 :          0 :         goto onError;
        3444                 :            :     }
        3445                 :            :
        3446         [ #  # ]:          0 :     if (PyErr_WarnEx(PyExc_DeprecationWarning,
        3447                 :            :                      "PyUnicode_AsEncodedUnicode() is deprecated; "
        3448                 :            :                      "use PyCodec_Encode() to encode from str to str", 1) < 0)
        3449                 :          0 :         return NULL;
        3450                 :            :
        3451         [ #  # ]:          0 :     if (encoding == NULL)
        3452                 :          0 :         encoding = PyUnicode_GetDefaultEncoding();
        3453                 :            :
        3454                 :            :     /* Encode via the codec registry */
        3455                 :          0 :     v = PyCodec_Encode(unicode, encoding, errors);
        3456         [ #  # ]:          0 :     if (v == NULL)
        3457                 :          0 :         goto onError;
        3458         [ #  # ]:          0 :     if (!PyUnicode_Check(v)) {
        3459                 :          0 :         PyErr_Format(PyExc_TypeError,
        3460                 :            :                      "'%.400s' encoder returned '%.400s' instead of 'str'; "
        3461                 :            :                      "use codecs.encode() to encode to arbitrary types",
        3462                 :            :                      encoding,
        3463                 :          0 :                      Py_TYPE(v)->tp_name);
        3464                 :          0 :         Py_DECREF(v);
        3465                 :          0 :         goto onError;
        3466                 :            :     }
        3467                 :          0 :     return v;
        3468                 :            :
        3469                 :          0 :   onError:
        3470                 :          0 :     return NULL;
        3471                 :            : }
        3472                 :            :
        3473                 :            : static PyObject*
        3474                 :       8891 : unicode_decode_locale(const char *str, Py_ssize_t len,
        3475                 :            :                       _Py_error_handler errors, int current_locale)
        3476                 :            : {
        3477   [ +  -  -  + ]:       8891 :     if (str[len] != '\0' || (size_t)len != strlen(str))  {
        3478                 :          0 :         PyErr_SetString(PyExc_ValueError, "embedded null byte");
        3479                 :          0 :         return NULL;
        3480                 :            :     }
        3481                 :            :
        3482                 :            :     wchar_t *wstr;
        3483                 :            :     size_t wlen;
        3484                 :            :     const char *reason;
        3485                 :       8891 :     int res = _Py_DecodeLocaleEx(str, &wstr, &wlen, &reason,
        3486                 :            :                                  current_locale, errors);
        3487         [ -  + ]:       8891 :     if (res != 0) {
        3488         [ #  # ]:          0 :         if (res == -2) {
        3489                 :            :             PyObject *exc;
        3490                 :          0 :             exc = PyObject_CallFunction(PyExc_UnicodeDecodeError, "sy#nns",
        3491                 :            :                                         "locale", str, len,
        3492                 :            :                                         (Py_ssize_t)wlen,
        3493                 :          0 :                                         (Py_ssize_t)(wlen + 1),
        3494                 :            :                                         reason);
        3495         [ #  # ]:          0 :             if (exc != NULL) {
        3496                 :          0 :                 PyCodec_StrictErrors(exc);
        3497                 :          0 :                 Py_DECREF(exc);
        3498                 :            :             }
        3499                 :            :         }
        3500         [ #  # ]:          0 :         else if (res == -3) {
        3501                 :          0 :             PyErr_SetString(PyExc_ValueError, "unsupported error handler");
        3502                 :            :         }
        3503                 :            :         else {
        3504                 :          0 :             PyErr_NoMemory();
        3505                 :            :         }
        3506                 :          0 :         return NULL;
        3507                 :            :     }
        3508                 :            :
        3509                 :       8891 :     PyObject *unicode = PyUnicode_FromWideChar(wstr, wlen);
        3510                 :       8891 :     PyMem_RawFree(wstr);
        3511                 :       8891 :     return unicode;
        3512                 :            : }
        3513                 :            :
        3514                 :            : PyObject*
        3515                 :          0 : PyUnicode_DecodeLocaleAndSize(const char *str, Py_ssize_t len,
        3516                 :            :                               const char *errors)
        3517                 :            : {
        3518                 :          0 :     _Py_error_handler error_handler = _Py_GetErrorHandler(errors);
        3519                 :          0 :     return unicode_decode_locale(str, len, error_handler, 1);
        3520                 :            : }
        3521                 :            :
        3522                 :            : PyObject*
        3523                 :        809 : PyUnicode_DecodeLocale(const char *str, const char *errors)
        3524                 :            : {
        3525                 :        809 :     Py_ssize_t size = (Py_ssize_t)strlen(str);
        3526                 :        809 :     _Py_error_handler error_handler = _Py_GetErrorHandler(errors);
        3527                 :        809 :     return unicode_decode_locale(str, size, error_handler, 1);
        3528                 :            : }
        3529                 :            :
        3530                 :            :
        3531                 :            : PyObject*
        3532                 :       1655 : PyUnicode_DecodeFSDefault(const char *s) {
        3533                 :       1655 :     Py_ssize_t size = (Py_ssize_t)strlen(s);
        3534                 :       1655 :     return PyUnicode_DecodeFSDefaultAndSize(s, size);
        3535                 :            : }
        3536                 :            :
        3537                 :            : PyObject*
        3538                 :      13311 : PyUnicode_DecodeFSDefaultAndSize(const char *s, Py_ssize_t size)
        3539                 :            : {
        3540                 :      13311 :     PyInterpreterState *interp = _PyInterpreterState_GET();
        3541                 :      13311 :     struct _Py_unicode_fs_codec *fs_codec = &interp->unicode.fs_codec;
        3542         [ +  + ]:      13311 :     if (fs_codec->utf8) {
        3543                 :       1908 :         return unicode_decode_utf8(s, size,
        3544                 :            :                                    fs_codec->error_handler,
        3545                 :       1908 :                                    fs_codec->errors,
        3546                 :            :                                    NULL);
        3547                 :            :     }
        3548                 :            : #ifndef _Py_FORCE_UTF8_FS_ENCODING
        3549         [ +  + ]:      11403 :     else if (fs_codec->encoding) {
        3550                 :       3321 :         return PyUnicode_Decode(s, size,
        3551                 :       3321 :                                 fs_codec->encoding,
        3552                 :       3321 :                                 fs_codec->errors);
        3553                 :            :     }
        3554                 :            : #endif
        3555                 :            :     else {
        3556                 :            :         /* Before _PyUnicode_InitEncodings() is called, the Python codec
        3557                 :            :            machinery is not ready and so cannot be used:
        3558                 :            :            use mbstowcs() in this case. */
        3559                 :       8082 :         const PyConfig *config = _PyInterpreterState_GetConfig(interp);
        3560                 :       8082 :         const wchar_t *filesystem_errors = config->filesystem_errors;
        3561                 :            :         assert(filesystem_errors != NULL);
        3562                 :       8082 :         _Py_error_handler errors = get_error_handler_wide(filesystem_errors);
        3563                 :            :         assert(errors != _Py_ERROR_UNKNOWN);
        3564                 :            : #ifdef _Py_FORCE_UTF8_FS_ENCODING
        3565                 :            :         return unicode_decode_utf8(s, size, errors, NULL, NULL);
        3566                 :            : #else
        3567                 :       8082 :         return unicode_decode_locale(s, size, errors, 0);
        3568                 :            : #endif
        3569                 :            :     }
        3570                 :            : }
        3571                 :            :
        3572                 :            :
        3573                 :            : int
        3574                 :       5296 : PyUnicode_FSConverter(PyObject* arg, void* addr)
        3575                 :            : {
        3576                 :       5296 :     PyObject *path = NULL;
        3577                 :       5296 :     PyObject *output = NULL;
        3578                 :            :     Py_ssize_t size;
        3579                 :            :     const char *data;
        3580         [ -  + ]:       5296 :     if (arg == NULL) {
        3581                 :          0 :         Py_DECREF(*(PyObject**)addr);
        3582                 :          0 :         *(PyObject**)addr = NULL;
        3583                 :          0 :         return 1;
        3584                 :            :     }
        3585                 :       5296 :     path = PyOS_FSPath(arg);
        3586         [ -  + ]:       5296 :     if (path == NULL) {
        3587                 :          0 :         return 0;
        3588                 :            :     }
        3589         [ +  + ]:       5296 :     if (PyBytes_Check(path)) {
        3590                 :          2 :         output = path;
        3591                 :            :     }
        3592                 :            :     else {  // PyOS_FSPath() guarantees its returned value is bytes or str.
        3593                 :       5294 :         output = PyUnicode_EncodeFSDefault(path);
        3594                 :       5294 :         Py_DECREF(path);
        3595         [ -  + ]:       5294 :         if (!output) {
        3596                 :          0 :             return 0;
        3597                 :            :         }
        3598                 :            :         assert(PyBytes_Check(output));
        3599                 :            :     }
        3600                 :            :
        3601                 :       5296 :     size = PyBytes_GET_SIZE(output);
        3602                 :       5296 :     data = PyBytes_AS_STRING(output);
        3603         [ -  + ]:       5296 :     if ((size_t)size != strlen(data)) {
        3604                 :          0 :         PyErr_SetString(PyExc_ValueError, "embedded null byte");
        3605                 :          0 :         Py_DECREF(output);
        3606                 :          0 :         return 0;
        3607                 :            :     }
        3608                 :       5296 :     *(PyObject**)addr = output;
        3609                 :       5296 :     return Py_CLEANUP_SUPPORTED;
        3610                 :            : }
        3611                 :            :
        3612                 :            :
        3613                 :            : int
        3614                 :        267 : PyUnicode_FSDecoder(PyObject* arg, void* addr)
        3615                 :            : {
        3616         [ -  + ]:        267 :     if (arg == NULL) {
        3617                 :          0 :         Py_DECREF(*(PyObject**)addr);
        3618                 :          0 :         *(PyObject**)addr = NULL;
        3619                 :          0 :         return 1;
        3620                 :            :     }
        3621                 :            :
        3622                 :        267 :     PyObject *path = PyOS_FSPath(arg);
        3623         [ -  + ]:        267 :     if (path == NULL) {
        3624                 :          0 :         return 0;
        3625                 :            :     }
        3626                 :            :
        3627                 :        267 :     PyObject *output = NULL;
        3628         [ +  - ]:        267 :     if (PyUnicode_Check(path)) {
        3629                 :        267 :         output = path;
        3630                 :            :     }
        3631         [ #  # ]:          0 :     else if (PyBytes_Check(path)) {
        3632                 :          0 :         output = PyUnicode_DecodeFSDefaultAndSize(PyBytes_AS_STRING(path),
        3633                 :            :                                                   PyBytes_GET_SIZE(path));
        3634                 :          0 :         Py_DECREF(path);
        3635         [ #  # ]:          0 :         if (!output) {
        3636                 :          0 :             return 0;
        3637                 :            :         }
        3638                 :            :     }
        3639                 :            :     else {
        3640                 :          0 :         PyErr_Format(PyExc_TypeError,
        3641                 :            :                      "path should be string, bytes, or os.PathLike, not %.200s",
        3642                 :          0 :                      Py_TYPE(arg)->tp_name);
        3643                 :          0 :         Py_DECREF(path);
        3644                 :          0 :         return 0;
        3645                 :            :     }
        3646                 :            :
        3647         [ -  + ]:        267 :     if (findchar(PyUnicode_DATA(output), PyUnicode_KIND(output),
        3648                 :            :                  PyUnicode_GET_LENGTH(output), 0, 1) >= 0) {
        3649                 :          0 :         PyErr_SetString(PyExc_ValueError, "embedded null character");
        3650                 :          0 :         Py_DECREF(output);
        3651                 :          0 :         return 0;
        3652                 :            :     }
        3653                 :        267 :     *(PyObject**)addr = output;
        3654                 :        267 :     return Py_CLEANUP_SUPPORTED;
        3655                 :            : }
        3656                 :            :
        3657                 :            :
        3658                 :            : static int unicode_fill_utf8(PyObject *unicode);
        3659                 :            :
        3660                 :            : const char *
        3661                 :      45593 : PyUnicode_AsUTF8AndSize(PyObject *unicode, Py_ssize_t *psize)
        3662                 :            : {
        3663         [ -  + ]:      45593 :     if (!PyUnicode_Check(unicode)) {
        3664                 :          0 :         PyErr_BadArgument();
        3665                 :          0 :         return NULL;
        3666                 :            :     }
        3667                 :            :
        3668   [ +  -  -  + ]:      45593 :     if (PyUnicode_UTF8(unicode) == NULL) {
        3669         [ #  # ]:          0 :         if (unicode_fill_utf8(unicode) == -1) {
        3670                 :          0 :             return NULL;
        3671                 :            :         }
        3672                 :            :     }
        3673                 :            :
        3674         [ +  + ]:      45593 :     if (psize)
        3675         [ +  - ]:      36910 :         *psize = PyUnicode_UTF8_LENGTH(unicode);
        3676         [ +  - ]:      45593 :     return PyUnicode_UTF8(unicode);
        3677                 :            : }
        3678                 :            :
        3679                 :            : const char *
        3680                 :       8683 : PyUnicode_AsUTF8(PyObject *unicode)
        3681                 :            : {
        3682                 :       8683 :     return PyUnicode_AsUTF8AndSize(unicode, NULL);
        3683                 :            : }
        3684                 :            :
        3685                 :            : /*
        3686                 :            : PyUnicode_GetSize() has been deprecated since Python 3.3
        3687                 :            : because it returned length of Py_UNICODE.
        3688                 :            :
        3689                 :            : But this function is part of stable abi, because it don't
        3690                 :            : include Py_UNICODE in signature and it was not excluded from
        3691                 :            : stable abi in PEP 384.
        3692                 :            : */
        3693                 :            : PyAPI_FUNC(Py_ssize_t)
        3694                 :          0 : PyUnicode_GetSize(PyObject *unicode)
        3695                 :            : {
        3696                 :          0 :     PyErr_SetString(PyExc_RuntimeError,
        3697                 :            :                     "PyUnicode_GetSize has been removed.");
        3698                 :          0 :     return -1;
        3699                 :            : }
        3700                 :            :
        3701                 :            : Py_ssize_t
        3702                 :        114 : PyUnicode_GetLength(PyObject *unicode)
        3703                 :            : {
        3704         [ -  + ]:        114 :     if (!PyUnicode_Check(unicode)) {
        3705                 :          0 :         PyErr_BadArgument();
        3706                 :          0 :         return -1;
        3707                 :            :     }
        3708                 :        114 :     return PyUnicode_GET_LENGTH(unicode);
        3709                 :            : }
        3710                 :            :
        3711                 :            : Py_UCS4
        3712                 :          0 : PyUnicode_ReadChar(PyObject *unicode, Py_ssize_t index)
        3713                 :            : {
        3714                 :            :     const void *data;
        3715                 :            :     int kind;
        3716                 :            :
        3717         [ #  # ]:          0 :     if (!PyUnicode_Check(unicode)) {
        3718                 :          0 :         PyErr_BadArgument();
        3719                 :          0 :         return (Py_UCS4)-1;
        3720                 :            :     }
        3721   [ #  #  #  # ]:          0 :     if (index < 0 || index >= PyUnicode_GET_LENGTH(unicode)) {
        3722                 :          0 :         PyErr_SetString(PyExc_IndexError, "string index out of range");
        3723                 :          0 :         return (Py_UCS4)-1;
        3724                 :            :     }
        3725                 :          0 :     data = PyUnicode_DATA(unicode);
        3726                 :          0 :     kind = PyUnicode_KIND(unicode);
        3727                 :          0 :     return PyUnicode_READ(kind, data, index);
        3728                 :            : }
        3729                 :            :
        3730                 :            : int
        3731                 :          0 : PyUnicode_WriteChar(PyObject *unicode, Py_ssize_t index, Py_UCS4 ch)
        3732                 :            : {
        3733   [ #  #  #  # ]:          0 :     if (!PyUnicode_Check(unicode) || !PyUnicode_IS_COMPACT(unicode)) {
        3734                 :          0 :         PyErr_BadArgument();
        3735                 :          0 :         return -1;
        3736                 :            :     }
        3737   [ #  #  #  # ]:          0 :     if (index < 0 || index >= PyUnicode_GET_LENGTH(unicode)) {
        3738                 :          0 :         PyErr_SetString(PyExc_IndexError, "string index out of range");
        3739                 :          0 :         return -1;
        3740                 :            :     }
        3741         [ #  # ]:          0 :     if (unicode_check_modifiable(unicode))
        3742                 :          0 :         return -1;
        3743         [ #  # ]:          0 :     if (ch > PyUnicode_MAX_CHAR_VALUE(unicode)) {
        3744                 :          0 :         PyErr_SetString(PyExc_ValueError, "character out of range");
        3745                 :          0 :         return -1;
        3746                 :            :     }
        3747                 :          0 :     PyUnicode_WRITE(PyUnicode_KIND(unicode), PyUnicode_DATA(unicode),
        3748                 :            :                     index, ch);
        3749                 :          0 :     return 0;
        3750                 :            : }
        3751                 :            :
        3752                 :            : const char *
        3753                 :          0 : PyUnicode_GetDefaultEncoding(void)
        3754                 :            : {
        3755                 :          0 :     return "utf-8";
        3756                 :            : }
        3757                 :            :
        3758                 :            : /* create or adjust a UnicodeDecodeError */
        3759                 :            : static void
        3760                 :          2 : make_decode_exception(PyObject **exceptionObject,
        3761                 :            :                       const char *encoding,
        3762                 :            :                       const char *input, Py_ssize_t length,
        3763                 :            :                       Py_ssize_t startpos, Py_ssize_t endpos,
        3764                 :            :                       const char *reason)
        3765                 :            : {
        3766         [ +  - ]:          2 :     if (*exceptionObject == NULL) {
        3767                 :          2 :         *exceptionObject = PyUnicodeDecodeError_Create(
        3768                 :            :             encoding, input, length, startpos, endpos, reason);
        3769                 :            :     }
        3770                 :            :     else {
        3771         [ #  # ]:          0 :         if (PyUnicodeDecodeError_SetStart(*exceptionObject, startpos))
        3772                 :          0 :             goto onError;
        3773         [ #  # ]:          0 :         if (PyUnicodeDecodeError_SetEnd(*exceptionObject, endpos))
        3774                 :          0 :             goto onError;
        3775         [ #  # ]:          0 :         if (PyUnicodeDecodeError_SetReason(*exceptionObject, reason))
        3776                 :          0 :             goto onError;
        3777                 :            :     }
        3778                 :          2 :     return;
        3779                 :            :
        3780                 :          0 : onError:
        3781         [ #  # ]:          0 :     Py_CLEAR(*exceptionObject);
        3782                 :            : }
        3783                 :            :
        3784                 :            : #ifdef MS_WINDOWS
        3785                 :            : static int
        3786                 :            : widechar_resize(wchar_t **buf, Py_ssize_t *size, Py_ssize_t newsize)
        3787                 :            : {
        3788                 :            :     if (newsize > *size) {
        3789                 :            :         wchar_t *newbuf = *buf;
        3790                 :            :         if (PyMem_Resize(newbuf, wchar_t, newsize) == NULL) {
        3791                 :            :             PyErr_NoMemory();
        3792                 :            :             return -1;
        3793                 :            :         }
        3794                 :            :         *buf = newbuf;
        3795                 :            :     }
        3796                 :            :     *size = newsize;
        3797                 :            :     return 0;
        3798                 :            : }
        3799                 :            :
        3800                 :            : /* error handling callback helper:
        3801                 :            :    build arguments, call the callback and check the arguments,
        3802                 :            :    if no exception occurred, copy the replacement to the output
        3803                 :            :    and adjust various state variables.
        3804                 :            :    return 0 on success, -1 on error
        3805                 :            : */
        3806                 :            :
        3807                 :            : static int
        3808                 :            : unicode_decode_call_errorhandler_wchar(
        3809                 :            :     const char *errors, PyObject **errorHandler,
        3810                 :            :     const char *encoding, const char *reason,
        3811                 :            :     const char **input, const char **inend, Py_ssize_t *startinpos,
        3812                 :            :     Py_ssize_t *endinpos, PyObject **exceptionObject, const char **inptr,
        3813                 :            :     wchar_t **buf, Py_ssize_t *bufsize, Py_ssize_t *outpos)
        3814                 :            : {
        3815                 :            :     static const char *argparse = "Un;decoding error handler must return (str, int) tuple";
        3816                 :            :
        3817                 :            :     PyObject *restuple = NULL;
        3818                 :            :     PyObject *repunicode = NULL;
        3819                 :            :     Py_ssize_t outsize;
        3820                 :            :     Py_ssize_t insize;
        3821                 :            :     Py_ssize_t requiredsize;
        3822                 :            :     Py_ssize_t newpos;
        3823                 :            :     PyObject *inputobj = NULL;
        3824                 :            :     Py_ssize_t repwlen;
        3825                 :            :
        3826                 :            :     if (*errorHandler == NULL) {
        3827                 :            :         *errorHandler = PyCodec_LookupError(errors);
        3828                 :            :         if (*errorHandler == NULL)
        3829                 :            :             goto onError;
        3830                 :            :     }
        3831                 :            :
        3832                 :            :     make_decode_exception(exceptionObject,
        3833                 :            :         encoding,
        3834                 :            :         *input, *inend - *input,
        3835                 :            :         *startinpos, *endinpos,
        3836                 :            :         reason);
        3837                 :            :     if (*exceptionObject == NULL)
        3838                 :            :         goto onError;
        3839                 :            :
        3840                 :            :     restuple = PyObject_CallOneArg(*errorHandler, *exceptionObject);
        3841                 :            :     if (restuple == NULL)
        3842                 :            :         goto onError;
        3843                 :            :     if (!PyTuple_Check(restuple)) {
        3844                 :            :         PyErr_SetString(PyExc_TypeError, &argparse[3]);
        3845                 :            :         goto onError;
        3846                 :            :     }
        3847                 :            :     if (!PyArg_ParseTuple(restuple, argparse, &repunicode, &newpos))
        3848                 :            :         goto onError;
        3849                 :            :
        3850                 :            :     /* Copy back the bytes variables, which might have been modified by the
        3851                 :            :        callback */
        3852                 :            :     inputobj = PyUnicodeDecodeError_GetObject(*exceptionObject);
        3853                 :            :     if (!inputobj)
        3854                 :            :         goto onError;
        3855                 :            :     *input = PyBytes_AS_STRING(inputobj);
        3856                 :            :     insize = PyBytes_GET_SIZE(inputobj);
        3857                 :            :     *inend = *input + insize;
        3858                 :            :     /* we can DECREF safely, as the exception has another reference,
        3859                 :            :        so the object won't go away. */
        3860                 :            :     Py_DECREF(inputobj);
        3861                 :            :
        3862                 :            :     if (newpos<0)
        3863                 :            :         newpos = insize+newpos;
        3864                 :            :     if (newpos<0 || newpos>insize) {
        3865                 :            :         PyErr_Format(PyExc_IndexError, "position %zd from error handler out of bounds", newpos);
        3866                 :            :         goto onError;
        3867                 :            :     }
        3868                 :            :
        3869                 :            :     repwlen = PyUnicode_AsWideChar(repunicode, NULL, 0);
        3870                 :            :     if (repwlen < 0)
        3871                 :            :         goto onError;
        3872                 :            :     repwlen--;
        3873                 :            :     /* need more space? (at least enough for what we
        3874                 :            :        have+the replacement+the rest of the string (starting
        3875                 :            :        at the new input position), so we won't have to check space
        3876                 :            :        when there are no errors in the rest of the string) */
        3877                 :            :     requiredsize = *outpos;
        3878                 :            :     if (requiredsize > PY_SSIZE_T_MAX - repwlen)
        3879                 :            :         goto overflow;
        3880                 :            :     requiredsize += repwlen;
        3881                 :            :     if (requiredsize > PY_SSIZE_T_MAX - (insize - newpos))
        3882                 :            :         goto overflow;
        3883                 :            :     requiredsize += insize - newpos;
        3884                 :            :     outsize = *bufsize;
        3885                 :            :     if (requiredsize > outsize) {
        3886                 :            :         if (outsize <= PY_SSIZE_T_MAX/2 && requiredsize < 2*outsize)
        3887                 :            :             requiredsize = 2*outsize;
        3888                 :            :         if (widechar_resize(buf, bufsize, requiredsize) < 0) {
        3889                 :            :             goto onError;
        3890                 :            :         }
        3891                 :            :     }
        3892                 :            :     PyUnicode_AsWideChar(repunicode, *buf + *outpos, repwlen);
        3893                 :            :     *outpos += repwlen;
        3894                 :            :     *endinpos = newpos;
        3895                 :            :     *inptr = *input + newpos;
        3896                 :            :
        3897                 :            :     /* we made it! */
        3898                 :            :     Py_DECREF(restuple);
        3899                 :            :     return 0;
        3900                 :            :
        3901                 :            :   overflow:
        3902                 :            :     PyErr_SetString(PyExc_OverflowError,
        3903                 :            :                     "decoded result is too long for a Python string");
        3904                 :            :
        3905                 :            :   onError:
        3906                 :            :     Py_XDECREF(restuple);
        3907                 :            :     return -1;
        3908                 :            : }
        3909                 :            : #endif   /* MS_WINDOWS */
        3910                 :            :
        3911                 :            : static int
        3912                 :          2 : unicode_decode_call_errorhandler_writer(
        3913                 :            :     const char *errors, PyObject **errorHandler,
        3914                 :            :     const char *encoding, const char *reason,
        3915                 :            :     const char **input, const char **inend, Py_ssize_t *startinpos,
        3916                 :            :     Py_ssize_t *endinpos, PyObject **exceptionObject, const char **inptr,
        3917                 :            :     _PyUnicodeWriter *writer /* PyObject **output, Py_ssize_t *outpos */)
        3918                 :            : {
        3919                 :            :     static const char *argparse = "Un;decoding error handler must return (str, int) tuple";
        3920                 :            :
        3921                 :          2 :     PyObject *restuple = NULL;
        3922                 :          2 :     PyObject *repunicode = NULL;
        3923                 :            :     Py_ssize_t insize;
        3924                 :            :     Py_ssize_t newpos;
        3925                 :            :     Py_ssize_t replen;
        3926                 :            :     Py_ssize_t remain;
        3927                 :          2 :     PyObject *inputobj = NULL;
        3928                 :          2 :     int need_to_grow = 0;
        3929                 :            :     const char *new_inptr;
        3930                 :            :
        3931         [ +  - ]:          2 :     if (*errorHandler == NULL) {
        3932                 :          2 :         *errorHandler = PyCodec_LookupError(errors);
        3933         [ -  + ]:          2 :         if (*errorHandler == NULL)
        3934                 :          0 :             goto onError;
        3935                 :            :     }
        3936                 :            :
        3937                 :          2 :     make_decode_exception(exceptionObject,
        3938                 :            :         encoding,
        3939                 :          2 :         *input, *inend - *input,
        3940                 :            :         *startinpos, *endinpos,
        3941                 :            :         reason);
        3942         [ -  + ]:          2 :     if (*exceptionObject == NULL)
        3943                 :          0 :         goto onError;
        3944                 :            :
        3945                 :          2 :     restuple = PyObject_CallOneArg(*errorHandler, *exceptionObject);
        3946         [ +  - ]:          2 :     if (restuple == NULL)
        3947                 :          2 :         goto onError;
        3948         [ #  # ]:          0 :     if (!PyTuple_Check(restuple)) {
        3949                 :          0 :         PyErr_SetString(PyExc_TypeError, &argparse[3]);
        3950                 :          0 :         goto onError;
        3951                 :            :     }
        3952         [ #  # ]:          0 :     if (!PyArg_ParseTuple(restuple, argparse, &repunicode, &newpos))
        3953                 :          0 :         goto onError;
        3954                 :            :
        3955                 :            :     /* Copy back the bytes variables, which might have been modified by the
        3956                 :            :        callback */
        3957                 :          0 :     inputobj = PyUnicodeDecodeError_GetObject(*exceptionObject);
        3958         [ #  # ]:          0 :     if (!inputobj)
        3959                 :          0 :         goto onError;
        3960                 :          0 :     remain = *inend - *input - *endinpos;
        3961                 :          0 :     *input = PyBytes_AS_STRING(inputobj);
        3962                 :          0 :     insize = PyBytes_GET_SIZE(inputobj);
        3963                 :          0 :     *inend = *input + insize;
        3964                 :            :     /* we can DECREF safely, as the exception has another reference,
        3965                 :            :        so the object won't go away. */
        3966                 :          0 :     Py_DECREF(inputobj);
        3967                 :            :
        3968         [ #  # ]:          0 :     if (newpos<0)
        3969                 :          0 :         newpos = insize+newpos;
        3970   [ #  #  #  # ]:          0 :     if (newpos<0 || newpos>insize) {
        3971                 :          0 :         PyErr_Format(PyExc_IndexError, "position %zd from error handler out of bounds", newpos);
        3972                 :          0 :         goto onError;
        3973                 :            :     }
        3974                 :            :
        3975                 :          0 :     replen = PyUnicode_GET_LENGTH(repunicode);
        3976         [ #  # ]:          0 :     if (replen > 1) {
        3977                 :          0 :         writer->min_length += replen - 1;
        3978                 :          0 :         need_to_grow = 1;
        3979                 :            :     }
        3980                 :          0 :     new_inptr = *input + newpos;
        3981         [ #  # ]:          0 :     if (*inend - new_inptr > remain) {
        3982                 :            :         /* We don't know the decoding algorithm here so we make the worst
        3983                 :            :            assumption that one byte decodes to one unicode character.
        3984                 :            :            If unfortunately one byte could decode to more unicode characters,
        3985                 :            :            the decoder may write out-of-bound then.  Is it possible for the
        3986                 :            :            algorithms using this function? */
        3987                 :          0 :         writer->min_length += *inend - new_inptr - remain;
        3988                 :          0 :         need_to_grow = 1;
        3989                 :            :     }
        3990         [ #  # ]:          0 :     if (need_to_grow) {
        3991                 :          0 :         writer->overallocate = 1;
        3992   [ #  #  #  # ]:          0 :         if (_PyUnicodeWriter_Prepare(writer, writer->min_length - writer->pos,
        3993   [ #  #  #  # ]:          0 :                             PyUnicode_MAX_CHAR_VALUE(repunicode)) == -1)
        3994                 :          0 :             goto onError;
        3995                 :            :     }
        3996         [ #  # ]:          0 :     if (_PyUnicodeWriter_WriteStr(writer, repunicode) == -1)
        3997                 :          0 :         goto onError;
        3998                 :            :
        3999                 :          0 :     *endinpos = newpos;
        4000                 :          0 :     *inptr = new_inptr;
        4001                 :            :
        4002                 :            :     /* we made it! */
        4003                 :          0 :     Py_DECREF(restuple);
        4004                 :          0 :     return 0;
        4005                 :            :
        4006                 :          2 :   onError:
        4007                 :          2 :     Py_XDECREF(restuple);
        4008                 :          2 :     return -1;
        4009                 :            : }
        4010                 :            :
        4011                 :            : /* --- UTF-7 Codec -------------------------------------------------------- */
        4012                 :            :
        4013                 :            : /* See RFC2152 for details.  We encode conservatively and decode liberally. */
        4014                 :            :
        4015                 :            : /* Three simple macros defining base-64. */
        4016                 :            :
        4017                 :            : /* Is c a base-64 character? */
        4018                 :            :
        4019                 :            : #define IS_BASE64(c) \
        4020                 :            :     (((c) >= 'A' && (c) <= 'Z') ||     \
        4021                 :            :      ((c) >= 'a' && (c) <= 'z') ||     \
        4022                 :            :      ((c) >= '0' && (c) <= '9') ||     \
        4023                 :            :      (c) == '+' || (c) == '/')
        4024                 :            :
        4025                 :            : /* given that c is a base-64 character, what is its base-64 value? */
        4026                 :            :
        4027                 :            : #define FROM_BASE64(c)                                                  \
        4028                 :            :     (((c) >= 'A' && (c) <= 'Z') ? (c) - 'A' :                           \
        4029                 :            :      ((c) >= 'a' && (c) <= 'z') ? (c) - 'a' + 26 :                      \
        4030                 :            :      ((c) >= '0' && (c) <= '9') ? (c) - '0' + 52 :                      \
        4031                 :            :      (c) == '+' ? 62 : 63)
        4032                 :            :
        4033                 :            : /* What is the base-64 character of the bottom 6 bits of n? */
        4034                 :            :
        4035                 :            : #define TO_BASE64(n)  \
        4036                 :            :     ("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"[(n) & 0x3f])
        4037                 :            :
        4038                 :            : /* DECODE_DIRECT: this byte encountered in a UTF-7 string should be
        4039                 :            :  * decoded as itself.  We are permissive on decoding; the only ASCII
        4040                 :            :  * byte not decoding to itself is the + which begins a base64
        4041                 :            :  * string. */
        4042                 :            :
        4043                 :            : #define DECODE_DIRECT(c)                                \
        4044                 :            :     ((c) <= 127 && (c) != '+')
        4045                 :            :
        4046                 :            : /* The UTF-7 encoder treats ASCII characters differently according to
        4047                 :            :  * whether they are Set D, Set O, Whitespace, or special (i.e. none of
        4048                 :            :  * the above).  See RFC2152.  This array identifies these different
        4049                 :            :  * sets:
        4050                 :            :  * 0 : "Set D"
        4051                 :            :  *     alphanumeric and '(),-./:?
        4052                 :            :  * 1 : "Set O"
        4053                 :            :  *     !"#$%&*;<=>@[]^_`{|}
        4054                 :            :  * 2 : "whitespace"
        4055                 :            :  *     ht nl cr sp
        4056                 :            :  * 3 : special (must be base64 encoded)
        4057                 :            :  *     everything else (i.e. +\~ and non-printing codes 0-8 11-12 14-31 127)
        4058                 :            :  */
        4059                 :            :
        4060                 :            : static
        4061                 :            : char utf7_category[128] = {
        4062                 :            : /* nul soh stx etx eot enq ack bel bs  ht  nl  vt  np  cr  so  si  */
        4063                 :            :     3,  3,  3,  3,  3,  3,  3,  3,  3,  2,  2,  3,  3,  2,  3,  3,
        4064                 :            : /* dle dc1 dc2 dc3 dc4 nak syn etb can em  sub esc fs  gs  rs  us  */
        4065                 :            :     3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,  3,
        4066                 :            : /* sp   !   "   #   $   %   &   '   (   )   *   +   ,   -   .   /  */
        4067                 :            :     2,  1,  1,  1,  1,  1,  1,  0,  0,  0,  1,  3,  0,  0,  0,  0,
        4068                 :            : /*  0   1   2   3   4   5   6   7   8   9   :   ;   <   =   >   ?  */
        4069                 :            :     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  1,  1,  1,  0,
        4070                 :            : /*  @   A   B   C   D   E   F   G   H   I   J   K   L   M   N   O  */
        4071                 :            :     1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
        4072                 :            : /*  P   Q   R   S   T   U   V   W   X   Y   Z   [   \   ]   ^   _  */
        4073                 :            :     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  3,  1,  1,  1,
        4074                 :            : /*  `   a   b   c   d   e   f   g   h   i   j   k   l   m   n   o  */
        4075                 :            :     1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
        4076                 :            : /*  p   q   r   s   t   u   v   w   x   y   z   {   |   }   ~  del */
        4077                 :            :     0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  1,  1,  3,  3,
        4078                 :            : };
        4079                 :            :
        4080                 :            : /* ENCODE_DIRECT: this character should be encoded as itself.  The
        4081                 :            :  * answer depends on whether we are encoding set O as itself, and also
        4082                 :            :  * on whether we are encoding whitespace as itself.  RFC2152 makes it
        4083                 :            :  * clear that the answers to these questions vary between
        4084                 :            :  * applications, so this code needs to be flexible.  */
        4085                 :            :
        4086                 :            : #define ENCODE_DIRECT(c, directO, directWS)             \
        4087                 :            :     ((c) < 128 && (c) > 0 &&                            \
        4088                 :            :      ((utf7_category[(c)] == 0) ||                      \
        4089                 :            :       (directWS && (utf7_category[(c)] == 2)) ||        \
        4090                 :            :       (directO && (utf7_category[(c)] == 1))))
        4091                 :            :
        4092                 :            : PyObject *
        4093                 :          0 : PyUnicode_DecodeUTF7(const char *s,
        4094                 :            :                      Py_ssize_t size,
        4095                 :            :                      const char *errors)
        4096                 :            : {
        4097                 :          0 :     return PyUnicode_DecodeUTF7Stateful(s, size, errors, NULL);
        4098                 :            : }
        4099                 :            :
        4100                 :            : /* The decoder.  The only state we preserve is our read position,
        4101                 :            :  * i.e. how many characters we have consumed.  So if we end in the
        4102                 :            :  * middle of a shift sequence we have to back off the read position
        4103                 :            :  * and the output to the beginning of the sequence, otherwise we lose
        4104                 :            :  * all the shift state (seen bits, number of bits seen, high
        4105                 :            :  * surrogate). */
        4106                 :            :
        4107                 :            : PyObject *
        4108                 :          0 : PyUnicode_DecodeUTF7Stateful(const char *s,
        4109                 :            :                              Py_ssize_t size,
        4110                 :            :                              const char *errors,
        4111                 :            :                              Py_ssize_t *consumed)
        4112                 :            : {
        4113                 :          0 :     const char *starts = s;
        4114                 :            :     Py_ssize_t startinpos;
        4115                 :            :     Py_ssize_t endinpos;
        4116                 :            :     const char *e;
        4117                 :            :     _PyUnicodeWriter writer;
        4118                 :          0 :     const char *errmsg = "";
        4119                 :          0 :     int inShift = 0;
        4120                 :            :     Py_ssize_t shiftOutStart;
        4121                 :          0 :     unsigned int base64bits = 0;
        4122                 :          0 :     unsigned long base64buffer = 0;
        4123                 :          0 :     Py_UCS4 surrogate = 0;
        4124                 :          0 :     PyObject *errorHandler = NULL;
        4125                 :          0 :     PyObject *exc = NULL;
        4126                 :            :
        4127         [ #  # ]:          0 :     if (size == 0) {
        4128         [ #  # ]:          0 :         if (consumed)
        4129                 :          0 :             *consumed = 0;
        4130                 :          0 :         _Py_RETURN_UNICODE_EMPTY();
        4131                 :            :     }
        4132                 :            :
        4133                 :            :     /* Start off assuming it's all ASCII. Widen later as necessary. */
        4134                 :          0 :     _PyUnicodeWriter_Init(&writer);
        4135                 :          0 :     writer.min_length = size;
        4136                 :            :
        4137                 :          0 :     shiftOutStart = 0;
        4138                 :          0 :     e = s + size;
        4139                 :            :
        4140         [ #  # ]:          0 :     while (s < e) {
        4141                 :            :         Py_UCS4 ch;
        4142                 :          0 :       restart:
        4143                 :          0 :         ch = (unsigned char) *s;
        4144                 :            :
        4145         [ #  # ]:          0 :         if (inShift) { /* in a base-64 section */
        4146   [ #  #  #  #  :          0 :             if (IS_BASE64(ch)) { /* consume a base-64 character */
              #  #  #  #  #
              #  #  #  #  #
                       #  # ]
        4147   [ #  #  #  #  :          0 :                 base64buffer = (base64buffer << 6) | FROM_BASE64(ch);
              #  #  #  #  #
                 #  #  #  #
                          # ]
        4148                 :          0 :                 base64bits += 6;
        4149                 :          0 :                 s++;
        4150         [ #  # ]:          0 :                 if (base64bits >= 16) {
        4151                 :            :                     /* we have enough bits for a UTF-16 value */
        4152                 :          0 :                     Py_UCS4 outCh = (Py_UCS4)(base64buffer >> (base64bits-16));
        4153                 :          0 :                     base64bits -= 16;
        4154                 :          0 :                     base64buffer &= (1 << base64bits) - 1; /* clear high bits */
        4155                 :            :                     assert(outCh <= 0xffff);
        4156         [ #  # ]:          0 :                     if (surrogate) {
        4157                 :            :                         /* expecting a second surrogate */
        4158         [ #  # ]:          0 :                         if (Py_UNICODE_IS_LOW_SURROGATE(outCh)) {
        4159                 :          0 :                             Py_UCS4 ch2 = Py_UNICODE_JOIN_SURROGATES(surrogate, outCh);
        4160         [ #  # ]:          0 :                             if (_PyUnicodeWriter_WriteCharInline(&writer, ch2) < 0)
        4161                 :          0 :                                 goto onError;
        4162                 :          0 :                             surrogate = 0;
        4163                 :          0 :                             continue;
        4164                 :            :                         }
        4165                 :            :                         else {
        4166         [ #  # ]:          0 :                             if (_PyUnicodeWriter_WriteCharInline(&writer, surrogate) < 0)
        4167                 :          0 :                                 goto onError;
        4168                 :          0 :                             surrogate = 0;
        4169                 :            :                         }
        4170                 :            :                     }
        4171         [ #  # ]:          0 :                     if (Py_UNICODE_IS_HIGH_SURROGATE(outCh)) {
        4172                 :            :                         /* first surrogate */
        4173                 :          0 :                         surrogate = outCh;
        4174                 :            :                     }
        4175                 :            :                     else {
        4176         [ #  # ]:          0 :                         if (_PyUnicodeWriter_WriteCharInline(&writer, outCh) < 0)
        4177                 :          0 :                             goto onError;
        4178                 :            :                     }
        4179                 :            :                 }
        4180                 :            :             }
        4181                 :            :             else { /* now leaving a base-64 section */
        4182                 :          0 :                 inShift = 0;
        4183         [ #  # ]:          0 :                 if (base64bits > 0) { /* left-over bits */
        4184         [ #  # ]:          0 :                     if (base64bits >= 6) {
        4185                 :            :                         /* We've seen at least one base-64 character */
        4186                 :          0 :                         s++;
        4187                 :          0 :                         errmsg = "partial character in shift sequence";
        4188                 :          0 :                         goto utf7Error;
        4189                 :            :                     }
        4190                 :            :                     else {
        4191                 :            :                         /* Some bits remain; they should be zero */
        4192         [ #  # ]:          0 :                         if (base64buffer != 0) {
        4193                 :          0 :                             s++;
        4194                 :          0 :                             errmsg = "non-zero padding bits in shift sequence";
        4195                 :          0 :                             goto utf7Error;
        4196                 :            :                         }
        4197                 :            :                     }
        4198                 :            :                 }
        4199   [ #  #  #  #  :          0 :                 if (surrogate && DECODE_DIRECT(ch)) {
                       #  # ]
        4200         [ #  # ]:          0 :                     if (_PyUnicodeWriter_WriteCharInline(&writer, surrogate) < 0)
        4201                 :          0 :                         goto onError;
        4202                 :            :                 }
        4203                 :          0 :                 surrogate = 0;
        4204         [ #  # ]:          0 :                 if (ch == '-') {
        4205                 :            :                     /* '-' is absorbed; other terminating
        4206                 :            :                        characters are preserved */
        4207                 :          0 :                     s++;
        4208                 :            :                 }
        4209                 :            :             }
        4210                 :            :         }
        4211         [ #  # ]:          0 :         else if ( ch == '+' ) {
        4212                 :          0 :             startinpos = s-starts;
        4213                 :          0 :             s++; /* consume '+' */
        4214   [ #  #  #  # ]:          0 :             if (s < e && *s == '-') { /* '+-' encodes '+' */
        4215                 :          0 :                 s++;
        4216         [ #  # ]:          0 :                 if (_PyUnicodeWriter_WriteCharInline(&writer, '+') < 0)
        4217                 :          0 :                     goto onError;
        4218                 :            :             }
        4219   [ #  #  #  #  :          0 :             else if (s < e && !IS_BASE64(*s)) {
              #  #  #  #  #
              #  #  #  #  #
                 #  #  #  # ]
        4220                 :          0 :                 s++;
        4221                 :          0 :                 errmsg = "ill-formed sequence";
        4222                 :          0 :                 goto utf7Error;
        4223                 :            :             }
        4224                 :            :             else { /* begin base64-encoded section */
        4225                 :          0 :                 inShift = 1;
        4226                 :          0 :                 surrogate = 0;
        4227                 :          0 :                 shiftOutStart = writer.pos;
        4228                 :          0 :                 base64bits = 0;
        4229                 :          0 :                 base64buffer = 0;
        4230                 :            :             }
        4231                 :            :         }
        4232   [ #  #  #  # ]:          0 :         else if (DECODE_DIRECT(ch)) { /* character decodes as itself */
        4233                 :          0 :             s++;
        4234         [ #  # ]:          0 :             if (_PyUnicodeWriter_WriteCharInline(&writer, ch) < 0)
        4235                 :          0 :                 goto onError;
        4236                 :            :         }
        4237                 :            :         else {
        4238                 :          0 :             startinpos = s-starts;
        4239                 :          0 :             s++;
        4240                 :          0 :             errmsg = "unexpected special character";
        4241                 :          0 :             goto utf7Error;
        4242                 :            :         }
        4243                 :          0 :         continue;
        4244                 :          0 : utf7Error:
        4245                 :          0 :         endinpos = s-starts;
        4246         [ #  # ]:          0 :         if (unicode_decode_call_errorhandler_writer(
        4247                 :            :                 errors, &errorHandler,
        4248                 :            :                 "utf7", errmsg,
        4249                 :            :                 &starts, &e, &startinpos, &endinpos, &exc, &s,
        4250                 :            :                 &writer))
        4251                 :          0 :             goto onError;
        4252                 :            :     }
        4253                 :            :
        4254                 :            :     /* end of string */
        4255                 :            :
        4256   [ #  #  #  # ]:          0 :     if (inShift && !consumed) { /* in shift sequence, no more to follow */
        4257                 :            :         /* if we're in an inconsistent state, that's an error */
        4258                 :          0 :         inShift = 0;
        4259   [ #  #  #  # ]:          0 :         if (surrogate ||
        4260         [ #  # ]:          0 :                 (base64bits >= 6) ||
        4261         [ #  # ]:          0 :                 (base64bits > 0 && base64buffer != 0)) {
        4262                 :          0 :             endinpos = size;
        4263         [ #  # ]:          0 :             if (unicode_decode_call_errorhandler_writer(
        4264                 :            :                     errors, &errorHandler,
        4265                 :            :                     "utf7", "unterminated shift sequence",
        4266                 :            :                     &starts, &e, &startinpos, &endinpos, &exc, &s,
        4267                 :            :                     &writer))
        4268                 :          0 :                 goto onError;
        4269         [ #  # ]:          0 :             if (s < e)
        4270                 :          0 :                 goto restart;
        4271                 :            :         }
        4272                 :            :     }
        4273                 :            :
        4274                 :            :     /* return state */
        4275         [ #  # ]:          0 :     if (consumed) {
        4276         [ #  # ]:          0 :         if (inShift) {
        4277                 :          0 :             *consumed = startinpos;
        4278   [ #  #  #  # ]:          0 :             if (writer.pos != shiftOutStart && writer.maxchar > 127) {
        4279                 :          0 :                 PyObject *result = PyUnicode_FromKindAndData(
        4280                 :          0 :                         writer.kind, writer.data, shiftOutStart);
        4281                 :          0 :                 Py_XDECREF(errorHandler);
        4282                 :          0 :                 Py_XDECREF(exc);
        4283                 :          0 :                 _PyUnicodeWriter_Dealloc(&writer);
        4284                 :          0 :                 return result;
        4285                 :            :             }
        4286                 :          0 :             writer.pos = shiftOutStart; /* back off output */
        4287                 :            :         }
        4288                 :            :         else {
        4289                 :          0 :             *consumed = s-starts;
        4290                 :            :         }
        4291                 :            :     }
        4292                 :            :
        4293                 :          0 :     Py_XDECREF(errorHandler);
        4294                 :          0 :     Py_XDECREF(exc);
        4295                 :          0 :     return _PyUnicodeWriter_Finish(&writer);
        4296                 :            :
        4297                 :          0 :   onError:
        4298                 :          0 :     Py_XDECREF(errorHandler);
        4299                 :          0 :     Py_XDECREF(exc);
        4300                 :          0 :     _PyUnicodeWriter_Dealloc(&writer);
        4301                 :          0 :     return NULL;
        4302                 :            : }
        4303                 :            :
        4304                 :            :
        4305                 :            : PyObject *
        4306                 :          0 : _PyUnicode_EncodeUTF7(PyObject *str,
        4307                 :            :                       int base64SetO,
        4308                 :            :                       int base64WhiteSpace,
        4309                 :            :                       const char *errors)
        4310                 :            : {
        4311                 :            :     int kind;
        4312                 :            :     const void *data;
        4313                 :            :     Py_ssize_t len;
        4314                 :            :     PyObject *v;
        4315                 :          0 :     int inShift = 0;
        4316                 :            :     Py_ssize_t i;
        4317                 :          0 :     unsigned int base64bits = 0;
        4318                 :          0 :     unsigned long base64buffer = 0;
        4319                 :            :     char * out;
        4320                 :            :     const char * start;
        4321                 :            :
        4322                 :          0 :     kind = PyUnicode_KIND(str);
        4323                 :          0 :     data = PyUnicode_DATA(str);
        4324                 :          0 :     len = PyUnicode_GET_LENGTH(str);
        4325                 :            :
        4326         [ #  # ]:          0 :     if (len == 0)
        4327                 :          0 :         return PyBytes_FromStringAndSize(NULL, 0);
        4328                 :            :
        4329                 :            :     /* It might be possible to tighten this worst case */
        4330         [ #  # ]:          0 :     if (len > PY_SSIZE_T_MAX / 8)
        4331                 :          0 :         return PyErr_NoMemory();
        4332                 :          0 :     v = PyBytes_FromStringAndSize(NULL, len * 8);
        4333         [ #  # ]:          0 :     if (v == NULL)
        4334                 :          0 :         return NULL;
        4335                 :            :
        4336                 :          0 :     start = out = PyBytes_AS_STRING(v);
        4337         [ #  # ]:          0 :     for (i = 0; i < len; ++i) {
        4338                 :          0 :         Py_UCS4 ch = PyUnicode_READ(kind, data, i);
        4339                 :            :
        4340         [ #  # ]:          0 :         if (inShift) {
        4341   [ #  #  #  #  :          0 :             if (ENCODE_DIRECT(ch, !base64SetO, !base64WhiteSpace)) {
              #  #  #  #  #
                 #  #  #  #
                          # ]
        4342                 :            :                 /* shifting out */
        4343         [ #  # ]:          0 :                 if (base64bits) { /* output remaining bits */
        4344                 :          0 :                     *out++ = TO_BASE64(base64buffer << (6-base64bits));
        4345                 :          0 :                     base64buffer = 0;
        4346                 :          0 :                     base64bits = 0;
        4347                 :            :                 }
        4348                 :          0 :                 inShift = 0;
        4349                 :            :                 /* Characters not in the BASE64 set implicitly unshift the sequence
        4350                 :            :                    so no '-' is required, except if the character is itself a '-' */
        4351   [ #  #  #  #  :          0 :                 if (IS_BASE64(ch) || ch == '-') {
              #  #  #  #  #
              #  #  #  #  #
                 #  #  #  # ]
        4352                 :          0 :                     *out++ = '-';
        4353                 :            :                 }
        4354                 :          0 :                 *out++ = (char) ch;
        4355                 :            :             }
        4356                 :            :             else {
        4357                 :          0 :                 goto encode_char;
        4358                 :            :             }
        4359                 :            :         }
        4360                 :            :         else { /* not in a shift sequence */
        4361         [ #  # ]:          0 :             if (ch == '+') {
        4362                 :          0 :                 *out++ = '+';
        4363                 :          0 :                         *out++ = '-';
        4364                 :            :             }
        4365   [ #  #  #  #  :          0 :             else if (ENCODE_DIRECT(ch, !base64SetO, !base64WhiteSpace)) {
              #  #  #  #  #
                 #  #  #  #
                          # ]
        4366                 :          0 :                 *out++ = (char) ch;
        4367                 :            :             }
        4368                 :            :             else {
        4369                 :          0 :                 *out++ = '+';
        4370                 :          0 :                 inShift = 1;
        4371                 :          0 :                 goto encode_char;
        4372                 :            :             }
        4373                 :            :         }
        4374                 :          0 :         continue;
        4375                 :          0 : encode_char:
        4376         [ #  # ]:          0 :         if (ch >= 0x10000) {
        4377                 :            :             assert(ch <= MAX_UNICODE);
        4378                 :            :
        4379                 :            :             /* code first surrogate */
        4380                 :          0 :             base64bits += 16;
        4381                 :          0 :             base64buffer = (base64buffer << 16) | Py_UNICODE_HIGH_SURROGATE(ch);
        4382         [ #  # ]:          0 :             while (base64bits >= 6) {
        4383                 :          0 :                 *out++ = TO_BASE64(base64buffer >> (base64bits-6));
        4384                 :          0 :                 base64bits -= 6;
        4385                 :            :             }
        4386                 :            :             /* prepare second surrogate */
        4387                 :          0 :             ch = Py_UNICODE_LOW_SURROGATE(ch);
        4388                 :            :         }
        4389                 :          0 :         base64bits += 16;
        4390                 :          0 :         base64buffer = (base64buffer << 16) | ch;
        4391         [ #  # ]:          0 :         while (base64bits >= 6) {
        4392                 :          0 :             *out++ = TO_BASE64(base64buffer >> (base64bits-6));
        4393                 :          0 :             base64bits -= 6;
        4394                 :            :         }
        4395                 :            :     }
        4396         [ #  # ]:          0 :     if (base64bits)
        4397                 :          0 :         *out++= TO_BASE64(base64buffer << (6-base64bits) );
        4398         [ #  # ]:          0 :     if (inShift)
        4399                 :          0 :         *out++ = '-';
        4400         [ #  # ]:          0 :     if (_PyBytes_Resize(&v, out - start) < 0)
        4401                 :          0 :         return NULL;
        4402                 :          0 :     return v;
        4403                 :            : }
        4404                 :            :
        4405                 :            : #undef IS_BASE64
        4406                 :            : #undef FROM_BASE64
        4407                 :            : #undef TO_BASE64
        4408                 :            : #undef DECODE_DIRECT
        4409                 :            : #undef ENCODE_DIRECT
        4410                 :            :
        4411                 :            : /* --- UTF-8 Codec -------------------------------------------------------- */
        4412                 :            :
        4413                 :            : PyObject *
        4414                 :     534498 : PyUnicode_DecodeUTF8(const char *s,
        4415                 :            :                      Py_ssize_t size,
        4416                 :            :                      const char *errors)
        4417                 :            : {
        4418                 :     534498 :     return PyUnicode_DecodeUTF8Stateful(s, size, errors, NULL);
        4419                 :            : }
        4420                 :            :
        4421                 :            : #include "stringlib/asciilib.h"
        4422                 :            : #include "stringlib/codecs.h"
        4423                 :            : #include "stringlib/undef.h"
        4424                 :            :
        4425                 :            : #include "stringlib/ucs1lib.h"
        4426                 :            : #include "stringlib/codecs.h"
        4427                 :            : #include "stringlib/undef.h"
        4428                 :            :
        4429                 :            : #include "stringlib/ucs2lib.h"
        4430                 :            : #include "stringlib/codecs.h"
        4431                 :            : #include "stringlib/undef.h"
        4432                 :            :
        4433                 :            : #include "stringlib/ucs4lib.h"
        4434                 :            : #include "stringlib/codecs.h"
        4435                 :            : #include "stringlib/undef.h"
        4436                 :            :
        4437                 :            : /* Mask to quickly check whether a C 'size_t' contains a
        4438                 :            :    non-ASCII, UTF8-encoded char. */
        4439                 :            : #if (SIZEOF_SIZE_T == 8)
        4440                 :            : # define ASCII_CHAR_MASK 0x8080808080808080ULL
        4441                 :            : #elif (SIZEOF_SIZE_T == 4)
        4442                 :            : # define ASCII_CHAR_MASK 0x80808080U
        4443                 :            : #else
        4444                 :            : # error C 'size_t' size should be either 4 or 8!
        4445                 :            : #endif
        4446                 :            :
        4447                 :            : static Py_ssize_t
        4448                 :    2162562 : ascii_decode(const char *start, const char *end, Py_UCS1 *dest)
        4449                 :            : {
        4450                 :    2162562 :     const char *p = start;
        4451                 :            :
        4452                 :            : #if SIZEOF_SIZE_T <= SIZEOF_VOID_P
        4453                 :            :     assert(_Py_IS_ALIGNED(dest, ALIGNOF_SIZE_T));
        4454         [ +  + ]:    2162562 :     if (_Py_IS_ALIGNED(p, ALIGNOF_SIZE_T)) {
        4455                 :            :         /* Fast path, see in STRINGLIB(utf8_decode) for
        4456                 :            :            an explanation. */
        4457                 :            :         /* Help allocation */
        4458                 :     566069 :         const char *_p = p;
        4459                 :     566069 :         Py_UCS1 * q = dest;
        4460         [ +  + ]:    4225999 :         while (_p + SIZEOF_SIZE_T <= end) {
        4461                 :    3659975 :             size_t value = *(const size_t *) _p;
        4462         [ +  + ]:    3659975 :             if (value & ASCII_CHAR_MASK)
        4463                 :         45 :                 break;
        4464                 :    3659930 :             *((size_t *)q) = value;
        4465                 :    3659930 :             _p += SIZEOF_SIZE_T;
        4466                 :    3659930 :             q += SIZEOF_SIZE_T;
        4467                 :            :         }
        4468                 :     566069 :         p = _p;
        4469         [ +  + ]:    2730864 :         while (p < end) {
        4470         [ +  + ]:    2164857 :             if ((unsigned char)*p & 0x80)
        4471                 :         62 :                 break;
        4472                 :    2164795 :             *q++ = *p++;
        4473                 :            :         }
        4474                 :     566069 :         return p - start;
        4475                 :            :     }
        4476                 :            : #endif
        4477         [ +  + ]:   11303477 :     while (p < end) {
        4478                 :            :         /* Fast path, see in STRINGLIB(utf8_decode) in stringlib/codecs.h
        4479                 :            :            for an explanation. */
        4480         [ +  + ]:    9716775 :         if (_Py_IS_ALIGNED(p, ALIGNOF_SIZE_T)) {
        4481                 :            :             /* Help allocation */
        4482                 :    1570188 :             const char *_p = p;
        4483         [ +  + ]:    1750246 :             while (_p + SIZEOF_SIZE_T <= end) {
        4484                 :     180083 :                 size_t value = *(const size_t *) _p;
        4485         [ +  + ]:     180083 :                 if (value & ASCII_CHAR_MASK)
        4486                 :         25 :                     break;
        4487                 :     180058 :                 _p += SIZEOF_SIZE_T;
        4488                 :            :             }
        4489                 :    1570188 :             p = _p;
        4490         [ +  + ]:    1570188 :             if (_p == end)
        4491                 :       9760 :                 break;
        4492                 :            :         }
        4493         [ +  + ]:    9707015 :         if ((unsigned char)*p & 0x80)
        4494                 :         31 :             break;
        4495                 :    9706984 :         ++p;
        4496                 :            :     }
        4497                 :    1596493 :     memcpy(dest, start, p - start);
        4498                 :    1596493 :     return p - start;
        4499                 :            : }
        4500                 :            :
        4501                 :            : static PyObject *
        4502                 :    2184272 : unicode_decode_utf8(const char *s, Py_ssize_t size,
        4503                 :            :                     _Py_error_handler error_handler, const char *errors,
        4504                 :            :                     Py_ssize_t *consumed)
        4505                 :            : {
        4506         [ +  + ]:    2184272 :     if (size == 0) {
        4507         [ -  + ]:       1344 :         if (consumed)
        4508                 :          0 :             *consumed = 0;
        4509                 :       1344 :         _Py_RETURN_UNICODE_EMPTY();
        4510                 :            :     }
        4511                 :            :
        4512                 :            :     /* ASCII is equivalent to the first 128 ordinals in Unicode. */
        4513   [ +  +  +  + ]:    2182928 :     if (size == 1 && (unsigned char)s[0] < 128) {
        4514         [ -  + ]:      30777 :         if (consumed) {
        4515                 :          0 :             *consumed = 1;
        4516                 :            :         }
        4517                 :      30777 :         return get_latin1_char((unsigned char)s[0]);
        4518                 :            :     }
        4519                 :            :
        4520                 :    2152151 :     const char *starts = s;
        4521                 :    2152151 :     const char *end = s + size;
        4522                 :            :
        4523                 :            :     // fast path: try ASCII string.
        4524                 :    2152151 :     PyObject *u = PyUnicode_New(size, 127);
        4525         [ -  + ]:    2152151 :     if (u == NULL) {
        4526                 :          0 :         return NULL;
        4527                 :            :     }
        4528                 :    2152151 :     s += ascii_decode(s, end, PyUnicode_1BYTE_DATA(u));
        4529         [ +  + ]:    2152151 :     if (s == end) {
        4530         [ +  + ]:    2152058 :         if (consumed) {
        4531                 :       3400 :             *consumed = size;
        4532                 :            :         }
        4533                 :    2152058 :         return u;
        4534                 :            :     }
        4535                 :            :
        4536                 :            :     // Use _PyUnicodeWriter after fast path is failed.
        4537                 :            :     _PyUnicodeWriter writer;
        4538                 :         93 :     _PyUnicodeWriter_InitWithBuffer(&writer, u);
        4539                 :         93 :     writer.pos = s - starts;
        4540                 :            :
        4541                 :            :     Py_ssize_t startinpos, endinpos;
        4542                 :         93 :     const char *errmsg = "";
        4543                 :         93 :     PyObject *error_handler_obj = NULL;
        4544                 :         93 :     PyObject *exc = NULL;
        4545                 :            :
        4546         [ +  + ]:        211 :     while (s < end) {
        4547                 :            :         Py_UCS4 ch;
        4548                 :        196 :         int kind = writer.kind;
        4549                 :            :
        4550         [ +  + ]:        196 :         if (kind == PyUnicode_1BYTE_KIND) {
        4551         [ +  + ]:        156 :             if (PyUnicode_IS_ASCII(writer.buffer))
        4552                 :         93 :                 ch = asciilib_utf8_decode(&s, end, writer.data, &writer.pos);
        4553                 :            :             else
        4554                 :         63 :                 ch = ucs1lib_utf8_decode(&s, end, writer.data, &writer.pos);
        4555         [ +  - ]:         40 :         } else if (kind == PyUnicode_2BYTE_KIND) {
        4556                 :         40 :             ch = ucs2lib_utf8_decode(&s, end, writer.data, &writer.pos);
        4557                 :            :         } else {
        4558                 :            :             assert(kind == PyUnicode_4BYTE_KIND);
        4559                 :          0 :             ch = ucs4lib_utf8_decode(&s, end, writer.data, &writer.pos);
        4560                 :            :         }
        4561                 :            :
        4562   [ +  +  +  -  :        196 :         switch (ch) {
                          + ]
        4563                 :         81 :         case 0:
        4564   [ +  +  -  + ]:         81 :             if (s == end || consumed)
        4565                 :         76 :                 goto End;
        4566                 :          5 :             errmsg = "unexpected end of data";
        4567                 :          5 :             startinpos = s - starts;
        4568                 :          5 :             endinpos = end - starts;
        4569                 :          5 :             break;
        4570                 :          2 :         case 1:
        4571                 :          2 :             errmsg = "invalid start byte";
        4572                 :          2 :             startinpos = s - starts;
        4573                 :          2 :             endinpos = startinpos + 1;
        4574                 :          2 :             break;
        4575                 :          6 :         case 2:
        4576   [ -  +  -  -  :          6 :             if (consumed && (unsigned char)s[0] == 0xED && end - s == 2
                       -  - ]
        4577   [ #  #  #  # ]:          0 :                 && (unsigned char)s[1] >= 0xA0 && (unsigned char)s[1] <= 0xBF)
        4578                 :            :             {
        4579                 :            :                 /* Truncated surrogate code in range D800-DFFF */
        4580                 :          0 :                 goto End;
        4581                 :            :             }
        4582                 :            :             /* fall through */
        4583                 :            :         case 3:
        4584                 :            :         case 4:
        4585                 :          6 :             errmsg = "invalid continuation byte";
        4586                 :          6 :             startinpos = s - starts;
        4587                 :          6 :             endinpos = startinpos + ch - 1;
        4588                 :          6 :             break;
        4589                 :        107 :         default:
        4590         [ -  + ]:        107 :             if (_PyUnicodeWriter_WriteCharInline(&writer, ch) < 0)
        4591                 :          0 :                 goto onError;
        4592                 :        107 :             continue;
        4593                 :            :         }
        4594                 :            :
        4595         [ +  + ]:         13 :         if (error_handler == _Py_ERROR_UNKNOWN)
        4596                 :          8 :             error_handler = _Py_GetErrorHandler(errors);
        4597                 :            :
        4598   [ -  -  +  + ]:         13 :         switch (error_handler) {
        4599                 :          0 :         case _Py_ERROR_IGNORE:
        4600                 :          0 :             s += (endinpos - startinpos);
        4601                 :          0 :             break;
        4602                 :            :
        4603                 :          0 :         case _Py_ERROR_REPLACE:
        4604         [ #  # ]:          0 :             if (_PyUnicodeWriter_WriteCharInline(&writer, 0xfffd) < 0)
        4605                 :          0 :                 goto onError;
        4606                 :          0 :             s += (endinpos - startinpos);
        4607                 :          0 :             break;
        4608                 :            :
        4609                 :         11 :         case _Py_ERROR_SURROGATEESCAPE:
        4610                 :            :         {
        4611                 :            :             Py_ssize_t i;
        4612                 :            :
        4613   [ +  +  -  + ]:         11 :             if (_PyUnicodeWriter_PrepareKind(&writer, PyUnicode_2BYTE_KIND) < 0)
        4614                 :          0 :                 goto onError;
        4615         [ +  + ]:         22 :             for (i=startinpos; i<endinpos; i++) {
        4616                 :         11 :                 ch = (Py_UCS4)(unsigned char)(starts[i]);
        4617                 :         11 :                 PyUnicode_WRITE(writer.kind, writer.data, writer.pos,
        4618                 :            :                                 ch + 0xdc00);
        4619                 :         11 :                 writer.pos++;
        4620                 :            :             }
        4621                 :         11 :             s += (endinpos - startinpos);
        4622                 :         11 :             break;
        4623                 :            :         }
        4624                 :            :
        4625                 :          2 :         default:
        4626         [ +  - ]:          2 :             if (unicode_decode_call_errorhandler_writer(
        4627                 :            :                     errors, &error_handler_obj,
        4628                 :            :                     "utf-8", errmsg,
        4629                 :            :                     &starts, &end, &startinpos, &endinpos, &exc, &s,
        4630                 :            :                     &writer))
        4631                 :          2 :                 goto onError;
        4632                 :            :         }
        4633                 :            :     }
        4634                 :            :
        4635                 :         15 : End:
        4636         [ +  + ]:         91 :     if (consumed)
        4637                 :         39 :         *consumed = s - starts;
        4638                 :            :
        4639                 :         91 :     Py_XDECREF(error_handler_obj);
        4640                 :         91 :     Py_XDECREF(exc);
        4641                 :         91 :     return _PyUnicodeWriter_Finish(&writer);
        4642                 :            :
        4643                 :          2 : onError:
        4644                 :          2 :     Py_XDECREF(error_handler_obj);
        4645                 :          2 :     Py_XDECREF(exc);
        4646                 :          2 :     _PyUnicodeWriter_Dealloc(&writer);
        4647                 :          2 :     return NULL;
        4648                 :            : }
        4649                 :            :
        4650                 :            :
        4651                 :            : PyObject *
        4652                 :    2182364 : PyUnicode_DecodeUTF8Stateful(const char *s,
        4653                 :            :                              Py_ssize_t size,
        4654                 :            :                              const char *errors,
        4655                 :            :                              Py_ssize_t *consumed)
        4656                 :            : {
        4657                 :    2182364 :     return unicode_decode_utf8(s, size, _Py_ERROR_UNKNOWN, errors, consumed);
        4658                 :            : }
        4659                 :            :
        4660                 :            :
        4661                 :            : /* UTF-8 decoder: use surrogateescape error handler if 'surrogateescape' is
        4662                 :            :    non-zero, use strict error handler otherwise.
        4663                 :            :
        4664                 :            :    On success, write a pointer to a newly allocated wide character string into
        4665                 :            :    *wstr (use PyMem_RawFree() to free the memory) and write the output length
        4666                 :            :    (in number of wchar_t units) into *wlen (if wlen is set).
        4667                 :            :
        4668                 :            :    On memory allocation failure, return -1.
        4669                 :            :
        4670                 :            :    On decoding error (if surrogateescape is zero), return -2. If wlen is
        4671                 :            :    non-NULL, write the start of the illegal byte sequence into *wlen. If reason
        4672                 :            :    is not NULL, write the decoding error message into *reason. */
        4673                 :            : int
        4674                 :          4 : _Py_DecodeUTF8Ex(const char *s, Py_ssize_t size, wchar_t **wstr, size_t *wlen,
        4675                 :            :                  const char **reason, _Py_error_handler errors)
        4676                 :            : {
        4677                 :          4 :     const char *orig_s = s;
        4678                 :            :     const char *e;
        4679                 :            :     wchar_t *unicode;
        4680                 :            :     Py_ssize_t outpos;
        4681                 :            :
        4682                 :          4 :     int surrogateescape = 0;
        4683                 :          4 :     int surrogatepass = 0;
        4684   [ -  +  -  - ]:          4 :     switch (errors)
        4685                 :            :     {
        4686                 :          0 :     case _Py_ERROR_STRICT:
        4687                 :          0 :         break;
        4688                 :          4 :     case _Py_ERROR_SURROGATEESCAPE:
        4689                 :          4 :         surrogateescape = 1;
        4690                 :          4 :         break;
        4691                 :          0 :     case _Py_ERROR_SURROGATEPASS:
        4692                 :          0 :         surrogatepass = 1;
        4693                 :          0 :         break;
        4694                 :          0 :     default:
        4695                 :          0 :         return -3;
        4696                 :            :     }
        4697                 :            :
        4698                 :            :     /* Note: size will always be longer than the resulting Unicode
        4699                 :            :        character count */
        4700         [ -  + ]:          4 :     if (PY_SSIZE_T_MAX / (Py_ssize_t)sizeof(wchar_t) - 1 < size) {
        4701                 :          0 :         return -1;
        4702                 :            :     }
        4703                 :            :
        4704                 :          4 :     unicode = PyMem_RawMalloc((size + 1) * sizeof(wchar_t));
        4705         [ -  + ]:          4 :     if (!unicode) {
        4706                 :          0 :         return -1;
        4707                 :            :     }
        4708                 :            :
        4709                 :            :     /* Unpack UTF-8 encoded data */
        4710                 :          4 :     e = s + size;
        4711                 :          4 :     outpos = 0;
        4712         [ +  - ]:          4 :     while (s < e) {
        4713                 :            :         Py_UCS4 ch;
        4714                 :            : #if SIZEOF_WCHAR_T == 4
        4715                 :          4 :         ch = ucs4lib_utf8_decode(&s, e, (Py_UCS4 *)unicode, &outpos);
        4716                 :            : #else
        4717                 :            :         ch = ucs2lib_utf8_decode(&s, e, (Py_UCS2 *)unicode, &outpos);
        4718                 :            : #endif
        4719         [ -  + ]:          4 :         if (ch > 0xFF) {
        4720                 :            : #if SIZEOF_WCHAR_T == 4
        4721                 :          0 :             Py_UNREACHABLE();
        4722                 :            : #else
        4723                 :            :             assert(ch > 0xFFFF && ch <= MAX_UNICODE);
        4724                 :            :             /* write a surrogate pair */
        4725                 :            :             unicode[outpos++] = (wchar_t)Py_UNICODE_HIGH_SURROGATE(ch);
        4726                 :            :             unicode[outpos++] = (wchar_t)Py_UNICODE_LOW_SURROGATE(ch);
        4727                 :            : #endif
        4728                 :            :         }
        4729                 :            :         else {
        4730   [ +  -  +  - ]:          4 :             if (!ch && s == e) {
        4731                 :          4 :                 break;
        4732                 :            :             }
        4733                 :            :
        4734         [ #  # ]:          0 :             if (surrogateescape) {
        4735                 :          0 :                 unicode[outpos++] = 0xDC00 + (unsigned char)*s++;
        4736                 :            :             }
        4737                 :            :             else {
        4738                 :            :                 /* Is it a valid three-byte code? */
        4739         [ #  # ]:          0 :                 if (surrogatepass
        4740         [ #  # ]:          0 :                     && (e - s) >= 3
        4741         [ #  # ]:          0 :                     && (s[0] & 0xf0) == 0xe0
        4742         [ #  # ]:          0 :                     && (s[1] & 0xc0) == 0x80
        4743         [ #  # ]:          0 :                     && (s[2] & 0xc0) == 0x80)
        4744                 :            :                 {
        4745                 :          0 :                     ch = ((s[0] & 0x0f) << 12) + ((s[1] & 0x3f) << 6) + (s[2] & 0x3f);
        4746                 :          0 :                     s += 3;
        4747                 :          0 :                     unicode[outpos++] = ch;
        4748                 :            :                 }
        4749                 :            :                 else {
        4750                 :          0 :                     PyMem_RawFree(unicode );
        4751         [ #  # ]:          0 :                     if (reason != NULL) {
        4752      [ #  #  # ]:          0 :                         switch (ch) {
        4753                 :          0 :                         case 0:
        4754                 :          0 :                             *reason = "unexpected end of data";
        4755                 :          0 :                             break;
        4756                 :          0 :                         case 1:
        4757                 :          0 :                             *reason = "invalid start byte";
        4758                 :          0 :                             break;
        4759                 :            :                         /* 2, 3, 4 */
        4760                 :          0 :                         default:
        4761                 :          0 :                             *reason = "invalid continuation byte";
        4762                 :          0 :                             break;
        4763                 :            :                         }
        4764                 :          0 :                     }
        4765         [ #  # ]:          0 :                     if (wlen != NULL) {
        4766                 :          0 :                         *wlen = s - orig_s;
        4767                 :            :                     }
        4768                 :          0 :                     return -2;
        4769                 :            :                 }
        4770                 :            :             }
        4771                 :            :         }
        4772                 :            :     }
        4773                 :          4 :     unicode[outpos] = L'\0';
        4774         [ +  - ]:          4 :     if (wlen) {
        4775                 :          4 :         *wlen = outpos;
        4776                 :            :     }
        4777                 :          4 :     *wstr = unicode;
        4778                 :          4 :     return 0;
        4779                 :            : }
        4780                 :            :
        4781                 :            :
        4782                 :            : wchar_t*
        4783                 :          4 : _Py_DecodeUTF8_surrogateescape(const char *arg, Py_ssize_t arglen,
        4784                 :            :                                size_t *wlen)
        4785                 :            : {
        4786                 :            :     wchar_t *wstr;
        4787                 :          4 :     int res = _Py_DecodeUTF8Ex(arg, arglen,
        4788                 :            :                                &wstr, wlen,
        4789                 :            :                                NULL, _Py_ERROR_SURROGATEESCAPE);
        4790         [ -  + ]:          4 :     if (res != 0) {
        4791                 :            :         /* _Py_DecodeUTF8Ex() must support _Py_ERROR_SURROGATEESCAPE */
        4792                 :            :         assert(res != -3);
        4793         [ #  # ]:          0 :         if (wlen) {
        4794                 :          0 :             *wlen = (size_t)res;
        4795                 :            :         }
        4796                 :          0 :         return NULL;
        4797                 :            :     }
        4798                 :          4 :     return wstr;
        4799                 :            : }
        4800                 :            :
        4801                 :            :
        4802                 :            : /* UTF-8 encoder using the surrogateescape error handler .
        4803                 :            :
        4804                 :            :    On success, return 0 and write the newly allocated character string (use
        4805                 :            :    PyMem_Free() to free the memory) into *str.
        4806                 :            :
        4807                 :            :    On encoding failure, return -2 and write the position of the invalid
        4808                 :            :    surrogate character into *error_pos (if error_pos is set) and the decoding
        4809                 :            :    error message into *reason (if reason is set).
        4810                 :            :
        4811                 :            :    On memory allocation failure, return -1. */
        4812                 :            : int
        4813                 :        100 : _Py_EncodeUTF8Ex(const wchar_t *text, char **str, size_t *error_pos,
        4814                 :            :                  const char **reason, int raw_malloc, _Py_error_handler errors)
        4815                 :            : {
        4816                 :        100 :     const Py_ssize_t max_char_size = 4;
        4817                 :        100 :     Py_ssize_t len = wcslen(text);
        4818                 :            :
        4819                 :            :     assert(len >= 0);
        4820                 :            :
        4821                 :        100 :     int surrogateescape = 0;
        4822                 :        100 :     int surrogatepass = 0;
        4823   [ +  -  -  - ]:        100 :     switch (errors)
        4824                 :            :     {
        4825                 :        100 :     case _Py_ERROR_STRICT:
        4826                 :        100 :         break;
        4827                 :          0 :     case _Py_ERROR_SURROGATEESCAPE:
        4828                 :          0 :         surrogateescape = 1;
        4829                 :          0 :         break;
        4830                 :          0 :     case _Py_ERROR_SURROGATEPASS:
        4831                 :          0 :         surrogatepass = 1;
        4832                 :          0 :         break;
        4833                 :          0 :     default:
        4834                 :          0 :         return -3;
        4835                 :            :     }
        4836                 :            :
        4837         [ -  + ]:        100 :     if (len > PY_SSIZE_T_MAX / max_char_size - 1) {
        4838                 :          0 :         return -1;
        4839                 :            :     }
        4840                 :            :     char *bytes;
        4841         [ +  - ]:        100 :     if (raw_malloc) {
        4842                 :        100 :         bytes = PyMem_RawMalloc((len + 1) * max_char_size);
        4843                 :            :     }
        4844                 :            :     else {
        4845                 :          0 :         bytes = PyMem_Malloc((len + 1) * max_char_size);
        4846                 :            :     }
        4847         [ -  + ]:        100 :     if (bytes == NULL) {
        4848                 :          0 :         return -1;
        4849                 :            :     }
        4850                 :            :
        4851                 :        100 :     char *p = bytes;
        4852                 :            :     Py_ssize_t i;
        4853         [ +  + ]:       1228 :     for (i = 0; i < len; ) {
        4854                 :       1128 :         Py_ssize_t ch_pos = i;
        4855                 :       1128 :         Py_UCS4 ch = text[i];
        4856                 :       1128 :         i++;
        4857                 :            : #if Py_UNICODE_SIZE == 2
        4858                 :            :         if (Py_UNICODE_IS_HIGH_SURROGATE(ch)
        4859                 :            :             && i < len
        4860                 :            :             && Py_UNICODE_IS_LOW_SURROGATE(text[i]))
        4861                 :            :         {
        4862                 :            :             ch = Py_UNICODE_JOIN_SURROGATES(ch, text[i]);
        4863                 :            :             i++;
        4864                 :            :         }
        4865                 :            : #endif
        4866                 :            :
        4867         [ +  - ]:       1128 :         if (ch < 0x80) {
        4868                 :            :             /* Encode ASCII */
        4869                 :       1128 :             *p++ = (char) ch;
        4870                 :            :
        4871                 :            :         }
        4872         [ #  # ]:          0 :         else if (ch < 0x0800) {
        4873                 :            :             /* Encode Latin-1 */
        4874                 :          0 :             *p++ = (char)(0xc0 | (ch >> 6));
        4875                 :          0 :             *p++ = (char)(0x80 | (ch & 0x3f));
        4876                 :            :         }
        4877   [ #  #  #  # ]:          0 :         else if (Py_UNICODE_IS_SURROGATE(ch) && !surrogatepass) {
        4878                 :            :             /* surrogateescape error handler */
        4879   [ #  #  #  #  :          0 :             if (!surrogateescape || !(0xDC80 <= ch && ch <= 0xDCFF)) {
                       #  # ]
        4880         [ #  # ]:          0 :                 if (error_pos != NULL) {
        4881                 :          0 :                     *error_pos = (size_t)ch_pos;
        4882                 :            :                 }
        4883         [ #  # ]:          0 :                 if (reason != NULL) {
        4884                 :          0 :                     *reason = "encoding error";
        4885                 :            :                 }
        4886         [ #  # ]:          0 :                 if (raw_malloc) {
        4887                 :          0 :                     PyMem_RawFree(bytes);
        4888                 :            :                 }
        4889                 :            :                 else {
        4890                 :          0 :                     PyMem_Free(bytes);
        4891                 :            :                 }
        4892                 :          0 :                 return -2;
        4893                 :            :             }
        4894                 :          0 :             *p++ = (char)(ch & 0xff);
        4895                 :            :         }
        4896         [ #  # ]:          0 :         else if (ch < 0x10000) {
        4897                 :          0 :             *p++ = (char)(0xe0 | (ch >> 12));
        4898                 :          0 :             *p++ = (char)(0x80 | ((ch >> 6) & 0x3f));
        4899                 :          0 :             *p++ = (char)(0x80 | (ch & 0x3f));
        4900                 :            :         }
        4901                 :            :         else {  /* ch >= 0x10000 */
        4902                 :            :             assert(ch <= MAX_UNICODE);
        4903                 :            :             /* Encode UCS4 Unicode ordinals */
        4904                 :          0 :             *p++ = (char)(0xf0 | (ch >> 18));
        4905                 :          0 :             *p++ = (char)(0x80 | ((ch >> 12) & 0x3f));
        4906                 :          0 :             *p++ = (char)(0x80 | ((ch >> 6) & 0x3f));
        4907                 :          0 :             *p++ = (char)(0x80 | (ch & 0x3f));
        4908                 :            :         }
        4909                 :            :     }
        4910                 :        100 :     *p++ = '\0';
        4911                 :            :
        4912                 :        100 :     size_t final_size = (p - bytes);
        4913                 :            :     char *bytes2;
        4914         [ +  - ]:        100 :     if (raw_malloc) {
        4915                 :        100 :         bytes2 = PyMem_RawRealloc(bytes, final_size);
        4916                 :            :     }
        4917                 :            :     else {
        4918                 :          0 :         bytes2 = PyMem_Realloc(bytes, final_size);
        4919                 :            :     }
        4920         [ -  + ]:        100 :     if (bytes2 == NULL) {
        4921         [ #  # ]:          0 :         if (error_pos != NULL) {
        4922                 :          0 :             *error_pos = (size_t)-1;
        4923                 :            :         }
        4924         [ #  # ]:          0 :         if (raw_malloc) {
        4925                 :          0 :             PyMem_RawFree(bytes);
        4926                 :            :         }
        4927                 :            :         else {
        4928                 :          0 :             PyMem_Free(bytes);
        4929                 :            :         }
        4930                 :          0 :         return -1;
        4931                 :            :     }
        4932                 :        100 :     *str = bytes2;
        4933                 :        100 :     return 0;
        4934                 :            : }
        4935                 :            :
        4936                 :            :
        4937                 :            : /* Primary internal function which creates utf8 encoded bytes objects.
        4938                 :            :
        4939                 :            :    Allocation strategy:  if the string is short, convert into a stack buffer
        4940                 :            :    and allocate exactly as much space needed at the end.  Else allocate the
        4941                 :            :    maximum possible needed (4 result bytes per Unicode character), and return
        4942                 :            :    the excess memory at the end.
        4943                 :            : */
        4944                 :            : static PyObject *
        4945                 :       2933 : unicode_encode_utf8(PyObject *unicode, _Py_error_handler error_handler,
        4946                 :            :                     const char *errors)
        4947                 :            : {
        4948         [ -  + ]:       2933 :     if (!PyUnicode_Check(unicode)) {
        4949                 :          0 :         PyErr_BadArgument();
        4950                 :          0 :         return NULL;
        4951                 :            :     }
        4952                 :            :
        4953   [ +  +  +  + ]:       2933 :     if (PyUnicode_UTF8(unicode))
        4954   [ +  +  +  + ]:       2900 :         return PyBytes_FromStringAndSize(PyUnicode_UTF8(unicode),
        4955                 :       2900 :                                          PyUnicode_UTF8_LENGTH(unicode));
        4956                 :            :
        4957                 :         33 :     int kind = PyUnicode_KIND(unicode);
        4958                 :         33 :     const void *data = PyUnicode_DATA(unicode);
        4959                 :         33 :     Py_ssize_t size = PyUnicode_GET_LENGTH(unicode);
        4960                 :            :
        4961                 :            :     _PyBytesWriter writer;
        4962                 :            :     char *end;
        4963                 :            :
        4964   [ -  +  +  + ]:         33 :     switch (kind) {
        4965                 :          0 :     default:
        4966                 :          0 :         Py_UNREACHABLE();
        4967                 :         12 :     case PyUnicode_1BYTE_KIND:
        4968                 :            :         /* the string cannot be ASCII, or PyUnicode_UTF8() would be set */
        4969                 :            :         assert(!PyUnicode_IS_ASCII(unicode));
        4970                 :         12 :         end = ucs1lib_utf8_encoder(&writer, unicode, data, size, error_handler, errors);
        4971                 :         12 :         break;
        4972                 :         19 :     case PyUnicode_2BYTE_KIND:
        4973                 :         19 :         end = ucs2lib_utf8_encoder(&writer, unicode, data, size, error_handler, errors);
        4974                 :         19 :         break;
        4975                 :          2 :     case PyUnicode_4BYTE_KIND:
        4976                 :          2 :         end = ucs4lib_utf8_encoder(&writer, unicode, data, size, error_handler, errors);
        4977                 :          2 :         break;
        4978                 :            :     }
        4979                 :            :
        4980         [ -  + ]:         33 :     if (end == NULL) {
        4981                 :          0 :         _PyBytesWriter_Dealloc(&writer);
        4982                 :          0 :         return NULL;
        4983                 :            :     }
        4984                 :         33 :     return _PyBytesWriter_Finish(&writer, end);
        4985                 :            : }
        4986                 :            :
        4987                 :            : static int
        4988                 :          0 : unicode_fill_utf8(PyObject *unicode)
        4989                 :            : {
        4990                 :            :     /* the string cannot be ASCII, or PyUnicode_UTF8() would be set */
        4991                 :            :     assert(!PyUnicode_IS_ASCII(unicode));
        4992                 :            :
        4993                 :          0 :     int kind = PyUnicode_KIND(unicode);
        4994                 :          0 :     const void *data = PyUnicode_DATA(unicode);
        4995                 :          0 :     Py_ssize_t size = PyUnicode_GET_LENGTH(unicode);
        4996                 :            :
        4997                 :            :     _PyBytesWriter writer;
        4998                 :            :     char *end;
        4999                 :            :
        5000   [ #  #  #  # ]:          0 :     switch (kind) {
        5001                 :          0 :     default:
        5002                 :          0 :         Py_UNREACHABLE();
        5003                 :          0 :     case PyUnicode_1BYTE_KIND:
        5004                 :          0 :         end = ucs1lib_utf8_encoder(&writer, unicode, data, size,
        5005                 :            :                                    _Py_ERROR_STRICT, NULL);
        5006                 :          0 :         break;
        5007                 :          0 :     case PyUnicode_2BYTE_KIND:
        5008                 :          0 :         end = ucs2lib_utf8_encoder(&writer, unicode, data, size,
        5009                 :            :                                    _Py_ERROR_STRICT, NULL);
        5010                 :          0 :         break;
        5011                 :          0 :     case PyUnicode_4BYTE_KIND:
        5012                 :          0 :         end = ucs4lib_utf8_encoder(&writer, unicode, data, size,
        5013                 :            :                                    _Py_ERROR_STRICT, NULL);
        5014                 :          0 :         break;
        5015                 :            :     }
        5016         [ #  # ]:          0 :     if (end == NULL) {
        5017                 :          0 :         _PyBytesWriter_Dealloc(&writer);
        5018                 :          0 :         return -1;
        5019                 :            :     }
        5020                 :            :
        5021         [ #  # ]:          0 :     const char *start = writer.use_small_buffer ? writer.small_buffer :
        5022                 :          0 :                     PyBytes_AS_STRING(writer.buffer);
        5023                 :          0 :     Py_ssize_t len = end - start;
        5024                 :            :
        5025                 :          0 :     char *cache = PyObject_Malloc(len + 1);
        5026         [ #  # ]:          0 :     if (cache == NULL) {
        5027                 :          0 :         _PyBytesWriter_Dealloc(&writer);
        5028                 :          0 :         PyErr_NoMemory();
        5029                 :          0 :         return -1;
        5030                 :            :     }
        5031                 :          0 :     _PyUnicode_UTF8(unicode) = cache;
        5032                 :          0 :     _PyUnicode_UTF8_LENGTH(unicode) = len;
        5033                 :          0 :     memcpy(cache, start, len);
        5034                 :          0 :     cache[len] = '\0';
        5035                 :          0 :     _PyBytesWriter_Dealloc(&writer);
        5036                 :          0 :     return 0;
        5037                 :            : }
        5038                 :            :
        5039                 :            : PyObject *
        5040                 :        459 : _PyUnicode_AsUTF8String(PyObject *unicode, const char *errors)
        5041                 :            : {
        5042                 :        459 :     return unicode_encode_utf8(unicode, _Py_ERROR_UNKNOWN, errors);
        5043                 :            : }
        5044                 :            :
        5045                 :            :
        5046                 :            : PyObject *
        5047                 :          1 : PyUnicode_AsUTF8String(PyObject *unicode)
        5048                 :            : {
        5049                 :          1 :     return _PyUnicode_AsUTF8String(unicode, NULL);
        5050                 :            : }
        5051                 :            :
        5052                 :            : /* --- UTF-32 Codec ------------------------------------------------------- */
        5053                 :            :
        5054                 :            : PyObject *
        5055                 :          0 : PyUnicode_DecodeUTF32(const char *s,
        5056                 :            :                       Py_ssize_t size,
        5057                 :            :                       const char *errors,
        5058                 :            :                       int *byteorder)
        5059                 :            : {
        5060                 :          0 :     return PyUnicode_DecodeUTF32Stateful(s, size, errors, byteorder, NULL);
        5061                 :            : }
        5062                 :            :
        5063                 :            : PyObject *
        5064                 :          0 : PyUnicode_DecodeUTF32Stateful(const char *s,
        5065                 :            :                               Py_ssize_t size,
        5066                 :            :                               const char *errors,
        5067                 :            :                               int *byteorder,
        5068                 :            :                               Py_ssize_t *consumed)
        5069                 :            : {
        5070                 :          0 :     const char *starts = s;
        5071                 :            :     Py_ssize_t startinpos;
        5072                 :            :     Py_ssize_t endinpos;
        5073                 :            :     _PyUnicodeWriter writer;
        5074                 :            :     const unsigned char *q, *e;
        5075                 :          0 :     int le, bo = 0;       /* assume native ordering by default */
        5076                 :            :     const char *encoding;
        5077                 :          0 :     const char *errmsg = "";
        5078                 :          0 :     PyObject *errorHandler = NULL;
        5079                 :          0 :     PyObject *exc = NULL;
        5080                 :            :
        5081                 :          0 :     q = (const unsigned char *)s;
        5082                 :          0 :     e = q + size;
        5083                 :            :
        5084         [ #  # ]:          0 :     if (byteorder)
        5085                 :          0 :         bo = *byteorder;
        5086                 :            :
        5087                 :            :     /* Check for BOM marks (U+FEFF) in the input and adjust current
        5088                 :            :        byte order setting accordingly. In native mode, the leading BOM
        5089                 :            :        mark is skipped, in all other modes, it is copied to the output
        5090                 :            :        stream as-is (giving a ZWNBSP character). */
        5091   [ #  #  #  # ]:          0 :     if (bo == 0 && size >= 4) {
        5092                 :          0 :         Py_UCS4 bom = ((unsigned int)q[3] << 24) | (q[2] << 16) | (q[1] << 8) | q[0];
        5093         [ #  # ]:          0 :         if (bom == 0x0000FEFF) {
        5094                 :          0 :             bo = -1;
        5095                 :          0 :             q += 4;
        5096                 :            :         }
        5097         [ #  # ]:          0 :         else if (bom == 0xFFFE0000) {
        5098                 :          0 :             bo = 1;
        5099                 :          0 :             q += 4;
        5100                 :            :         }
        5101         [ #  # ]:          0 :         if (byteorder)
        5102                 :          0 :             *byteorder = bo;
        5103                 :            :     }
        5104                 :            :
        5105         [ #  # ]:          0 :     if (q == e) {
        5106         [ #  # ]:          0 :         if (consumed)
        5107                 :          0 :             *consumed = size;
        5108                 :          0 :         _Py_RETURN_UNICODE_EMPTY();
        5109                 :            :     }
        5110                 :            :
        5111                 :            : #ifdef WORDS_BIGENDIAN
        5112                 :            :     le = bo < 0;
        5113                 :            : #else
        5114                 :          0 :     le = bo <= 0;
        5115                 :            : #endif
        5116         [ #  # ]:          0 :     encoding = le ? "utf-32-le" : "utf-32-be";
        5117                 :            :
        5118                 :          0 :     _PyUnicodeWriter_Init(&writer);
        5119                 :          0 :     writer.min_length = (e - q + 3) / 4;
        5120   [ #  #  #  #  :          0 :     if (_PyUnicodeWriter_Prepare(&writer, writer.min_length, 127) == -1)
                 #  #  #  # ]
        5121                 :          0 :         goto onError;
        5122                 :            :
        5123                 :          0 :     while (1) {
        5124                 :          0 :         Py_UCS4 ch = 0;
        5125                 :          0 :         Py_UCS4 maxch = PyUnicode_MAX_CHAR_VALUE(writer.buffer);
        5126                 :            :
        5127         [ #  # ]:          0 :         if (e - q >= 4) {
        5128                 :          0 :             int kind = writer.kind;
        5129                 :          0 :             void *data = writer.data;
        5130                 :          0 :             const unsigned char *last = e - 4;
        5131                 :          0 :             Py_ssize_t pos = writer.pos;
        5132         [ #  # ]:          0 :             if (le) {
        5133                 :            :                 do {
        5134                 :          0 :                     ch = ((unsigned int)q[3] << 24) | (q[2] << 16) | (q[1] << 8) | q[0];
        5135         [ #  # ]:          0 :                     if (ch > maxch)
        5136                 :          0 :                         break;
        5137   [ #  #  #  # ]:          0 :                     if (kind != PyUnicode_1BYTE_KIND &&
        5138                 :          0 :                         Py_UNICODE_IS_SURROGATE(ch))
        5139                 :          0 :                         break;
        5140                 :          0 :                     PyUnicode_WRITE(kind, data, pos++, ch);
        5141                 :          0 :                     q += 4;
        5142         [ #  # ]:          0 :                 } while (q <= last);
        5143                 :            :             }
        5144                 :            :             else {
        5145                 :            :                 do {
        5146                 :          0 :                     ch = ((unsigned int)q[0] << 24) | (q[1] << 16) | (q[2] << 8) | q[3];
        5147         [ #  # ]:          0 :                     if (ch > maxch)
        5148                 :          0 :                         break;
        5149   [ #  #  #  # ]:          0 :                     if (kind != PyUnicode_1BYTE_KIND &&
        5150                 :          0 :                         Py_UNICODE_IS_SURROGATE(ch))
        5151                 :          0 :                         break;
        5152                 :          0 :                     PyUnicode_WRITE(kind, data, pos++, ch);
        5153                 :          0 :                     q += 4;
        5154         [ #  # ]:          0 :                 } while (q <= last);
        5155                 :            :             }
        5156                 :          0 :             writer.pos = pos;
        5157                 :            :         }
        5158                 :            :
        5159         [ #  # ]:          0 :         if (Py_UNICODE_IS_SURROGATE(ch)) {
        5160                 :          0 :             errmsg = "code point in surrogate code point range(0xd800, 0xe000)";
        5161                 :          0 :             startinpos = ((const char *)q) - starts;
        5162                 :          0 :             endinpos = startinpos + 4;
        5163                 :            :         }
        5164         [ #  # ]:          0 :         else if (ch <= maxch) {
        5165   [ #  #  #  # ]:          0 :             if (q == e || consumed)
        5166                 :            :                 break;
        5167                 :            :             /* remaining bytes at the end? (size should be divisible by 4) */
        5168                 :          0 :             errmsg = "truncated data";
        5169                 :          0 :             startinpos = ((const char *)q) - starts;
        5170                 :          0 :             endinpos = ((const char *)e) - starts;
        5171                 :            :         }
        5172                 :            :         else {
        5173         [ #  # ]:          0 :             if (ch < 0x110000) {
        5174         [ #  # ]:          0 :                 if (_PyUnicodeWriter_WriteCharInline(&writer, ch) < 0)
        5175                 :          0 :                     goto onError;
        5176                 :          0 :                 q += 4;
        5177                 :          0 :                 continue;
        5178                 :            :             }
        5179                 :          0 :             errmsg = "code point not in range(0x110000)";
        5180                 :          0 :             startinpos = ((const char *)q) - starts;
        5181                 :          0 :             endinpos = startinpos + 4;
        5182                 :            :         }
        5183                 :            :
        5184                 :            :         /* The remaining input chars are ignored if the callback
        5185                 :            :            chooses to skip the input */
        5186         [ #  # ]:          0 :         if (unicode_decode_call_errorhandler_writer(
        5187                 :            :                 errors, &errorHandler,
        5188                 :            :                 encoding, errmsg,
        5189                 :            :                 &starts, (const char **)&e, &startinpos, &endinpos, &exc, (const char **)&q,
        5190                 :            :                 &writer))
        5191                 :          0 :             goto onError;
        5192                 :            :     }
        5193                 :            :
        5194         [ #  # ]:          0 :     if (consumed)
        5195                 :          0 :         *consumed = (const char *)q-starts;
        5196                 :            :
        5197                 :          0 :     Py_XDECREF(errorHandler);
        5198                 :          0 :     Py_XDECREF(exc);
        5199                 :          0 :     return _PyUnicodeWriter_Finish(&writer);
        5200                 :            :
        5201                 :          0 :   onError:
        5202                 :          0 :     _PyUnicodeWriter_Dealloc(&writer);
        5203                 :          0 :     Py_XDECREF(errorHandler);
        5204                 :          0 :     Py_XDECREF(exc);
        5205                 :          0 :     return NULL;
        5206                 :            : }
        5207                 :            :
        5208                 :            : PyObject *
        5209                 :          0 : _PyUnicode_EncodeUTF32(PyObject *str,
        5210                 :            :                        const char *errors,
        5211                 :            :                        int byteorder)
        5212                 :            : {
        5213                 :            :     int kind;
        5214                 :            :     const void *data;
        5215                 :            :     Py_ssize_t len;
        5216                 :            :     PyObject *v;
        5217                 :            :     uint32_t *out;
        5218                 :            : #if PY_LITTLE_ENDIAN
        5219                 :          0 :     int native_ordering = byteorder <= 0;
        5220                 :            : #else
        5221                 :            :     int native_ordering = byteorder >= 0;
        5222                 :            : #endif
        5223                 :            :     const char *encoding;
        5224                 :            :     Py_ssize_t nsize, pos;
        5225                 :          0 :     PyObject *errorHandler = NULL;
        5226                 :          0 :     PyObject *exc = NULL;
        5227                 :          0 :     PyObject *rep = NULL;
        5228                 :            :
        5229         [ #  # ]:          0 :     if (!PyUnicode_Check(str)) {
        5230                 :          0 :         PyErr_BadArgument();
        5231                 :          0 :         return NULL;
        5232                 :            :     }
        5233                 :          0 :     kind = PyUnicode_KIND(str);
        5234                 :          0 :     data = PyUnicode_DATA(str);
        5235                 :          0 :     len = PyUnicode_GET_LENGTH(str);
        5236                 :            :
        5237   [ #  #  #  # ]:          0 :     if (len > PY_SSIZE_T_MAX / 4 - (byteorder == 0))
        5238                 :          0 :         return PyErr_NoMemory();
        5239                 :          0 :     nsize = len + (byteorder == 0);
        5240                 :          0 :     v = PyBytes_FromStringAndSize(NULL, nsize * 4);
        5241         [ #  # ]:          0 :     if (v == NULL)
        5242                 :          0 :         return NULL;
        5243                 :            :
        5244                 :            :     /* output buffer is 4-bytes aligned */
        5245                 :            :     assert(_Py_IS_ALIGNED(PyBytes_AS_STRING(v), 4));
        5246                 :          0 :     out = (uint32_t *)PyBytes_AS_STRING(v);
        5247         [ #  # ]:          0 :     if (byteorder == 0)
        5248                 :          0 :         *out++ = 0xFEFF;
        5249         [ #  # ]:          0 :     if (len == 0)
        5250                 :          0 :         goto done;
        5251                 :            :
        5252         [ #  # ]:          0 :     if (byteorder == -1)
        5253                 :          0 :         encoding = "utf-32-le";
        5254         [ #  # ]:          0 :     else if (byteorder == 1)
        5255                 :          0 :         encoding = "utf-32-be";
        5256                 :            :     else
        5257                 :          0 :         encoding = "utf-32";
        5258                 :            :
        5259         [ #  # ]:          0 :     if (kind == PyUnicode_1BYTE_KIND) {
        5260                 :          0 :         ucs1lib_utf32_encode((const Py_UCS1 *)data, len, &out, native_ordering);
        5261                 :          0 :         goto done;
        5262                 :            :     }
        5263                 :            :
        5264                 :          0 :     pos = 0;
        5265         [ #  # ]:          0 :     while (pos < len) {
        5266                 :            :         Py_ssize_t newpos, repsize, moreunits;
        5267                 :            :
        5268         [ #  # ]:          0 :         if (kind == PyUnicode_2BYTE_KIND) {
        5269                 :          0 :             pos += ucs2lib_utf32_encode((const Py_UCS2 *)data + pos, len - pos,
        5270                 :            :                                         &out, native_ordering);
        5271                 :            :         }
        5272                 :            :         else {
        5273                 :            :             assert(kind == PyUnicode_4BYTE_KIND);
        5274                 :          0 :             pos += ucs4lib_utf32_encode((const Py_UCS4 *)data + pos, len - pos,
        5275                 :            :                                         &out, native_ordering);
        5276                 :            :         }
        5277         [ #  # ]:          0 :         if (pos == len)
        5278                 :          0 :             break;
        5279                 :            :
        5280                 :          0 :         rep = unicode_encode_call_errorhandler(
        5281                 :            :                 errors, &errorHandler,
        5282                 :            :                 encoding, "surrogates not allowed",
        5283                 :            :                 str, &exc, pos, pos + 1, &newpos);
        5284         [ #  # ]:          0 :         if (!rep)
        5285                 :          0 :             goto error;
        5286                 :            :
        5287         [ #  # ]:          0 :         if (PyBytes_Check(rep)) {
        5288                 :          0 :             repsize = PyBytes_GET_SIZE(rep);
        5289         [ #  # ]:          0 :             if (repsize & 3) {
        5290                 :          0 :                 raise_encode_exception(&exc, encoding,
        5291                 :            :                                        str, pos, pos + 1,
        5292                 :            :                                        "surrogates not allowed");
        5293                 :          0 :                 goto error;
        5294                 :            :             }
        5295                 :          0 :             moreunits = repsize / 4;
        5296                 :            :         }
        5297                 :            :         else {
        5298                 :            :             assert(PyUnicode_Check(rep));
        5299                 :          0 :             moreunits = repsize = PyUnicode_GET_LENGTH(rep);
        5300         [ #  # ]:          0 :             if (!PyUnicode_IS_ASCII(rep)) {
        5301                 :          0 :                 raise_encode_exception(&exc, encoding,
        5302                 :            :                                        str, pos, pos + 1,
        5303                 :            :                                        "surrogates not allowed");
        5304                 :          0 :                 goto error;
        5305                 :            :             }
        5306                 :            :         }
        5307                 :          0 :         moreunits += pos - newpos;
        5308                 :          0 :         pos = newpos;
        5309                 :            :
        5310                 :            :         /* four bytes are reserved for each surrogate */
        5311         [ #  # ]:          0 :         if (moreunits > 0) {
        5312                 :          0 :             Py_ssize_t outpos = out - (uint32_t*) PyBytes_AS_STRING(v);
        5313         [ #  # ]:          0 :             if (moreunits >= (PY_SSIZE_T_MAX - PyBytes_GET_SIZE(v)) / 4) {
        5314                 :            :                 /* integer overflow */
        5315                 :          0 :                 PyErr_NoMemory();
        5316                 :          0 :                 goto error;
        5317                 :            :             }
        5318         [ #  # ]:          0 :             if (_PyBytes_Resize(&v, PyBytes_GET_SIZE(v) + 4 * moreunits) < 0)
        5319                 :          0 :                 goto error;
        5320                 :          0 :             out = (uint32_t*) PyBytes_AS_STRING(v) + outpos;
        5321                 :            :         }
        5322                 :            :
        5323         [ #  # ]:          0 :         if (PyBytes_Check(rep)) {
        5324                 :          0 :             memcpy(out, PyBytes_AS_STRING(rep), repsize);
        5325                 :          0 :             out += repsize / 4;
        5326                 :            :         } else /* rep is unicode */ {
        5327                 :            :             assert(PyUnicode_KIND(rep) == PyUnicode_1BYTE_KIND);
        5328                 :          0 :             ucs1lib_utf32_encode(PyUnicode_1BYTE_DATA(rep), repsize,
        5329                 :            :                                  &out, native_ordering);
        5330                 :            :         }
        5331                 :            :
        5332         [ #  # ]:          0 :         Py_CLEAR(rep);
        5333                 :            :     }
        5334                 :            :
        5335                 :            :     /* Cut back to size actually needed. This is necessary for, for example,
        5336                 :            :        encoding of a string containing isolated surrogates and the 'ignore'
        5337                 :            :        handler is used. */
        5338                 :          0 :     nsize = (unsigned char*) out - (unsigned char*) PyBytes_AS_STRING(v);
        5339         [ #  # ]:          0 :     if (nsize != PyBytes_GET_SIZE(v))
        5340                 :          0 :       _PyBytes_Resize(&v, nsize);
        5341                 :          0 :     Py_XDECREF(errorHandler);
        5342                 :          0 :     Py_XDECREF(exc);
        5343                 :          0 :   done:
        5344                 :          0 :     return v;
        5345                 :          0 :   error:
        5346                 :          0 :     Py_XDECREF(rep);
        5347                 :          0 :     Py_XDECREF(errorHandler);
        5348                 :          0 :     Py_XDECREF(exc);
        5349                 :          0 :     Py_XDECREF(v);
        5350                 :          0 :     return NULL;
        5351                 :            : }
        5352                 :            :
        5353                 :            : PyObject *
        5354                 :          0 : PyUnicode_AsUTF32String(PyObject *unicode)
        5355                 :            : {
        5356                 :          0 :     return _PyUnicode_EncodeUTF32(unicode, NULL, 0);
        5357                 :            : }
        5358                 :            :
        5359                 :            : /* --- UTF-16 Codec ------------------------------------------------------- */
        5360                 :            :
        5361                 :            : PyObject *
        5362                 :          0 : PyUnicode_DecodeUTF16(const char *s,
        5363                 :            :                       Py_ssize_t size,
        5364                 :            :                       const char *errors,
        5365                 :            :                       int *byteorder)
        5366                 :            : {
        5367                 :          0 :     return PyUnicode_DecodeUTF16Stateful(s, size, errors, byteorder, NULL);
        5368                 :            : }
        5369                 :            :
        5370                 :            : PyObject *
        5371                 :          0 : PyUnicode_DecodeUTF16Stateful(const char *s,
        5372                 :            :                               Py_ssize_t size,
        5373                 :            :                               const char *errors,
        5374                 :            :                               int *byteorder,
        5375                 :            :                               Py_ssize_t *consumed)
        5376                 :            : {
        5377                 :          0 :     const char *starts = s;
        5378                 :            :     Py_ssize_t startinpos;
        5379                 :            :     Py_ssize_t endinpos;
        5380                 :            :     _PyUnicodeWriter writer;
        5381                 :            :     const unsigned char *q, *e;
        5382                 :          0 :     int bo = 0;       /* assume native ordering by default */
        5383                 :            :     int native_ordering;
        5384                 :          0 :     const char *errmsg = "";
        5385                 :          0 :     PyObject *errorHandler = NULL;
        5386                 :          0 :     PyObject *exc = NULL;
        5387                 :            :     const char *encoding;
        5388                 :            :
        5389                 :          0 :     q = (const unsigned char *)s;
        5390                 :          0 :     e = q + size;
        5391                 :            :
        5392         [ #  # ]:          0 :     if (byteorder)
        5393                 :          0 :         bo = *byteorder;
        5394                 :            :
        5395                 :            :     /* Check for BOM marks (U+FEFF) in the input and adjust current
        5396                 :            :        byte order setting accordingly. In native mode, the leading BOM
        5397                 :            :        mark is skipped, in all other modes, it is copied to the output
        5398                 :            :        stream as-is (giving a ZWNBSP character). */
        5399   [ #  #  #  # ]:          0 :     if (bo == 0 && size >= 2) {
        5400                 :          0 :         const Py_UCS4 bom = (q[1] << 8) | q[0];
        5401         [ #  # ]:          0 :         if (bom == 0xFEFF) {
        5402                 :          0 :             q += 2;
        5403                 :          0 :             bo = -1;
        5404                 :            :         }
        5405         [ #  # ]:          0 :         else if (bom == 0xFFFE) {
        5406                 :          0 :             q += 2;
        5407                 :          0 :             bo = 1;
        5408                 :            :         }
        5409         [ #  # ]:          0 :         if (byteorder)
        5410                 :          0 :             *byteorder = bo;
        5411                 :            :     }
        5412                 :            :
        5413         [ #  # ]:          0 :     if (q == e) {
        5414         [ #  # ]:          0 :         if (consumed)
        5415                 :          0 :             *consumed = size;
        5416                 :          0 :         _Py_RETURN_UNICODE_EMPTY();
        5417                 :            :     }
        5418                 :            :
        5419                 :            : #if PY_LITTLE_ENDIAN
        5420                 :          0 :     native_ordering = bo <= 0;
        5421         [ #  # ]:          0 :     encoding = bo <= 0 ? "utf-16-le" : "utf-16-be";
        5422                 :            : #else
        5423                 :            :     native_ordering = bo >= 0;
        5424                 :            :     encoding = bo >= 0 ? "utf-16-be" : "utf-16-le";
        5425                 :            : #endif
        5426                 :            :
        5427                 :            :     /* Note: size will always be longer than the resulting Unicode
        5428                 :            :        character count normally.  Error handler will take care of
        5429                 :            :        resizing when needed. */
        5430                 :          0 :     _PyUnicodeWriter_Init(&writer);
        5431                 :          0 :     writer.min_length = (e - q + 1) / 2;
        5432   [ #  #  #  #  :          0 :     if (_PyUnicodeWriter_Prepare(&writer, writer.min_length, 127) == -1)
                 #  #  #  # ]
        5433                 :          0 :         goto onError;
        5434                 :            :
        5435                 :          0 :     while (1) {
        5436                 :          0 :         Py_UCS4 ch = 0;
        5437         [ #  # ]:          0 :         if (e - q >= 2) {
        5438                 :          0 :             int kind = writer.kind;
        5439         [ #  # ]:          0 :             if (kind == PyUnicode_1BYTE_KIND) {
        5440         [ #  # ]:          0 :                 if (PyUnicode_IS_ASCII(writer.buffer))
        5441                 :          0 :                     ch = asciilib_utf16_decode(&q, e,
        5442                 :          0 :                             (Py_UCS1*)writer.data, &writer.pos,
        5443                 :            :                             native_ordering);
        5444                 :            :                 else
        5445                 :          0 :                     ch = ucs1lib_utf16_decode(&q, e,
        5446                 :          0 :                             (Py_UCS1*)writer.data, &writer.pos,
        5447                 :            :                             native_ordering);
        5448         [ #  # ]:          0 :             } else if (kind == PyUnicode_2BYTE_KIND) {
        5449                 :          0 :                 ch = ucs2lib_utf16_decode(&q, e,
        5450                 :          0 :                         (Py_UCS2*)writer.data, &writer.pos,
        5451                 :            :                         native_ordering);
        5452                 :            :             } else {
        5453                 :            :                 assert(kind == PyUnicode_4BYTE_KIND);
        5454                 :          0 :                 ch = ucs4lib_utf16_decode(&q, e,
        5455                 :          0 :                         (Py_UCS4*)writer.data, &writer.pos,
        5456                 :            :                         native_ordering);
        5457                 :            :             }
        5458                 :            :         }
        5459                 :            :
        5460   [ #  #  #  #  :          0 :         switch (ch)
                          # ]
        5461                 :            :         {
        5462                 :          0 :         case 0:
        5463                 :            :             /* remaining byte at the end? (size should be even) */
        5464   [ #  #  #  # ]:          0 :             if (q == e || consumed)
        5465                 :          0 :                 goto End;
        5466                 :          0 :             errmsg = "truncated data";
        5467                 :          0 :             startinpos = ((const char *)q) - starts;
        5468                 :          0 :             endinpos = ((const char *)e) - starts;
        5469                 :          0 :             break;
        5470                 :            :             /* The remaining input chars are ignored if the callback
        5471                 :            :                chooses to skip the input */
        5472                 :          0 :         case 1:
        5473                 :          0 :             q -= 2;
        5474         [ #  # ]:          0 :             if (consumed)
        5475                 :          0 :                 goto End;
        5476                 :          0 :             errmsg = "unexpected end of data";
        5477                 :          0 :             startinpos = ((const char *)q) - starts;
        5478                 :          0 :             endinpos = ((const char *)e) - starts;
        5479                 :          0 :             break;
        5480                 :          0 :         case 2:
        5481                 :          0 :             errmsg = "illegal encoding";
        5482                 :          0 :             startinpos = ((const char *)q) - 2 - starts;
        5483                 :          0 :             endinpos = startinpos + 2;
        5484                 :          0 :             break;
        5485                 :          0 :         case 3:
        5486                 :          0 :             errmsg = "illegal UTF-16 surrogate";
        5487                 :          0 :             startinpos = ((const char *)q) - 4 - starts;
        5488                 :          0 :             endinpos = startinpos + 2;
        5489                 :          0 :             break;
        5490                 :          0 :         default:
        5491         [ #  # ]:          0 :             if (_PyUnicodeWriter_WriteCharInline(&writer, ch) < 0)
        5492                 :          0 :                 goto onError;
        5493                 :          0 :             continue;
        5494                 :            :         }
        5495                 :            :
        5496         [ #  # ]:          0 :         if (unicode_decode_call_errorhandler_writer(
        5497                 :            :                 errors,
        5498                 :            :                 &errorHandler,
        5499                 :            :                 encoding, errmsg,
        5500                 :            :                 &starts,
        5501                 :            :                 (const char **)&e,
        5502                 :            :                 &startinpos,
        5503                 :            :                 &endinpos,
        5504                 :            :                 &exc,
        5505                 :            :                 (const char **)&q,
        5506                 :            :                 &writer))
        5507                 :          0 :             goto onError;
        5508                 :            :     }
        5509                 :            :
        5510                 :          0 : End:
        5511         [ #  # ]:          0 :     if (consumed)
        5512                 :          0 :         *consumed = (const char *)q-starts;
        5513                 :            :
        5514                 :          0 :     Py_XDECREF(errorHandler);
        5515                 :          0 :     Py_XDECREF(exc);
        5516                 :          0 :     return _PyUnicodeWriter_Finish(&writer);
        5517                 :            :
        5518                 :          0 :   onError:
        5519                 :          0 :     _PyUnicodeWriter_Dealloc(&writer);
        5520                 :          0 :     Py_XDECREF(errorHandler);
        5521                 :          0 :     Py_XDECREF(exc);
        5522                 :          0 :     return NULL;
        5523                 :            : }
        5524                 :            :
        5525                 :            : PyObject *
        5526                 :          0 : _PyUnicode_EncodeUTF16(PyObject *str,
        5527                 :            :                        const char *errors,
        5528                 :            :                        int byteorder)
        5529                 :            : {
        5530                 :            :     int kind;
        5531                 :            :     const void *data;
        5532                 :            :     Py_ssize_t len;
        5533                 :            :     PyObject *v;
        5534                 :            :     unsigned short *out;
        5535                 :            :     Py_ssize_t pairs;
        5536                 :            : #if PY_BIG_ENDIAN
        5537                 :            :     int native_ordering = byteorder >= 0;
        5538                 :            : #else
        5539                 :          0 :     int native_ordering = byteorder <= 0;
        5540                 :            : #endif
        5541                 :            :     const char *encoding;
        5542                 :            :     Py_ssize_t nsize, pos;
        5543                 :          0 :     PyObject *errorHandler = NULL;
        5544                 :          0 :     PyObject *exc = NULL;
        5545                 :          0 :     PyObject *rep = NULL;
        5546                 :            :
        5547         [ #  # ]:          0 :     if (!PyUnicode_Check(str)) {
        5548                 :          0 :         PyErr_BadArgument();
        5549                 :          0 :         return NULL;
        5550                 :            :     }
        5551                 :          0 :     kind = PyUnicode_KIND(str);
        5552                 :          0 :     data = PyUnicode_DATA(str);
        5553                 :          0 :     len = PyUnicode_GET_LENGTH(str);
        5554                 :            :
        5555                 :          0 :     pairs = 0;
        5556         [ #  # ]:          0 :     if (kind == PyUnicode_4BYTE_KIND) {
        5557                 :          0 :         const Py_UCS4 *in = (const Py_UCS4 *)data;
        5558                 :          0 :         const Py_UCS4 *end = in + len;
        5559         [ #  # ]:          0 :         while (in < end) {
        5560         [ #  # ]:          0 :             if (*in++ >= 0x10000) {
        5561                 :          0 :                 pairs++;
        5562                 :            :             }
        5563                 :            :         }
        5564                 :            :     }
        5565         [ #  # ]:          0 :     if (len > PY_SSIZE_T_MAX / 2 - pairs - (byteorder == 0)) {
        5566                 :          0 :         return PyErr_NoMemory();
        5567                 :            :     }
        5568                 :          0 :     nsize = len + pairs + (byteorder == 0);
        5569                 :          0 :     v = PyBytes_FromStringAndSize(NULL, nsize * 2);
        5570         [ #  # ]:          0 :     if (v == NULL) {
        5571                 :          0 :         return NULL;
        5572                 :            :     }
        5573                 :            :
        5574                 :            :     /* output buffer is 2-bytes aligned */
        5575                 :            :     assert(_Py_IS_ALIGNED(PyBytes_AS_STRING(v), 2));
        5576                 :          0 :     out = (unsigned short *)PyBytes_AS_STRING(v);
        5577         [ #  # ]:          0 :     if (byteorder == 0) {
        5578                 :          0 :         *out++ = 0xFEFF;
        5579                 :            :     }
        5580         [ #  # ]:          0 :     if (len == 0) {
        5581                 :          0 :         goto done;
        5582                 :            :     }
        5583                 :            :
        5584         [ #  # ]:          0 :     if (kind == PyUnicode_1BYTE_KIND) {
        5585                 :          0 :         ucs1lib_utf16_encode((const Py_UCS1 *)data, len, &out, native_ordering);
        5586                 :          0 :         goto done;
        5587                 :            :     }
        5588                 :            :
        5589         [ #  # ]:          0 :     if (byteorder < 0) {
        5590                 :          0 :         encoding = "utf-16-le";
        5591                 :            :     }
        5592         [ #  # ]:          0 :     else if (byteorder > 0) {
        5593                 :          0 :         encoding = "utf-16-be";
        5594                 :            :     }
        5595                 :            :     else {
        5596                 :          0 :         encoding = "utf-16";
        5597                 :            :     }
        5598                 :            :
        5599                 :          0 :     pos = 0;
        5600         [ #  # ]:          0 :     while (pos < len) {
        5601                 :            :         Py_ssize_t newpos, repsize, moreunits;
        5602                 :            :
        5603         [ #  # ]:          0 :         if (kind == PyUnicode_2BYTE_KIND) {
        5604                 :          0 :             pos += ucs2lib_utf16_encode((const Py_UCS2 *)data + pos, len - pos,
        5605                 :            :                                         &out, native_ordering);
        5606                 :            :         }
        5607                 :            :         else {
        5608                 :            :             assert(kind == PyUnicode_4BYTE_KIND);
        5609                 :          0 :             pos += ucs4lib_utf16_encode((const Py_UCS4 *)data + pos, len - pos,
        5610                 :            :                                         &out, native_ordering);
        5611                 :            :         }
        5612         [ #  # ]:          0 :         if (pos == len)
        5613                 :          0 :             break;
        5614                 :            :
        5615                 :          0 :         rep = unicode_encode_call_errorhandler(
        5616                 :            :                 errors, &errorHandler,
        5617                 :            :                 encoding, "surrogates not allowed",
        5618                 :            :                 str, &exc, pos, pos + 1, &newpos);
        5619         [ #  # ]:          0 :         if (!rep)
        5620                 :          0 :             goto error;
        5621                 :            :
        5622         [ #  # ]:          0 :         if (PyBytes_Check(rep)) {
        5623                 :          0 :             repsize = PyBytes_GET_SIZE(rep);
        5624         [ #  # ]:          0 :             if (repsize & 1) {
        5625                 :          0 :                 raise_encode_exception(&exc, encoding,
        5626                 :            :                                        str, pos, pos + 1,
        5627                 :            :                                        "surrogates not allowed");
        5628                 :          0 :                 goto error;
        5629                 :            :             }
        5630                 :          0 :             moreunits = repsize / 2;
        5631                 :            :         }
        5632                 :            :         else {
        5633                 :            :             assert(PyUnicode_Check(rep));
        5634                 :          0 :             moreunits = repsize = PyUnicode_GET_LENGTH(rep);
        5635         [ #  # ]:          0 :             if (!PyUnicode_IS_ASCII(rep)) {
        5636                 :          0 :                 raise_encode_exception(&exc, encoding,
        5637                 :            :                                        str, pos, pos + 1,
        5638                 :            :                                        "surrogates not allowed");
        5639                 :          0 :                 goto error;
        5640                 :            :             }
        5641                 :            :         }
        5642                 :          0 :         moreunits += pos - newpos;
        5643                 :          0 :         pos = newpos;
        5644                 :            :
        5645                 :            :         /* two bytes are reserved for each surrogate */
        5646         [ #  # ]:          0 :         if (moreunits > 0) {
        5647                 :          0 :             Py_ssize_t outpos = out - (unsigned short*) PyBytes_AS_STRING(v);
        5648         [ #  # ]:          0 :             if (moreunits >= (PY_SSIZE_T_MAX - PyBytes_GET_SIZE(v)) / 2) {
        5649                 :            :                 /* integer overflow */
        5650                 :          0 :                 PyErr_NoMemory();
        5651                 :          0 :                 goto error;
        5652                 :            :             }
        5653         [ #  # ]:          0 :             if (_PyBytes_Resize(&v, PyBytes_GET_SIZE(v) + 2 * moreunits) < 0)
        5654                 :          0 :                 goto error;
        5655                 :          0 :             out = (unsigned short*) PyBytes_AS_STRING(v) + outpos;
        5656                 :            :         }
        5657                 :            :
        5658         [ #  # ]:          0 :         if (PyBytes_Check(rep)) {
        5659                 :          0 :             memcpy(out, PyBytes_AS_STRING(rep), repsize);
        5660                 :          0 :             out += repsize / 2;
        5661                 :            :         } else /* rep is unicode */ {
        5662                 :            :             assert(PyUnicode_KIND(rep) == PyUnicode_1BYTE_KIND);
        5663                 :          0 :             ucs1lib_utf16_encode(PyUnicode_1BYTE_DATA(rep), repsize,
        5664                 :            :                                  &out, native_ordering);
        5665                 :            :         }
        5666                 :            :
        5667         [ #  # ]:          0 :         Py_CLEAR(rep);
        5668                 :            :     }
        5669                 :            :
        5670                 :            :     /* Cut back to size actually needed. This is necessary for, for example,
        5671                 :            :     encoding of a string containing isolated surrogates and the 'ignore' handler
        5672                 :            :     is used. */
        5673                 :          0 :     nsize = (unsigned char*) out - (unsigned char*) PyBytes_AS_STRING(v);
        5674         [ #  # ]:          0 :     if (nsize != PyBytes_GET_SIZE(v))
        5675                 :          0 :       _PyBytes_Resize(&v, nsize);
        5676                 :          0 :     Py_XDECREF(errorHandler);
        5677                 :          0 :     Py_XDECREF(exc);
        5678                 :          0 :   done:
        5679                 :          0 :     return v;
        5680                 :          0 :   error:
        5681                 :          0 :     Py_XDECREF(rep);
        5682                 :          0 :     Py_XDECREF(errorHandler);
        5683                 :          0 :     Py_XDECREF(exc);
        5684                 :          0 :     Py_XDECREF(v);
        5685                 :          0 :     return NULL;
        5686                 :            : #undef STORECHAR
        5687                 :            : }
        5688                 :            :
        5689                 :            : PyObject *
        5690                 :          0 : PyUnicode_AsUTF16String(PyObject *unicode)
        5691                 :            : {
        5692                 :          0 :     return _PyUnicode_EncodeUTF16(unicode, NULL, 0);
        5693                 :            : }
        5694                 :            :
        5695                 :            : /* --- Unicode Escape Codec ----------------------------------------------- */
        5696                 :            :
        5697                 :            : PyObject *
        5698                 :       2190 : _PyUnicode_DecodeUnicodeEscapeInternal(const char *s,
        5699                 :            :                                Py_ssize_t size,
        5700                 :            :                                const char *errors,
        5701                 :            :                                Py_ssize_t *consumed,
        5702                 :            :                                const char **first_invalid_escape)
        5703                 :            : {
        5704                 :       2190 :     const char *starts = s;
        5705                 :            :     _PyUnicodeWriter writer;
        5706                 :            :     const char *end;
        5707                 :       2190 :     PyObject *errorHandler = NULL;
        5708                 :       2190 :     PyObject *exc = NULL;
        5709                 :            :     _PyUnicode_Name_CAPI *ucnhash_capi;
        5710                 :       2190 :     PyInterpreterState *interp = _PyInterpreterState_Get();
        5711                 :            :
        5712                 :            :     // so we can remember if we've seen an invalid escape char or not
        5713                 :       2190 :     *first_invalid_escape = NULL;
        5714                 :            :
        5715         [ -  + ]:       2190 :     if (size == 0) {
        5716         [ #  # ]:          0 :         if (consumed) {
        5717                 :          0 :             *consumed = 0;
        5718                 :            :         }
        5719                 :          0 :         _Py_RETURN_UNICODE_EMPTY();
        5720                 :            :     }
        5721                 :            :     /* Escaped strings will always be longer than the resulting
        5722                 :            :        Unicode string, so we start with size here and then reduce the
        5723                 :            :        length after conversion to the true value.
        5724                 :            :        (but if the error callback returns a long replacement string
        5725                 :            :        we'll have to allocate more space) */
        5726                 :       2190 :     _PyUnicodeWriter_Init(&writer);
        5727                 :       2190 :     writer.min_length = size;
        5728   [ -  +  -  -  :       2190 :     if (_PyUnicodeWriter_Prepare(&writer, size, 127) < 0) {
                 +  -  -  + ]
        5729                 :          0 :         goto onError;
        5730                 :            :     }
        5731                 :            :
        5732                 :       2190 :     end = s + size;
        5733         [ +  + ]:      48912 :     while (s < end) {
        5734                 :      46722 :         unsigned char c = (unsigned char) *s++;
        5735                 :            :         Py_UCS4 ch;
        5736                 :            :         int count;
        5737                 :            :         const char *message;
        5738                 :            :
        5739                 :            : #define WRITE_ASCII_CHAR(ch)                                                  \
        5740                 :            :             do {                                                              \
        5741                 :            :                 assert(ch <= 127);                                            \
        5742                 :            :                 assert(writer.pos < writer.size);                             \
        5743                 :            :                 PyUnicode_WRITE(writer.kind, writer.data, writer.pos++, ch);  \
        5744                 :            :             } while(0)
        5745                 :            :
        5746                 :            : #define WRITE_CHAR(ch)                                                        \
        5747                 :            :             do {                                                              \
        5748                 :            :                 if (ch <= writer.maxchar) {                                   \
        5749                 :            :                     assert(writer.pos < writer.size);                         \
        5750                 :            :                     PyUnicode_WRITE(writer.kind, writer.data, writer.pos++, ch); \
        5751                 :            :                 }                                                             \
        5752                 :            :                 else if (_PyUnicodeWriter_WriteCharInline(&writer, ch) < 0) { \
        5753                 :            :                     goto onError;                                             \
        5754                 :            :                 }                                                             \
        5755                 :            :             } while(0)
        5756                 :            :
        5757                 :            :         /* Non-escape characters are interpreted as Unicode ordinals */
        5758         [ +  + ]:      46722 :         if (c != '\\') {
        5759   [ +  -  -  - ]:      45756 :             WRITE_CHAR(c);
        5760                 :      46722 :             continue;
        5761                 :            :         }
        5762                 :            :
        5763                 :        966 :         Py_ssize_t startinpos = s - starts - 1;
        5764                 :            :         /* \ - Escapes */
        5765         [ -  + ]:        966 :         if (s >= end) {
        5766                 :          0 :             message = "\\ at end of string";
        5767                 :          0 :             goto incomplete;
        5768                 :            :         }
        5769                 :        966 :         c = (unsigned char) *s++;
        5770                 :            :
        5771                 :            :         assert(writer.pos < writer.size);
        5772   [ +  +  +  +  :        966 :         switch (c) {
              +  +  +  +  +
              +  +  +  +  +
                    +  -  - ]
        5773                 :            :
        5774                 :            :             /* \x escapes */
        5775                 :         14 :         case '\n': continue;
        5776                 :        177 :         case '\\': WRITE_ASCII_CHAR('\\'); continue;
        5777                 :         10 :         case '\'': WRITE_ASCII_CHAR('\''); continue;
        5778                 :         12 :         case '\"': WRITE_ASCII_CHAR('\"'); continue;
        5779                 :          2 :         case 'b': WRITE_ASCII_CHAR('\b'); continue;
        5780                 :            :         /* FF */
        5781                 :          6 :         case 'f': WRITE_ASCII_CHAR('\014'); continue;
        5782                 :         34 :         case 't': WRITE_ASCII_CHAR('\t'); continue;
        5783                 :        465 :         case 'n': WRITE_ASCII_CHAR('\n'); continue;
        5784                 :         24 :         case 'r': WRITE_ASCII_CHAR('\r'); continue;
        5785                 :            :         /* VT */
        5786                 :          3 :         case 'v': WRITE_ASCII_CHAR('\013'); continue;
        5787                 :            :         /* BEL, not classic C */
        5788                 :          1 :         case 'a': WRITE_ASCII_CHAR('\007'); continue;
        5789                 :            :
        5790                 :            :             /* \OOO (octal) escapes */
        5791                 :         17 :         case '0': case '1': case '2': case '3':
        5792                 :            :         case '4': case '5': case '6': case '7':
        5793                 :         17 :             ch = c - '0';
        5794   [ +  +  +  +  :         17 :             if (s < end && '0' <= *s && *s <= '7') {
                       +  + ]
        5795                 :          1 :                 ch = (ch<<3) + *s++ - '0';
        5796   [ +  -  +  -  :          1 :                 if (s < end && '0' <= *s && *s <= '7') {
                       +  - ]
        5797                 :          1 :                     ch = (ch<<3) + *s++ - '0';
        5798                 :            :                 }
        5799                 :            :             }
        5800         [ -  + ]:         17 :             if (ch > 0377) {
        5801         [ #  # ]:          0 :                 if (*first_invalid_escape == NULL) {
        5802                 :          0 :                     *first_invalid_escape = s-3; /* Back up 3 chars, since we've
        5803                 :            :                                                     already incremented s. */
        5804                 :            :                 }
        5805                 :            :             }
        5806   [ +  -  -  - ]:         17 :             WRITE_CHAR(ch);
        5807                 :         17 :             continue;
        5808                 :            :
        5809                 :            :             /* hex escapes */
        5810                 :            :             /* \xXX */
        5811                 :        103 :         case 'x':
        5812                 :        103 :             count = 2;
        5813                 :        103 :             message = "truncated \\xXX escape";
        5814                 :        103 :             goto hexescape;
        5815                 :            :
        5816                 :            :             /* \uXXXX */
        5817                 :         97 :         case 'u':
        5818                 :         97 :             count = 4;
        5819                 :         97 :             message = "truncated \\uXXXX escape";
        5820                 :         97 :             goto hexescape;
        5821                 :            :
        5822                 :            :             /* \UXXXXXXXX */
        5823                 :          1 :         case 'U':
        5824                 :          1 :             count = 8;
        5825                 :          1 :             message = "truncated \\UXXXXXXXX escape";
        5826                 :        201 :         hexescape:
        5827         [ +  + ]:        803 :             for (ch = 0; count; ++s, --count) {
        5828         [ -  + ]:        602 :                 if (s >= end) {
        5829                 :          0 :                     goto incomplete;
        5830                 :            :                 }
        5831                 :        602 :                 c = (unsigned char)*s;
        5832                 :        602 :                 ch <<= 4;
        5833   [ +  -  +  + ]:        602 :                 if (c >= '0' && c <= '9') {
        5834                 :        452 :                     ch += c - '0';
        5835                 :            :                 }
        5836   [ +  +  +  - ]:        150 :                 else if (c >= 'a' && c <= 'f') {
        5837                 :        131 :                     ch += c - ('a' - 10);
        5838                 :            :                 }
        5839   [ +  -  +  - ]:         19 :                 else if (c >= 'A' && c <= 'F') {
        5840                 :         19 :                     ch += c - ('A' - 10);
        5841                 :            :                 }
        5842                 :            :                 else {
        5843                 :          0 :                     goto error;
        5844                 :            :                 }
        5845                 :            :             }
        5846                 :            :
        5847                 :            :             /* when we get here, ch is a 32-bit unicode character */
        5848         [ -  + ]:        201 :             if (ch > MAX_UNICODE) {
        5849                 :          0 :                 message = "illegal Unicode character";
        5850                 :          0 :                 goto error;
        5851                 :            :             }
        5852                 :            :
        5853   [ +  +  -  + ]:        201 :             WRITE_CHAR(ch);
        5854                 :        201 :             continue;
        5855                 :            :
        5856                 :            :             /* \N{name} */
        5857                 :          0 :         case 'N':
        5858                 :          0 :             ucnhash_capi = interp->unicode.ucnhash_capi;
        5859         [ #  # ]:          0 :             if (ucnhash_capi == NULL) {
        5860                 :            :                 /* load the unicode data module */
        5861                 :          0 :                 ucnhash_capi = (_PyUnicode_Name_CAPI *)PyCapsule_Import(
        5862                 :            :                                                 PyUnicodeData_CAPSULE_NAME, 1);
        5863         [ #  # ]:          0 :                 if (ucnhash_capi == NULL) {
        5864                 :          0 :                     PyErr_SetString(
        5865                 :            :                         PyExc_UnicodeError,
        5866                 :            :                         "\\N escapes not supported (can't load unicodedata module)"
        5867                 :            :                         );
        5868                 :          0 :                     goto onError;
        5869                 :            :                 }
        5870                 :          0 :                 interp->unicode.ucnhash_capi = ucnhash_capi;
        5871                 :            :             }
        5872                 :            :
        5873                 :          0 :             message = "malformed \\N character escape";
        5874         [ #  # ]:          0 :             if (s >= end) {
        5875                 :          0 :                 goto incomplete;
        5876                 :            :             }
        5877         [ #  # ]:          0 :             if (*s == '{') {
        5878                 :          0 :                 const char *start = ++s;
        5879                 :            :                 size_t namelen;
        5880                 :            :                 /* look for the closing brace */
        5881   [ #  #  #  # ]:          0 :                 while (s < end && *s != '}')
        5882                 :          0 :                     s++;
        5883         [ #  # ]:          0 :                 if (s >= end) {
        5884                 :          0 :                     goto incomplete;
        5885                 :            :                 }
        5886                 :          0 :                 namelen = s - start;
        5887         [ #  # ]:          0 :                 if (namelen) {
        5888                 :            :                     /* found a name.  look it up in the unicode database */
        5889                 :          0 :                     s++;
        5890                 :          0 :                     ch = 0xffffffff; /* in case 'getcode' messes up */
        5891   [ #  #  #  # ]:          0 :                     if (namelen <= INT_MAX &&
        5892                 :          0 :                         ucnhash_capi->getcode(start, (int)namelen,
        5893                 :            :                                               &ch, 0)) {
        5894                 :            :                         assert(ch <= MAX_UNICODE);
        5895   [ #  #  #  # ]:          0 :                         WRITE_CHAR(ch);
        5896                 :          0 :                         continue;
        5897                 :            :                     }
        5898                 :          0 :                     message = "unknown Unicode character name";
        5899                 :            :                 }
        5900                 :            :             }
        5901                 :          0 :             goto error;
        5902                 :            :
        5903                 :          0 :         default:
        5904         [ #  # ]:          0 :             if (*first_invalid_escape == NULL) {
        5905                 :          0 :                 *first_invalid_escape = s-1; /* Back up one char, since we've
        5906                 :            :                                                 already incremented s. */
        5907                 :            :             }
        5908                 :          0 :             WRITE_ASCII_CHAR('\\');
        5909   [ #  #  #  # ]:          0 :             WRITE_CHAR(c);
        5910                 :          0 :             continue;
        5911                 :            :         }
        5912                 :            :
        5913                 :          0 :       incomplete:
        5914         [ #  # ]:          0 :         if (consumed) {
        5915                 :          0 :             *consumed = startinpos;
        5916                 :          0 :             break;
        5917                 :            :         }
        5918                 :          0 :       error:;
        5919                 :          0 :         Py_ssize_t endinpos = s-starts;
        5920                 :          0 :         writer.min_length = end - s + writer.pos;
        5921         [ #  # ]:          0 :         if (unicode_decode_call_errorhandler_writer(
        5922                 :            :                 errors, &errorHandler,
        5923                 :            :                 "unicodeescape", message,
        5924                 :            :                 &starts, &end, &startinpos, &endinpos, &exc, &s,
        5925                 :            :                 &writer)) {
        5926                 :          0 :             goto onError;
        5927                 :            :         }
        5928                 :            :         assert(end - s <= writer.size - writer.pos);
        5929                 :            :
        5930                 :            : #undef WRITE_ASCII_CHAR
        5931                 :            : #undef WRITE_CHAR
        5932                 :            :     }
        5933                 :            :
        5934                 :       2190 :     Py_XDECREF(errorHandler);
        5935                 :       2190 :     Py_XDECREF(exc);
        5936                 :       2190 :     return _PyUnicodeWriter_Finish(&writer);
        5937                 :            :
        5938                 :          0 :   onError:
        5939                 :          0 :     _PyUnicodeWriter_Dealloc(&writer);
        5940                 :          0 :     Py_XDECREF(errorHandler);
        5941                 :          0 :     Py_XDECREF(exc);
        5942                 :          0 :     return NULL;
        5943                 :            : }
        5944                 :            :
        5945                 :            : PyObject *
        5946                 :          0 : _PyUnicode_DecodeUnicodeEscapeStateful(const char *s,
        5947                 :            :                               Py_ssize_t size,
        5948                 :            :                               const char *errors,
        5949                 :            :                               Py_ssize_t *consumed)
        5950                 :            : {
        5951                 :            :     const char *first_invalid_escape;
        5952                 :          0 :     PyObject *result = _PyUnicode_DecodeUnicodeEscapeInternal(s, size, errors,
        5953                 :            :                                                       consumed,
        5954                 :            :                                                       &first_invalid_escape);
        5955         [ #  # ]:          0 :     if (result == NULL)
        5956                 :          0 :         return NULL;
        5957         [ #  # ]:          0 :     if (first_invalid_escape != NULL) {
        5958                 :          0 :         unsigned char c = *first_invalid_escape;
        5959   [ #  #  #  # ]:          0 :         if ('4' <= c && c <= '7') {
        5960         [ #  # ]:          0 :             if (PyErr_WarnFormat(PyExc_DeprecationWarning, 1,
        5961                 :            :                                  "invalid octal escape sequence '\\%.3s'",
        5962                 :            :                                  first_invalid_escape) < 0)
        5963                 :            :             {
        5964                 :          0 :                 Py_DECREF(result);
        5965                 :          0 :                 return NULL;
        5966                 :            :             }
        5967                 :            :         }
        5968                 :            :         else {
        5969         [ #  # ]:          0 :             if (PyErr_WarnFormat(PyExc_DeprecationWarning, 1,
        5970                 :            :                                  "invalid escape sequence '\\%c'",
        5971                 :            :                                  c) < 0)
        5972                 :            :             {
        5973                 :          0 :                 Py_DECREF(result);
        5974                 :          0 :                 return NULL;
        5975                 :            :             }
        5976                 :            :         }
        5977                 :            :     }
        5978                 :          0 :     return result;
        5979                 :            : }
        5980                 :            :
        5981                 :            : PyObject *
        5982                 :          0 : PyUnicode_DecodeUnicodeEscape(const char *s,
        5983                 :            :                               Py_ssize_t size,
        5984                 :            :                               const char *errors)
        5985                 :            : {
        5986                 :          0 :     return _PyUnicode_DecodeUnicodeEscapeStateful(s, size, errors, NULL);
        5987                 :            : }
        5988                 :            :
        5989                 :            : /* Return a Unicode-Escape string version of the Unicode object. */
        5990                 :            :
        5991                 :            : PyObject *
        5992                 :          0 : PyUnicode_AsUnicodeEscapeString(PyObject *unicode)
        5993                 :            : {
        5994                 :            :     Py_ssize_t i, len;
        5995                 :            :     PyObject *repr;
        5996                 :            :     char *p;
        5997                 :            :     int kind;
        5998                 :            :     const void *data;
        5999                 :            :     Py_ssize_t expandsize;
        6000                 :            :
        6001                 :            :     /* Initial allocation is based on the longest-possible character
        6002                 :            :        escape.
        6003                 :            :
        6004                 :            :        For UCS1 strings it's '\xxx', 4 bytes per source character.
        6005                 :            :        For UCS2 strings it's '\uxxxx', 6 bytes per source character.
        6006                 :            :        For UCS4 strings it's '\U00xxxxxx', 10 bytes per source character.
        6007                 :            :     */
        6008                 :            :
        6009         [ #  # ]:          0 :     if (!PyUnicode_Check(unicode)) {
        6010                 :          0 :         PyErr_BadArgument();
        6011                 :          0 :         return NULL;
        6012                 :            :     }
        6013                 :            :
        6014                 :          0 :     len = PyUnicode_GET_LENGTH(unicode);
        6015         [ #  # ]:          0 :     if (len == 0) {
        6016                 :          0 :         return PyBytes_FromStringAndSize(NULL, 0);
        6017                 :            :     }
        6018                 :            :
        6019                 :          0 :     kind = PyUnicode_KIND(unicode);
        6020                 :          0 :     data = PyUnicode_DATA(unicode);
        6021                 :            :     /* 4 byte characters can take up 10 bytes, 2 byte characters can take up 6
        6022                 :            :        bytes, and 1 byte characters 4. */
        6023                 :          0 :     expandsize = kind * 2 + 2;
        6024         [ #  # ]:          0 :     if (len > PY_SSIZE_T_MAX / expandsize) {
        6025                 :          0 :         return PyErr_NoMemory();
        6026                 :            :     }
        6027                 :          0 :     repr = PyBytes_FromStringAndSize(NULL, expandsize * len);
        6028         [ #  # ]:          0 :     if (repr == NULL) {
        6029                 :          0 :         return NULL;
        6030                 :            :     }
        6031                 :            :
        6032                 :          0 :     p = PyBytes_AS_STRING(repr);
        6033         [ #  # ]:          0 :     for (i = 0; i < len; i++) {
        6034                 :          0 :         Py_UCS4 ch = PyUnicode_READ(kind, data, i);
        6035                 :            :
        6036                 :            :         /* U+0000-U+00ff range */
        6037         [ #  # ]:          0 :         if (ch < 0x100) {
        6038   [ #  #  #  # ]:          0 :             if (ch >= ' ' && ch < 127) {
        6039         [ #  # ]:          0 :                 if (ch != '\\') {
        6040                 :            :                     /* Copy printable US ASCII as-is */
        6041                 :          0 :                     *p++ = (char) ch;
        6042                 :            :                 }
        6043                 :            :                 /* Escape backslashes */
        6044                 :            :                 else {
        6045                 :          0 :                     *p++ = '\\';
        6046                 :          0 :                     *p++ = '\\';
        6047                 :            :                 }
        6048                 :            :             }
        6049                 :            :
        6050                 :            :             /* Map special whitespace to '\t', \n', '\r' */
        6051         [ #  # ]:          0 :             else if (ch == '\t') {
        6052                 :          0 :                 *p++ = '\\';
        6053                 :          0 :                 *p++ = 't';
        6054                 :            :             }
        6055         [ #  # ]:          0 :             else if (ch == '\n') {
        6056                 :          0 :                 *p++ = '\\';
        6057                 :          0 :                 *p++ = 'n';
        6058                 :            :             }
        6059         [ #  # ]:          0 :             else if (ch == '\r') {
        6060                 :          0 :                 *p++ = '\\';
        6061                 :          0 :                 *p++ = 'r';
        6062                 :            :             }
        6063                 :            :
        6064                 :            :             /* Map non-printable US ASCII and 8-bit characters to '\xHH' */
        6065                 :            :             else {
        6066                 :          0 :                 *p++ = '\\';
        6067                 :          0 :                 *p++ = 'x';
        6068                 :          0 :                 *p++ = Py_hexdigits[(ch >> 4) & 0x000F];
        6069                 :          0 :                 *p++ = Py_hexdigits[ch & 0x000F];
        6070                 :            :             }
        6071                 :            :         }
        6072                 :            :         /* U+0100-U+ffff range: Map 16-bit characters to '\uHHHH' */
        6073         [ #  # ]:          0 :         else if (ch < 0x10000) {
        6074                 :          0 :             *p++ = '\\';
        6075                 :          0 :             *p++ = 'u';
        6076                 :          0 :             *p++ = Py_hexdigits[(ch >> 12) & 0x000F];
        6077                 :          0 :             *p++ = Py_hexdigits[(ch >> 8) & 0x000F];
        6078                 :          0 :             *p++ = Py_hexdigits[(ch >> 4) & 0x000F];
        6079                 :          0 :             *p++ = Py_hexdigits[ch & 0x000F];
        6080                 :            :         }
        6081                 :            :         /* U+010000-U+10ffff range: Map 21-bit characters to '\U00HHHHHH' */
        6082                 :            :         else {
        6083                 :            :
        6084                 :            :             /* Make sure that the first two digits are zero */
        6085                 :            :             assert(ch <= MAX_UNICODE && MAX_UNICODE <= 0x10ffff);
        6086                 :          0 :             *p++ = '\\';
        6087                 :          0 :             *p++ = 'U';
        6088                 :          0 :             *p++ = '0';
        6089                 :          0 :             *p++ = '0';
        6090                 :          0 :             *p++ = Py_hexdigits[(ch >> 20) & 0x0000000F];
        6091                 :          0 :             *p++ = Py_hexdigits[(ch >> 16) & 0x0000000F];
        6092                 :          0 :             *p++ = Py_hexdigits[(ch >> 12) & 0x0000000F];
        6093                 :          0 :             *p++ = Py_hexdigits[(ch >> 8) & 0x0000000F];
        6094                 :          0 :             *p++ = Py_hexdigits[(ch >> 4) & 0x0000000F];
        6095                 :          0 :             *p++ = Py_hexdigits[ch & 0x0000000F];
        6096                 :            :         }
        6097                 :            :     }
        6098                 :            :
        6099                 :            :     assert(p - PyBytes_AS_STRING(repr) > 0);
        6100         [ #  # ]:          0 :     if (_PyBytes_Resize(&repr, p - PyBytes_AS_STRING(repr)) < 0) {
        6101                 :          0 :         return NULL;
        6102                 :            :     }
        6103                 :          0 :     return repr;
        6104                 :            : }
        6105                 :            :
        6106                 :            : /* --- Raw Unicode Escape Codec ------------------------------------------- */
        6107                 :            :
        6108                 :            : PyObject *
        6109                 :          0 : _PyUnicode_DecodeRawUnicodeEscapeStateful(const char *s,
        6110                 :            :                                           Py_ssize_t size,
        6111                 :            :                                           const char *errors,
        6112                 :            :                                           Py_ssize_t *consumed)
        6113                 :            : {
        6114                 :          0 :     const char *starts = s;
        6115                 :            :     _PyUnicodeWriter writer;
        6116                 :            :     const char *end;
        6117                 :          0 :     PyObject *errorHandler = NULL;
        6118                 :          0 :     PyObject *exc = NULL;
        6119                 :            :
        6120         [ #  # ]:          0 :     if (size == 0) {
        6121         [ #  # ]:          0 :         if (consumed) {
        6122                 :          0 :             *consumed = 0;
        6123                 :            :         }
        6124                 :          0 :         _Py_RETURN_UNICODE_EMPTY();
        6125                 :            :     }
        6126                 :            :
        6127                 :            :     /* Escaped strings will always be longer than the resulting
        6128                 :            :        Unicode string, so we start with size here and then reduce the
        6129                 :            :        length after conversion to the true value. (But decoding error
        6130                 :            :        handler might have to resize the string) */
        6131                 :          0 :     _PyUnicodeWriter_Init(&writer);
        6132                 :          0 :     writer.min_length = size;
        6133   [ #  #  #  #  :          0 :     if (_PyUnicodeWriter_Prepare(&writer, size, 127) < 0) {
                 #  #  #  # ]
        6134                 :          0 :         goto onError;
        6135                 :            :     }
        6136                 :            :
        6137                 :          0 :     end = s + size;
        6138         [ #  # ]:          0 :     while (s < end) {
        6139                 :          0 :         unsigned char c = (unsigned char) *s++;
        6140                 :            :         Py_UCS4 ch;
        6141                 :            :         int count;
        6142                 :            :         const char *message;
        6143                 :            :
        6144                 :            : #define WRITE_CHAR(ch)                                                        \
        6145                 :            :             do {                                                              \
        6146                 :            :                 if (ch <= writer.maxchar) {                                   \
        6147                 :            :                     assert(writer.pos < writer.size);                         \
        6148                 :            :                     PyUnicode_WRITE(writer.kind, writer.data, writer.pos++, ch); \
        6149                 :            :                 }                                                             \
        6150                 :            :                 else if (_PyUnicodeWriter_WriteCharInline(&writer, ch) < 0) { \
        6151                 :            :                     goto onError;                                             \
        6152                 :            :                 }                                                             \
        6153                 :            :             } while(0)
        6154                 :            :
        6155                 :            :         /* Non-escape characters are interpreted as Unicode ordinals */
        6156   [ #  #  #  #  :          0 :         if (c != '\\' || (s >= end && !consumed)) {
                       #  # ]
        6157   [ #  #  #  # ]:          0 :             WRITE_CHAR(c);
        6158                 :          0 :             continue;
        6159                 :            :         }
        6160                 :            :
        6161                 :          0 :         Py_ssize_t startinpos = s - starts - 1;
        6162                 :            :         /* \ - Escapes */
        6163         [ #  # ]:          0 :         if (s >= end) {
        6164                 :            :             assert(consumed);
        6165                 :            :             // Set message to silent compiler warning.
        6166                 :            :             // Actually it is never used.
        6167                 :          0 :             message = "\\ at end of string";
        6168                 :          0 :             goto incomplete;
        6169                 :            :         }
        6170                 :            :
        6171                 :          0 :         c = (unsigned char) *s++;
        6172         [ #  # ]:          0 :         if (c == 'u') {
        6173                 :          0 :             count = 4;
        6174                 :          0 :             message = "truncated \\uXXXX escape";
        6175                 :            :         }
        6176         [ #  # ]:          0 :         else if (c == 'U') {
        6177                 :          0 :             count = 8;
        6178                 :          0 :             message = "truncated \\UXXXXXXXX escape";
        6179                 :            :         }
        6180                 :            :         else {
        6181                 :            :             assert(writer.pos < writer.size);
        6182                 :          0 :             PyUnicode_WRITE(writer.kind, writer.data, writer.pos++, '\\');
        6183   [ #  #  #  # ]:          0 :             WRITE_CHAR(c);
        6184                 :          0 :             continue;
        6185                 :            :         }
        6186                 :            :
        6187                 :            :         /* \uHHHH with 4 hex digits, \U00HHHHHH with 8 */
        6188         [ #  # ]:          0 :         for (ch = 0; count; ++s, --count) {
        6189         [ #  # ]:          0 :             if (s >= end) {
        6190                 :          0 :                 goto incomplete;
        6191                 :            :             }
        6192                 :          0 :             c = (unsigned char)*s;
        6193                 :          0 :             ch <<= 4;
        6194   [ #  #  #  # ]:          0 :             if (c >= '0' && c <= '9') {
        6195                 :          0 :                 ch += c - '0';
        6196                 :            :             }
        6197   [ #  #  #  # ]:          0 :             else if (c >= 'a' && c <= 'f') {
        6198                 :          0 :                 ch += c - ('a' - 10);
        6199                 :            :             }
        6200   [ #  #  #  # ]:          0 :             else if (c >= 'A' && c <= 'F') {
        6201                 :          0 :                 ch += c - ('A' - 10);
        6202                 :            :             }
        6203                 :            :             else {
        6204                 :          0 :                 goto error;
        6205                 :            :             }
        6206                 :            :         }
        6207         [ #  # ]:          0 :         if (ch > MAX_UNICODE) {
        6208                 :          0 :             message = "\\Uxxxxxxxx out of range";
        6209                 :          0 :             goto error;
        6210                 :            :         }
        6211   [ #  #  #  # ]:          0 :         WRITE_CHAR(ch);
        6212                 :          0 :         continue;
        6213                 :            :
        6214                 :          0 :       incomplete:
        6215         [ #  # ]:          0 :         if (consumed) {
        6216                 :          0 :             *consumed = startinpos;
        6217                 :          0 :             break;
        6218                 :            :         }
        6219                 :          0 :       error:;
        6220                 :          0 :         Py_ssize_t endinpos = s-starts;
        6221                 :          0 :         writer.min_length = end - s + writer.pos;
        6222         [ #  # ]:          0 :         if (unicode_decode_call_errorhandler_writer(
        6223                 :            :                 errors, &errorHandler,
        6224                 :            :                 "rawunicodeescape", message,
        6225                 :            :                 &starts, &end, &startinpos, &endinpos, &exc, &s,
        6226                 :            :                 &writer)) {
        6227                 :          0 :             goto onError;
        6228                 :            :         }
        6229                 :            :         assert(end - s <= writer.size - writer.pos);
        6230                 :            :
        6231                 :            : #undef WRITE_CHAR
        6232                 :            :     }
        6233                 :          0 :     Py_XDECREF(errorHandler);
        6234                 :          0 :     Py_XDECREF(exc);
        6235                 :          0 :     return _PyUnicodeWriter_Finish(&writer);
        6236                 :            :
        6237                 :          0 :   onError:
        6238                 :          0 :     _PyUnicodeWriter_Dealloc(&writer);
        6239                 :          0 :     Py_XDECREF(errorHandler);
        6240                 :          0 :     Py_XDECREF(exc);
        6241                 :          0 :     return NULL;
        6242                 :            : }
        6243                 :            :
        6244                 :            : PyObject *
        6245                 :          0 : PyUnicode_DecodeRawUnicodeEscape(const char *s,
        6246                 :            :                                  Py_ssize_t size,
        6247                 :            :                                  const char *errors)
        6248                 :            : {
        6249                 :          0 :     return _PyUnicode_DecodeRawUnicodeEscapeStateful(s, size, errors, NULL);
        6250                 :            : }
        6251                 :            :
        6252                 :            :
        6253                 :            : PyObject *
        6254                 :          0 : PyUnicode_AsRawUnicodeEscapeString(PyObject *unicode)
        6255                 :            : {
        6256                 :            :     PyObject *repr;
        6257                 :            :     char *p;
        6258                 :            :     Py_ssize_t expandsize, pos;
        6259                 :            :     int kind;
        6260                 :            :     const void *data;
        6261                 :            :     Py_ssize_t len;
        6262                 :            :
        6263         [ #  # ]:          0 :     if (!PyUnicode_Check(unicode)) {
        6264                 :          0 :         PyErr_BadArgument();
        6265                 :          0 :         return NULL;
        6266                 :            :     }
        6267                 :          0 :     kind = PyUnicode_KIND(unicode);
        6268                 :          0 :     data = PyUnicode_DATA(unicode);
        6269                 :          0 :     len = PyUnicode_GET_LENGTH(unicode);
        6270         [ #  # ]:          0 :     if (kind == PyUnicode_1BYTE_KIND) {
        6271                 :          0 :         return PyBytes_FromStringAndSize(data, len);
        6272                 :            :     }
        6273                 :            :
        6274                 :            :     /* 4 byte characters can take up 10 bytes, 2 byte characters can take up 6
        6275                 :            :        bytes, and 1 byte characters 4. */
        6276                 :          0 :     expandsize = kind * 2 + 2;
        6277                 :            :
        6278         [ #  # ]:          0 :     if (len > PY_SSIZE_T_MAX / expandsize) {
        6279                 :          0 :         return PyErr_NoMemory();
        6280                 :            :     }
        6281                 :          0 :     repr = PyBytes_FromStringAndSize(NULL, expandsize * len);
        6282         [ #  # ]:          0 :     if (repr == NULL) {
        6283                 :          0 :         return NULL;
        6284                 :            :     }
        6285         [ #  # ]:          0 :     if (len == 0) {
        6286                 :          0 :         return repr;
        6287                 :            :     }
        6288                 :            :
        6289                 :          0 :     p = PyBytes_AS_STRING(repr);
        6290         [ #  # ]:          0 :     for (pos = 0; pos < len; pos++) {
        6291                 :          0 :         Py_UCS4 ch = PyUnicode_READ(kind, data, pos);
        6292                 :            :
        6293                 :            :         /* U+0000-U+00ff range: Copy 8-bit characters as-is */
        6294         [ #  # ]:          0 :         if (ch < 0x100) {
        6295                 :          0 :             *p++ = (char) ch;
        6296                 :            :         }
        6297                 :            :         /* U+0100-U+ffff range: Map 16-bit characters to '\uHHHH' */
        6298         [ #  # ]:          0 :         else if (ch < 0x10000) {
        6299                 :          0 :             *p++ = '\\';
        6300                 :          0 :             *p++ = 'u';
        6301                 :          0 :             *p++ = Py_hexdigits[(ch >> 12) & 0xf];
        6302                 :          0 :             *p++ = Py_hexdigits[(ch >> 8) & 0xf];
        6303                 :          0 :             *p++ = Py_hexdigits[(ch >> 4) & 0xf];
        6304                 :          0 :             *p++ = Py_hexdigits[ch & 15];
        6305                 :            :         }
        6306                 :            :         /* U+010000-U+10ffff range: Map 32-bit characters to '\U00HHHHHH' */
        6307                 :            :         else {
        6308                 :            :             assert(ch <= MAX_UNICODE && MAX_UNICODE <= 0x10ffff);
        6309                 :          0 :             *p++ = '\\';
        6310                 :          0 :             *p++ = 'U';
        6311                 :          0 :             *p++ = '0';
        6312                 :          0 :             *p++ = '0';
        6313                 :          0 :             *p++ = Py_hexdigits[(ch >> 20) & 0xf];
        6314                 :          0 :             *p++ = Py_hexdigits[(ch >> 16) & 0xf];
        6315                 :          0 :             *p++ = Py_hexdigits[(ch >> 12) & 0xf];
        6316                 :          0 :             *p++ = Py_hexdigits[(ch >> 8) & 0xf];
        6317                 :          0 :             *p++ = Py_hexdigits[(ch >> 4) & 0xf];
        6318                 :          0 :             *p++ = Py_hexdigits[ch & 15];
        6319                 :            :         }
        6320                 :            :     }
        6321                 :            :
        6322                 :            :     assert(p > PyBytes_AS_STRING(repr));
        6323         [ #  # ]:          0 :     if (_PyBytes_Resize(&repr, p - PyBytes_AS_STRING(repr)) < 0) {
        6324                 :          0 :         return NULL;
        6325                 :            :     }
        6326                 :          0 :     return repr;
        6327                 :            : }
        6328                 :            :
        6329                 :            : /* --- Latin-1 Codec ------------------------------------------------------ */
        6330                 :            :
        6331                 :            : PyObject *
        6332                 :          5 : PyUnicode_DecodeLatin1(const char *s,
        6333                 :            :                        Py_ssize_t size,
        6334                 :            :                        const char *errors)
        6335                 :            : {
        6336                 :            :     /* Latin-1 is equivalent to the first 256 ordinals in Unicode. */
        6337                 :          5 :     return _PyUnicode_FromUCS1((const unsigned char*)s, size);
        6338                 :            : }
        6339                 :            :
        6340                 :            : /* create or adjust a UnicodeEncodeError */
        6341                 :            : static void
        6342                 :          0 : make_encode_exception(PyObject **exceptionObject,
        6343                 :            :                       const char *encoding,
        6344                 :            :                       PyObject *unicode,
        6345                 :            :                       Py_ssize_t startpos, Py_ssize_t endpos,
        6346                 :            :                       const char *reason)
        6347                 :            : {
        6348         [ #  # ]:          0 :     if (*exceptionObject == NULL) {
        6349                 :          0 :         *exceptionObject = PyObject_CallFunction(
        6350                 :            :             PyExc_UnicodeEncodeError, "sOnns",
        6351                 :            :             encoding, unicode, startpos, endpos, reason);
        6352                 :            :     }
        6353                 :            :     else {
        6354         [ #  # ]:          0 :         if (PyUnicodeEncodeError_SetStart(*exceptionObject, startpos))
        6355                 :          0 :             goto onError;
        6356         [ #  # ]:          0 :         if (PyUnicodeEncodeError_SetEnd(*exceptionObject, endpos))
        6357                 :          0 :             goto onError;
        6358         [ #  # ]:          0 :         if (PyUnicodeEncodeError_SetReason(*exceptionObject, reason))
        6359                 :          0 :             goto onError;
        6360                 :          0 :         return;
        6361                 :          0 :       onError:
        6362         [ #  # ]:          0 :         Py_CLEAR(*exceptionObject);
        6363                 :            :     }
        6364                 :            : }
        6365                 :            :
        6366                 :            : /* raises a UnicodeEncodeError */
        6367                 :            : static void
        6368                 :          0 : raise_encode_exception(PyObject **exceptionObject,
        6369                 :            :                        const char *encoding,
        6370                 :            :                        PyObject *unicode,
        6371                 :            :                        Py_ssize_t startpos, Py_ssize_t endpos,
        6372                 :            :                        const char *reason)
        6373                 :            : {
        6374                 :          0 :     make_encode_exception(exceptionObject,
        6375                 :            :                           encoding, unicode, startpos, endpos, reason);
        6376         [ #  # ]:          0 :     if (*exceptionObject != NULL)
        6377                 :          0 :         PyCodec_StrictErrors(*exceptionObject);
        6378                 :          0 : }
        6379                 :            :
        6380                 :            : /* error handling callback helper:
        6381                 :            :    build arguments, call the callback and check the arguments,
        6382                 :            :    put the result into newpos and return the replacement string, which
        6383                 :            :    has to be freed by the caller */
        6384                 :            : static PyObject *
        6385                 :          0 : unicode_encode_call_errorhandler(const char *errors,
        6386                 :            :                                  PyObject **errorHandler,
        6387                 :            :                                  const char *encoding, const char *reason,
        6388                 :            :                                  PyObject *unicode, PyObject **exceptionObject,
        6389                 :            :                                  Py_ssize_t startpos, Py_ssize_t endpos,
        6390                 :            :                                  Py_ssize_t *newpos)
        6391                 :            : {
        6392                 :            :     static const char *argparse = "On;encoding error handler must return (str/bytes, int) tuple";
        6393                 :            :     Py_ssize_t len;
        6394                 :            :     PyObject *restuple;
        6395                 :            :     PyObject *resunicode;
        6396                 :            :
        6397         [ #  # ]:          0 :     if (*errorHandler == NULL) {
        6398                 :          0 :         *errorHandler = PyCodec_LookupError(errors);
        6399         [ #  # ]:          0 :         if (*errorHandler == NULL)
        6400                 :          0 :             return NULL;
        6401                 :            :     }
        6402                 :            :
        6403                 :          0 :     len = PyUnicode_GET_LENGTH(unicode);
        6404                 :            :
        6405                 :          0 :     make_encode_exception(exceptionObject,
        6406                 :            :                           encoding, unicode, startpos, endpos, reason);
        6407         [ #  # ]:          0 :     if (*exceptionObject == NULL)
        6408                 :          0 :         return NULL;
        6409                 :            :
        6410                 :          0 :     restuple = PyObject_CallOneArg(*errorHandler, *exceptionObject);
        6411         [ #  # ]:          0 :     if (restuple == NULL)
        6412                 :          0 :         return NULL;
        6413         [ #  # ]:          0 :     if (!PyTuple_Check(restuple)) {
        6414                 :          0 :         PyErr_SetString(PyExc_TypeError, &argparse[3]);
        6415                 :          0 :         Py_DECREF(restuple);
        6416                 :          0 :         return NULL;
        6417                 :            :     }
        6418         [ #  # ]:          0 :     if (!PyArg_ParseTuple(restuple, argparse,
        6419                 :            :                           &resunicode, newpos)) {
        6420                 :          0 :         Py_DECREF(restuple);
        6421                 :          0 :         return NULL;
        6422                 :            :     }
        6423   [ #  #  #  # ]:          0 :     if (!PyUnicode_Check(resunicode) && !PyBytes_Check(resunicode)) {
        6424                 :          0 :         PyErr_SetString(PyExc_TypeError, &argparse[3]);
        6425                 :          0 :         Py_DECREF(restuple);
        6426                 :          0 :         return NULL;
        6427                 :            :     }
        6428         [ #  # ]:          0 :     if (*newpos<0)
        6429                 :          0 :         *newpos = len + *newpos;
        6430   [ #  #  #  # ]:          0 :     if (*newpos<0 || *newpos>len) {
        6431                 :          0 :         PyErr_Format(PyExc_IndexError, "position %zd from error handler out of bounds", *newpos);
        6432                 :          0 :         Py_DECREF(restuple);
        6433                 :          0 :         return NULL;
        6434                 :            :     }
        6435                 :          0 :     Py_INCREF(resunicode);
        6436                 :          0 :     Py_DECREF(restuple);
        6437                 :          0 :     return resunicode;
        6438                 :            : }
        6439                 :            :
        6440                 :            : static PyObject *
        6441                 :          0 : unicode_encode_ucs1(PyObject *unicode,
        6442                 :            :                     const char *errors,
        6443                 :            :                     const Py_UCS4 limit)
        6444                 :            : {
        6445                 :            :     /* input state */
        6446                 :          0 :     Py_ssize_t pos=0, size;
        6447                 :            :     int kind;
        6448                 :            :     const void *data;
        6449                 :            :     /* pointer into the output */
        6450                 :            :     char *str;
        6451         [ #  # ]:          0 :     const char *encoding = (limit == 256) ? "latin-1" : "ascii";
        6452         [ #  # ]:          0 :     const char *reason = (limit == 256) ? "ordinal not in range(256)" : "ordinal not in range(128)";
        6453                 :          0 :     PyObject *error_handler_obj = NULL;
        6454                 :          0 :     PyObject *exc = NULL;
        6455                 :          0 :     _Py_error_handler error_handler = _Py_ERROR_UNKNOWN;
        6456                 :          0 :     PyObject *rep = NULL;
        6457                 :            :     /* output object */
        6458                 :            :     _PyBytesWriter writer;
        6459                 :            :
        6460                 :          0 :     size = PyUnicode_GET_LENGTH(unicode);
        6461                 :          0 :     kind = PyUnicode_KIND(unicode);
        6462                 :          0 :     data = PyUnicode_DATA(unicode);
        6463                 :            :     /* allocate enough for a simple encoding without
        6464                 :            :        replacements, if we need more, we'll resize */
        6465         [ #  # ]:          0 :     if (size == 0)
        6466                 :          0 :         return PyBytes_FromStringAndSize(NULL, 0);
        6467                 :            :
        6468                 :          0 :     _PyBytesWriter_Init(&writer);
        6469                 :          0 :     str = _PyBytesWriter_Alloc(&writer, size);
        6470         [ #  # ]:          0 :     if (str == NULL)
        6471                 :          0 :         return NULL;
        6472                 :            :
        6473         [ #  # ]:          0 :     while (pos < size) {
        6474                 :          0 :         Py_UCS4 ch = PyUnicode_READ(kind, data, pos);
        6475                 :            :
        6476                 :            :         /* can we encode this? */
        6477         [ #  # ]:          0 :         if (ch < limit) {
        6478                 :            :             /* no overflow check, because we know that the space is enough */
        6479                 :          0 :             *str++ = (char)ch;
        6480                 :          0 :             ++pos;
        6481                 :            :         }
        6482                 :            :         else {
        6483                 :            :             Py_ssize_t newpos, i;
        6484                 :            :             /* startpos for collecting unencodable chars */
        6485                 :          0 :             Py_ssize_t collstart = pos;
        6486                 :          0 :             Py_ssize_t collend = collstart + 1;
        6487                 :            :             /* find all unecodable characters */
        6488                 :            :
        6489   [ #  #  #  # ]:          0 :             while ((collend < size) && (PyUnicode_READ(kind, data, collend) >= limit))
        6490                 :          0 :                 ++collend;
        6491                 :            :
        6492                 :            :             /* Only overallocate the buffer if it's not the last write */
        6493                 :          0 :             writer.overallocate = (collend < size);
        6494                 :            :
        6495                 :            :             /* cache callback name lookup (if not done yet, i.e. it's the first error) */
        6496         [ #  # ]:          0 :             if (error_handler == _Py_ERROR_UNKNOWN)
        6497                 :          0 :                 error_handler = _Py_GetErrorHandler(errors);
        6498                 :            :
        6499   [ #  #  #  #  :          0 :             switch (error_handler) {
                    #  #  # ]
        6500                 :          0 :             case _Py_ERROR_STRICT:
        6501                 :          0 :                 raise_encode_exception(&exc, encoding, unicode, collstart, collend, reason);
        6502                 :          0 :                 goto onError;
        6503                 :            :
        6504                 :          0 :             case _Py_ERROR_REPLACE:
        6505                 :          0 :                 memset(str, '?', collend - collstart);
        6506                 :          0 :                 str += (collend - collstart);
        6507                 :            :                 /* fall through */
        6508                 :          0 :             case _Py_ERROR_IGNORE:
        6509                 :          0 :                 pos = collend;
        6510                 :          0 :                 break;
        6511                 :            :
        6512                 :          0 :             case _Py_ERROR_BACKSLASHREPLACE:
        6513                 :            :                 /* subtract preallocated bytes */
        6514                 :          0 :                 writer.min_size -= (collend - collstart);
        6515                 :          0 :                 str = backslashreplace(&writer, str,
        6516                 :            :                                        unicode, collstart, collend);
        6517         [ #  # ]:          0 :                 if (str == NULL)
        6518                 :          0 :                     goto onError;
        6519                 :          0 :                 pos = collend;
        6520                 :          0 :                 break;
        6521                 :            :
        6522                 :          0 :             case _Py_ERROR_XMLCHARREFREPLACE:
        6523                 :            :                 /* subtract preallocated bytes */
        6524                 :          0 :                 writer.min_size -= (collend - collstart);
        6525                 :          0 :                 str = xmlcharrefreplace(&writer, str,
        6526                 :            :                                         unicode, collstart, collend);
        6527         [ #  # ]:          0 :                 if (str == NULL)
        6528                 :          0 :                     goto onError;
        6529                 :          0 :                 pos = collend;
        6530                 :          0 :                 break;
        6531                 :            :
        6532                 :          0 :             case _Py_ERROR_SURROGATEESCAPE:
        6533         [ #  # ]:          0 :                 for (i = collstart; i < collend; ++i) {
        6534                 :          0 :                     ch = PyUnicode_READ(kind, data, i);
        6535   [ #  #  #  # ]:          0 :                     if (ch < 0xdc80 || 0xdcff < ch) {
        6536                 :            :                         /* Not a UTF-8b surrogate */
        6537                 :            :                         break;
        6538                 :            :                     }
        6539                 :          0 :                     *str++ = (char)(ch - 0xdc00);
        6540                 :          0 :                     ++pos;
        6541                 :            :                 }
        6542         [ #  # ]:          0 :                 if (i >= collend)
        6543                 :          0 :                     break;
        6544                 :          0 :                 collstart = pos;
        6545                 :            :                 assert(collstart != collend);
        6546                 :            :                 /* fall through */
        6547                 :            :
        6548                 :          0 :             default:
        6549                 :          0 :                 rep = unicode_encode_call_errorhandler(errors, &error_handler_obj,
        6550                 :            :                                                        encoding, reason, unicode, &exc,
        6551                 :            :                                                        collstart, collend, &newpos);
        6552         [ #  # ]:          0 :                 if (rep == NULL)
        6553                 :          0 :                     goto onError;
        6554                 :            :
        6555         [ #  # ]:          0 :                 if (newpos < collstart) {
        6556                 :          0 :                     writer.overallocate = 1;
        6557                 :          0 :                     str = _PyBytesWriter_Prepare(&writer, str,
        6558                 :            :                                                  collstart - newpos);
        6559         [ #  # ]:          0 :                     if (str == NULL)
        6560                 :          0 :                         goto onError;
        6561                 :            :                 }
        6562                 :            :                 else {
        6563                 :            :                     /* subtract preallocated bytes */
        6564                 :          0 :                     writer.min_size -= newpos - collstart;
        6565                 :            :                     /* Only overallocate the buffer if it's not the last write */
        6566                 :          0 :                     writer.overallocate = (newpos < size);
        6567                 :            :                 }
        6568                 :            :
        6569         [ #  # ]:          0 :                 if (PyBytes_Check(rep)) {
        6570                 :            :                     /* Directly copy bytes result to output. */
        6571                 :          0 :                     str = _PyBytesWriter_WriteBytes(&writer, str,
        6572                 :          0 :                                                     PyBytes_AS_STRING(rep),
        6573                 :            :                                                     PyBytes_GET_SIZE(rep));
        6574                 :            :                 }
        6575                 :            :                 else {
        6576                 :            :                     assert(PyUnicode_Check(rep));
        6577                 :            :
        6578   [ #  #  #  # ]:          0 :                     if (limit == 256 ?
        6579                 :          0 :                         PyUnicode_KIND(rep) != PyUnicode_1BYTE_KIND :
        6580                 :          0 :                         !PyUnicode_IS_ASCII(rep))
        6581                 :            :                     {
        6582                 :            :                         /* Not all characters are smaller than limit */
        6583                 :          0 :                         raise_encode_exception(&exc, encoding, unicode,
        6584                 :            :                                                collstart, collend, reason);
        6585                 :          0 :                         goto onError;
        6586                 :            :                     }
        6587                 :            :                     assert(PyUnicode_KIND(rep) == PyUnicode_1BYTE_KIND);
        6588                 :          0 :                     str = _PyBytesWriter_WriteBytes(&writer, str,
        6589                 :          0 :                                                     PyUnicode_DATA(rep),
        6590                 :            :                                                     PyUnicode_GET_LENGTH(rep));
        6591                 :            :                 }
        6592         [ #  # ]:          0 :                 if (str == NULL)
        6593                 :          0 :                     goto onError;
        6594                 :            :
        6595                 :          0 :                 pos = newpos;
        6596         [ #  # ]:          0 :                 Py_CLEAR(rep);
        6597                 :            :             }
        6598                 :            :
        6599                 :            :             /* If overallocation was disabled, ensure that it was the last
        6600                 :            :                write. Otherwise, we missed an optimization */
        6601                 :            :             assert(writer.overallocate || pos == size);
        6602                 :            :         }
        6603                 :            :     }
        6604                 :            :
        6605                 :          0 :     Py_XDECREF(error_handler_obj);
        6606                 :          0 :     Py_XDECREF(exc);
        6607                 :          0 :     return _PyBytesWriter_Finish(&writer, str);
        6608                 :            :
        6609                 :          0 :   onError:
        6610                 :          0 :     Py_XDECREF(rep);
        6611                 :          0 :     _PyBytesWriter_Dealloc(&writer);
        6612                 :          0 :     Py_XDECREF(error_handler_obj);
        6613                 :          0 :     Py_XDECREF(exc);
        6614                 :          0 :     return NULL;
        6615                 :            : }
        6616                 :            :
        6617                 :            : PyObject *
        6618                 :          0 : _PyUnicode_AsLatin1String(PyObject *unicode, const char *errors)
        6619                 :            : {
        6620         [ #  # ]:          0 :     if (!PyUnicode_Check(unicode)) {
        6621                 :          0 :         PyErr_BadArgument();
        6622                 :          0 :         return NULL;
        6623                 :            :     }
        6624                 :            :     /* Fast path: if it is a one-byte string, construct
        6625                 :            :        bytes object directly. */
        6626         [ #  # ]:          0 :     if (PyUnicode_KIND(unicode) == PyUnicode_1BYTE_KIND)
        6627                 :          0 :         return PyBytes_FromStringAndSize(PyUnicode_DATA(unicode),
        6628                 :            :                                          PyUnicode_GET_LENGTH(unicode));
        6629                 :            :     /* Non-Latin-1 characters present. Defer to above function to
        6630                 :            :        raise the exception. */
        6631                 :          0 :     return unicode_encode_ucs1(unicode, errors, 256);
        6632                 :            : }
        6633                 :            :
        6634                 :            : PyObject*
        6635                 :          0 : PyUnicode_AsLatin1String(PyObject *unicode)
        6636                 :            : {
        6637                 :          0 :     return _PyUnicode_AsLatin1String(unicode, NULL);
        6638                 :            : }
        6639                 :            :
        6640                 :            : /* --- 7-bit ASCII Codec -------------------------------------------------- */
        6641                 :            :
        6642                 :            : PyObject *
        6643                 :      10593 : PyUnicode_DecodeASCII(const char *s,
        6644                 :            :                       Py_ssize_t size,
        6645                 :            :                       const char *errors)
        6646                 :            : {
        6647                 :      10593 :     const char *starts = s;
        6648                 :      10593 :     const char *e = s + size;
        6649                 :      10593 :     PyObject *error_handler_obj = NULL;
        6650                 :      10593 :     PyObject *exc = NULL;
        6651                 :      10593 :     _Py_error_handler error_handler = _Py_ERROR_UNKNOWN;
        6652                 :            :
        6653         [ -  + ]:      10593 :     if (size == 0)
        6654                 :          0 :         _Py_RETURN_UNICODE_EMPTY();
        6655                 :            :
        6656                 :            :     /* ASCII is equivalent to the first 128 ordinals in Unicode. */
        6657   [ +  +  +  - ]:      10593 :     if (size == 1 && (unsigned char)s[0] < 128) {
        6658                 :        182 :         return get_latin1_char((unsigned char)s[0]);
        6659                 :            :     }
        6660                 :            :
        6661                 :            :     // Shortcut for simple case
        6662                 :      10411 :     PyObject *u = PyUnicode_New(size, 127);
        6663         [ -  + ]:      10411 :     if (u == NULL) {
        6664                 :          0 :         return NULL;
        6665                 :            :     }
        6666                 :      10411 :     Py_ssize_t outpos = ascii_decode(s, e, PyUnicode_1BYTE_DATA(u));
        6667         [ +  - ]:      10411 :     if (outpos == size) {
        6668                 :      10411 :         return u;
        6669                 :            :     }
        6670                 :            :
        6671                 :            :     _PyUnicodeWriter writer;
        6672                 :          0 :     _PyUnicodeWriter_InitWithBuffer(&writer, u);
        6673                 :          0 :     writer.pos = outpos;
        6674                 :            :
        6675                 :          0 :     s += outpos;
        6676                 :          0 :     int kind = writer.kind;
        6677                 :          0 :     void *data = writer.data;
        6678                 :            :     Py_ssize_t startinpos, endinpos;
        6679                 :            :
        6680         [ #  # ]:          0 :     while (s < e) {
        6681                 :          0 :         unsigned char c = (unsigned char)*s;
        6682         [ #  # ]:          0 :         if (c < 128) {
        6683                 :          0 :             PyUnicode_WRITE(kind, data, writer.pos, c);
        6684                 :          0 :             writer.pos++;
        6685                 :          0 :             ++s;
        6686                 :          0 :             continue;
        6687                 :            :         }
        6688                 :            :
        6689                 :            :         /* byte outsize range 0x00..0x7f: call the error handler */
        6690                 :            :
        6691         [ #  # ]:          0 :         if (error_handler == _Py_ERROR_UNKNOWN)
        6692                 :          0 :             error_handler = _Py_GetErrorHandler(errors);
        6693                 :            :
        6694      [ #  #  # ]:          0 :         switch (error_handler)
        6695                 :            :         {
        6696                 :          0 :         case _Py_ERROR_REPLACE:
        6697                 :            :         case _Py_ERROR_SURROGATEESCAPE:
        6698                 :            :             /* Fast-path: the error handler only writes one character,
        6699                 :            :                but we may switch to UCS2 at the first write */
        6700   [ #  #  #  # ]:          0 :             if (_PyUnicodeWriter_PrepareKind(&writer, PyUnicode_2BYTE_KIND) < 0)
        6701                 :          0 :                 goto onError;
        6702                 :          0 :             kind = writer.kind;
        6703                 :          0 :             data = writer.data;
        6704                 :            :
        6705         [ #  # ]:          0 :             if (error_handler == _Py_ERROR_REPLACE)
        6706                 :          0 :                 PyUnicode_WRITE(kind, data, writer.pos, 0xfffd);
        6707                 :            :             else
        6708                 :          0 :                 PyUnicode_WRITE(kind, data, writer.pos, c + 0xdc00);
        6709                 :          0 :             writer.pos++;
        6710                 :          0 :             ++s;
        6711                 :          0 :             break;
        6712                 :            :
        6713                 :          0 :         case _Py_ERROR_IGNORE:
        6714                 :          0 :             ++s;
        6715                 :          0 :             break;
        6716                 :            :
        6717                 :          0 :         default:
        6718                 :          0 :             startinpos = s-starts;
        6719                 :          0 :             endinpos = startinpos + 1;
        6720         [ #  # ]:          0 :             if (unicode_decode_call_errorhandler_writer(
        6721                 :            :                     errors, &error_handler_obj,
        6722                 :            :                     "ascii", "ordinal not in range(128)",
        6723                 :            :                     &starts, &e, &startinpos, &endinpos, &exc, &s,
        6724                 :            :                     &writer))
        6725                 :          0 :                 goto onError;
        6726                 :          0 :             kind = writer.kind;
        6727                 :          0 :             data = writer.data;
        6728                 :            :         }
        6729                 :            :     }
        6730                 :          0 :     Py_XDECREF(error_handler_obj);
        6731                 :          0 :     Py_XDECREF(exc);
        6732                 :          0 :     return _PyUnicodeWriter_Finish(&writer);
        6733                 :            :
        6734                 :          0 :   onError:
        6735                 :          0 :     _PyUnicodeWriter_Dealloc(&writer);
        6736                 :          0 :     Py_XDECREF(error_handler_obj);
        6737                 :          0 :     Py_XDECREF(exc);
        6738                 :          0 :     return NULL;
        6739                 :            : }
        6740                 :            :
        6741                 :            : PyObject *
        6742                 :       5049 : _PyUnicode_AsASCIIString(PyObject *unicode, const char *errors)
        6743                 :            : {
        6744         [ -  + ]:       5049 :     if (!PyUnicode_Check(unicode)) {
        6745                 :          0 :         PyErr_BadArgument();
        6746                 :          0 :         return NULL;
        6747                 :            :     }
        6748                 :            :     /* Fast path: if it is an ASCII-only string, construct bytes object
        6749                 :            :        directly. Else defer to above function to raise the exception. */
        6750         [ +  - ]:       5049 :     if (PyUnicode_IS_ASCII(unicode))
        6751                 :       5049 :         return PyBytes_FromStringAndSize(PyUnicode_DATA(unicode),
        6752                 :            :                                          PyUnicode_GET_LENGTH(unicode));
        6753                 :          0 :     return unicode_encode_ucs1(unicode, errors, 128);
        6754                 :            : }
        6755                 :            :
        6756                 :            : PyObject *
        6757                 :         18 : PyUnicode_AsASCIIString(PyObject *unicode)
        6758                 :            : {
        6759                 :         18 :     return _PyUnicode_AsASCIIString(unicode, NULL);
        6760                 :            : }
        6761                 :            :
        6762                 :            : #ifdef MS_WINDOWS
        6763                 :            :
        6764                 :            : /* --- MBCS codecs for Windows -------------------------------------------- */
        6765                 :            :
        6766                 :            : #if SIZEOF_INT < SIZEOF_SIZE_T
        6767                 :            : #define NEED_RETRY
        6768                 :            : #endif
        6769                 :            :
        6770                 :            : /* INT_MAX is the theoretical largest chunk (or INT_MAX / 2 when
        6771                 :            :    transcoding from UTF-16), but INT_MAX / 4 performs better in
        6772                 :            :    both cases also and avoids partial characters overrunning the
        6773                 :            :    length limit in MultiByteToWideChar on Windows */
        6774                 :            : #define DECODING_CHUNK_SIZE (INT_MAX/4)
        6775                 :            :
        6776                 :            : #ifndef WC_ERR_INVALID_CHARS
        6777                 :            : #  define WC_ERR_INVALID_CHARS 0x0080
        6778                 :            : #endif
        6779                 :            :
        6780                 :            : static const char*
        6781                 :            : code_page_name(UINT code_page, PyObject **obj)
        6782                 :            : {
        6783                 :            :     *obj = NULL;
        6784                 :            :     if (code_page == CP_ACP)
        6785                 :            :         return "mbcs";
        6786                 :            :     if (code_page == CP_UTF7)
        6787                 :            :         return "CP_UTF7";
        6788                 :            :     if (code_page == CP_UTF8)
        6789                 :            :         return "CP_UTF8";
        6790                 :            :
        6791                 :            :     *obj = PyBytes_FromFormat("cp%u", code_page);
        6792                 :            :     if (*obj == NULL)
        6793                 :            :         return NULL;
        6794                 :            :     return PyBytes_AS_STRING(*obj);
        6795                 :            : }
        6796                 :            :
        6797                 :            : static DWORD
        6798                 :            : decode_code_page_flags(UINT code_page)
        6799                 :            : {
        6800                 :            :     if (code_page == CP_UTF7) {
        6801                 :            :         /* The CP_UTF7 decoder only supports flags=0 */
        6802                 :            :         return 0;
        6803                 :            :     }
        6804                 :            :     else
        6805                 :            :         return MB_ERR_INVALID_CHARS;
        6806                 :            : }
        6807                 :            :
        6808                 :            : /*
        6809                 :            :  * Decode a byte string from a Windows code page into unicode object in strict
        6810                 :            :  * mode.
        6811                 :            :  *
        6812                 :            :  * Returns consumed size if succeed, returns -2 on decode error, or raise an
        6813                 :            :  * OSError and returns -1 on other error.
        6814                 :            :  */
        6815                 :            : static int
        6816                 :            : decode_code_page_strict(UINT code_page,
        6817                 :            :                         wchar_t **buf,
        6818                 :            :                         Py_ssize_t *bufsize,
        6819                 :            :                         const char *in,
        6820                 :            :                         int insize)
        6821                 :            : {
        6822                 :            :     DWORD flags = MB_ERR_INVALID_CHARS;
        6823                 :            :     wchar_t *out;
        6824                 :            :     DWORD outsize;
        6825                 :            :
        6826                 :            :     /* First get the size of the result */
        6827                 :            :     assert(insize > 0);
        6828                 :            :     while ((outsize = MultiByteToWideChar(code_page, flags,
        6829                 :            :                                           in, insize, NULL, 0)) <= 0)
        6830                 :            :     {
        6831                 :            :         if (!flags || GetLastError() != ERROR_INVALID_FLAGS) {
        6832                 :            :             goto error;
        6833                 :            :         }
        6834                 :            :         /* For some code pages (e.g. UTF-7) flags must be set to 0. */
        6835                 :            :         flags = 0;
        6836                 :            :     }
        6837                 :            :
        6838                 :            :     /* Extend a wchar_t* buffer */
        6839                 :            :     Py_ssize_t n = *bufsize;   /* Get the current length */
        6840                 :            :     if (widechar_resize(buf, bufsize, n + outsize) < 0) {
        6841                 :            :         return -1;
        6842                 :            :     }
        6843                 :            :     out = *buf + n;
        6844                 :            :
        6845                 :            :     /* Do the conversion */
        6846                 :            :     outsize = MultiByteToWideChar(code_page, flags, in, insize, out, outsize);
        6847                 :            :     if (outsize <= 0)
        6848                 :            :         goto error;
        6849                 :            :     return insize;
        6850                 :            :
        6851                 :            : error:
        6852                 :            :     if (GetLastError() == ERROR_NO_UNICODE_TRANSLATION)
        6853                 :            :         return -2;
        6854                 :            :     PyErr_SetFromWindowsErr(0);
        6855                 :            :     return -1;
        6856                 :            : }
        6857                 :            :
        6858                 :            : /*
        6859                 :            :  * Decode a byte string from a code page into unicode object with an error
        6860                 :            :  * handler.
        6861                 :            :  *
        6862                 :            :  * Returns consumed size if succeed, or raise an OSError or
        6863                 :            :  * UnicodeDecodeError exception and returns -1 on error.
        6864                 :            :  */
        6865                 :            : static int
        6866                 :            : decode_code_page_errors(UINT code_page,
        6867                 :            :                         wchar_t **buf,
        6868                 :            :                         Py_ssize_t *bufsize,
        6869                 :            :                         const char *in, const int size,
        6870                 :            :                         const char *errors, int final)
        6871                 :            : {
        6872                 :            :     const char *startin = in;
        6873                 :            :     const char *endin = in + size;
        6874                 :            :     DWORD flags = MB_ERR_INVALID_CHARS;
        6875                 :            :     /* Ideally, we should get reason from FormatMessage. This is the Windows
        6876                 :            :        2000 English version of the message. */
        6877                 :            :     const char *reason = "No mapping for the Unicode character exists "
        6878                 :            :                          "in the target code page.";
        6879                 :            :     /* each step cannot decode more than 1 character, but a character can be
        6880                 :            :        represented as a surrogate pair */
        6881                 :            :     wchar_t buffer[2], *out;
        6882                 :            :     int insize;
        6883                 :            :     Py_ssize_t outsize;
        6884                 :            :     PyObject *errorHandler = NULL;
        6885                 :            :     PyObject *exc = NULL;
        6886                 :            :     PyObject *encoding_obj = NULL;
        6887                 :            :     const char *encoding;
        6888                 :            :     DWORD err;
        6889                 :            :     int ret = -1;
        6890                 :            :
        6891                 :            :     assert(size > 0);
        6892                 :            :
        6893                 :            :     encoding = code_page_name(code_page, &encoding_obj);
        6894                 :            :     if (encoding == NULL)
        6895                 :            :         return -1;
        6896                 :            :
        6897                 :            :     if ((errors == NULL || strcmp(errors, "strict") == 0) && final) {
        6898                 :            :         /* The last error was ERROR_NO_UNICODE_TRANSLATION, then we raise a
        6899                 :            :            UnicodeDecodeError. */
        6900                 :            :         make_decode_exception(&exc, encoding, in, size, 0, 0, reason);
        6901                 :            :         if (exc != NULL) {
        6902                 :            :             PyCodec_StrictErrors(exc);
        6903                 :            :             Py_CLEAR(exc);
        6904                 :            :         }
        6905                 :            :         goto error;
        6906                 :            :     }
        6907                 :            :
        6908                 :            :     /* Extend a wchar_t* buffer */
        6909                 :            :     Py_ssize_t n = *bufsize;   /* Get the current length */
        6910                 :            :     if (size > (PY_SSIZE_T_MAX - n) / (Py_ssize_t)Py_ARRAY_LENGTH(buffer)) {
        6911                 :            :         PyErr_NoMemory();
        6912                 :            :         goto error;
        6913                 :            :     }
        6914                 :            :     if (widechar_resize(buf, bufsize, n + size * Py_ARRAY_LENGTH(buffer)) < 0) {
        6915                 :            :         goto error;
        6916                 :            :     }
        6917                 :            :     out = *buf + n;
        6918                 :            :
        6919                 :            :     /* Decode the byte string character per character */
        6920                 :            :     while (in < endin)
        6921                 :            :     {
        6922                 :            :         /* Decode a character */
        6923                 :            :         insize = 1;
        6924                 :            :         do
        6925                 :            :         {
        6926                 :            :             outsize = MultiByteToWideChar(code_page, flags,
        6927                 :            :                                           in, insize,
        6928                 :            :                                           buffer, Py_ARRAY_LENGTH(buffer));
        6929                 :            :             if (outsize > 0)
        6930                 :            :                 break;
        6931                 :            :             err = GetLastError();
        6932                 :            :             if (err == ERROR_INVALID_FLAGS && flags) {
        6933                 :            :                 /* For some code pages (e.g. UTF-7) flags must be set to 0. */
        6934                 :            :                 flags = 0;
        6935                 :            :                 continue;
        6936                 :            :             }
        6937                 :            :             if (err != ERROR_NO_UNICODE_TRANSLATION
        6938                 :            :                 && err != ERROR_INSUFFICIENT_BUFFER)
        6939                 :            :             {
        6940                 :            :                 PyErr_SetFromWindowsErr(0);
        6941                 :            :                 goto error;
        6942                 :            :             }
        6943                 :            :             insize++;
        6944                 :            :         }
        6945                 :            :         /* 4=maximum length of a UTF-8 sequence */
        6946                 :            :         while (insize <= 4 && (in + insize) <= endin);
        6947                 :            :
        6948                 :            :         if (outsize <= 0) {
        6949                 :            :             Py_ssize_t startinpos, endinpos, outpos;
        6950                 :            :
        6951                 :            :             /* last character in partial decode? */
        6952                 :            :             if (in + insize >= endin && !final)
        6953                 :            :                 break;
        6954                 :            :
        6955                 :            :             startinpos = in - startin;
        6956                 :            :             endinpos = startinpos + 1;
        6957                 :            :             outpos = out - *buf;
        6958                 :            :             if (unicode_decode_call_errorhandler_wchar(
        6959                 :            :                     errors, &errorHandler,
        6960                 :            :                     encoding, reason,
        6961                 :            :                     &startin, &endin, &startinpos, &endinpos, &exc, &in,
        6962                 :            :                     buf, bufsize, &outpos))
        6963                 :            :             {
        6964                 :            :                 goto error;
        6965                 :            :             }
        6966                 :            :             out = *buf + outpos;
        6967                 :            :         }
        6968                 :            :         else {
        6969                 :            :             in += insize;
        6970                 :            :             memcpy(out, buffer, outsize * sizeof(wchar_t));
        6971                 :            :             out += outsize;
        6972                 :            :         }
        6973                 :            :     }
        6974                 :            :
        6975                 :            :     /* Shrink the buffer */
        6976                 :            :     assert(out - *buf <= *bufsize);
        6977                 :            :     *bufsize = out - *buf;
        6978                 :            :     /* (in - startin) <= size and size is an int */
        6979                 :            :     ret = Py_SAFE_DOWNCAST(in - startin, Py_ssize_t, int);
        6980                 :            :
        6981                 :            : error:
        6982                 :            :     Py_XDECREF(encoding_obj);
        6983                 :            :     Py_XDECREF(errorHandler);
        6984                 :            :     Py_XDECREF(exc);
        6985                 :            :     return ret;
        6986                 :            : }
        6987                 :            :
        6988                 :            : static PyObject *
        6989                 :            : decode_code_page_stateful(int code_page,
        6990                 :            :                           const char *s, Py_ssize_t size,
        6991                 :            :                           const char *errors, Py_ssize_t *consumed)
        6992                 :            : {
        6993                 :            :     wchar_t *buf = NULL;
        6994                 :            :     Py_ssize_t bufsize = 0;
        6995                 :            :     int chunk_size, final, converted, done;
        6996                 :            :
        6997                 :            :     if (code_page < 0) {
        6998                 :            :         PyErr_SetString(PyExc_ValueError, "invalid code page number");
        6999                 :            :         return NULL;
        7000                 :            :     }
        7001                 :            :     if (size < 0) {
        7002                 :            :         PyErr_BadInternalCall();
        7003                 :            :         return NULL;
        7004                 :            :     }
        7005                 :            :
        7006                 :            :     if (consumed)
        7007                 :            :         *consumed = 0;
        7008                 :            :
        7009                 :            :     do
        7010                 :            :     {
        7011                 :            : #ifdef NEED_RETRY
        7012                 :            :         if (size > DECODING_CHUNK_SIZE) {
        7013                 :            :             chunk_size = DECODING_CHUNK_SIZE;
        7014                 :            :             final = 0;
        7015                 :            :             done = 0;
        7016                 :            :         }
        7017                 :            :         else
        7018                 :            : #endif
        7019                 :            :         {
        7020                 :            :             chunk_size = (int)size;
        7021                 :            :             final = (consumed == NULL);
        7022                 :            :             done = 1;
        7023                 :            :         }
        7024                 :            :
        7025                 :            :         if (chunk_size == 0 && done) {
        7026                 :            :             if (buf != NULL)
        7027                 :            :                 break;
        7028                 :            :             _Py_RETURN_UNICODE_EMPTY();
        7029                 :            :         }
        7030                 :            :
        7031                 :            :         converted = decode_code_page_strict(code_page, &buf, &bufsize,
        7032                 :            :                                             s, chunk_size);
        7033                 :            :         if (converted == -2)
        7034                 :            :             converted = decode_code_page_errors(code_page, &buf, &bufsize,
        7035                 :            :                                                 s, chunk_size,
        7036                 :            :                                                 errors, final);
        7037                 :            :         assert(converted != 0 || done);
        7038                 :            :
        7039                 :            :         if (converted < 0) {
        7040                 :            :             PyMem_Free(buf);
        7041                 :            :             return NULL;
        7042                 :            :         }
        7043                 :            :
        7044                 :            :         if (consumed)
        7045                 :            :             *consumed += converted;
        7046                 :            :
        7047                 :            :         s += converted;
        7048                 :            :         size -= converted;
        7049                 :            :     } while (!done);
        7050                 :            :
        7051                 :            :     PyObject *v = PyUnicode_FromWideChar(buf, bufsize);
        7052                 :            :     PyMem_Free(buf);
        7053                 :            :     return v;
        7054                 :            : }
        7055                 :            :
        7056                 :            : PyObject *
        7057                 :            : PyUnicode_DecodeCodePageStateful(int code_page,
        7058                 :            :                                  const char *s,
        7059                 :            :                                  Py_ssize_t size,
        7060                 :            :                                  const char *errors,
        7061                 :            :                                  Py_ssize_t *consumed)
        7062                 :            : {
        7063                 :            :     return decode_code_page_stateful(code_page, s, size, errors, consumed);
        7064                 :            : }
        7065                 :            :
        7066                 :            : PyObject *
        7067                 :            : PyUnicode_DecodeMBCSStateful(const char *s,
        7068                 :            :                              Py_ssize_t size,
        7069                 :            :                              const char *errors,
        7070                 :            :                              Py_ssize_t *consumed)
        7071                 :            : {
        7072                 :            :     return decode_code_page_stateful(CP_ACP, s, size, errors, consumed);
        7073                 :            : }
        7074                 :            :
        7075                 :            : PyObject *
        7076                 :            : PyUnicode_DecodeMBCS(const char *s,
        7077                 :            :                      Py_ssize_t size,
        7078                 :            :                      const char *errors)
        7079                 :            : {
        7080                 :            :     return PyUnicode_DecodeMBCSStateful(s, size, errors, NULL);
        7081                 :            : }
        7082                 :            :
        7083                 :            : static DWORD
        7084                 :            : encode_code_page_flags(UINT code_page, const char *errors)
        7085                 :            : {
        7086                 :            :     if (code_page == CP_UTF8) {
        7087                 :            :         return WC_ERR_INVALID_CHARS;
        7088                 :            :     }
        7089                 :            :     else if (code_page == CP_UTF7) {
        7090                 :            :         /* CP_UTF7 only supports flags=0 */
        7091                 :            :         return 0;
        7092                 :            :     }
        7093                 :            :     else {
        7094                 :            :         if (errors != NULL && strcmp(errors, "replace") == 0)
        7095                 :            :             return 0;
        7096                 :            :         else
        7097                 :            :             return WC_NO_BEST_FIT_CHARS;
        7098                 :            :     }
        7099                 :            : }
        7100                 :            :
        7101                 :            : /*
        7102                 :            :  * Encode a Unicode string to a Windows code page into a byte string in strict
        7103                 :            :  * mode.
        7104                 :            :  *
        7105                 :            :  * Returns consumed characters if succeed, returns -2 on encode error, or raise
        7106                 :            :  * an OSError and returns -1 on other error.
        7107                 :            :  */
        7108                 :            : static int
        7109                 :            : encode_code_page_strict(UINT code_page, PyObject **outbytes,
        7110                 :            :                         PyObject *unicode, Py_ssize_t offset, int len,
        7111                 :            :                         const char* errors)
        7112                 :            : {
        7113                 :            :     BOOL usedDefaultChar = FALSE;
        7114                 :            :     BOOL *pusedDefaultChar = &usedDefaultChar;
        7115                 :            :     int outsize;
        7116                 :            :     wchar_t *p;
        7117                 :            :     Py_ssize_t size;
        7118                 :            :     const DWORD flags = encode_code_page_flags(code_page, NULL);
        7119                 :            :     char *out;
        7120                 :            :     /* Create a substring so that we can get the UTF-16 representation
        7121                 :            :        of just the slice under consideration. */
        7122                 :            :     PyObject *substring;
        7123                 :            :     int ret = -1;
        7124                 :            :
        7125                 :            :     assert(len > 0);
        7126                 :            :
        7127                 :            :     if (code_page != CP_UTF8 && code_page != CP_UTF7)
        7128                 :            :         pusedDefaultChar = &usedDefaultChar;
        7129                 :            :     else
        7130                 :            :         pusedDefaultChar = NULL;
        7131                 :            :
        7132                 :            :     substring = PyUnicode_Substring(unicode, offset, offset+len);
        7133                 :            :     if (substring == NULL)
        7134                 :            :         return -1;
        7135                 :            :     p = PyUnicode_AsWideCharString(substring, &size);
        7136                 :            :     Py_CLEAR(substring);
        7137                 :            :     if (p == NULL) {
        7138                 :            :         return -1;
        7139                 :            :     }
        7140                 :            :     assert(size <= INT_MAX);
        7141                 :            :
        7142                 :            :     /* First get the size of the result */
        7143                 :            :     outsize = WideCharToMultiByte(code_page, flags,
        7144                 :            :                                   p, (int)size,
        7145                 :            :                                   NULL, 0,
        7146                 :            :                                   NULL, pusedDefaultChar);
        7147                 :            :     if (outsize <= 0)
        7148                 :            :         goto error;
        7149                 :            :     /* If we used a default char, then we failed! */
        7150                 :            :     if (pusedDefaultChar && *pusedDefaultChar) {
        7151                 :            :         ret = -2;
        7152                 :            :         goto done;
        7153                 :            :     }
        7154                 :            :
        7155                 :            :     if (*outbytes == NULL) {
        7156                 :            :         /* Create string object */
        7157                 :            :         *outbytes = PyBytes_FromStringAndSize(NULL, outsize);
        7158                 :            :         if (*outbytes == NULL) {
        7159                 :            :             goto done;
        7160                 :            :         }
        7161                 :            :         out = PyBytes_AS_STRING(*outbytes);
        7162                 :            :     }
        7163                 :            :     else {
        7164                 :            :         /* Extend string object */
        7165                 :            :         const Py_ssize_t n = PyBytes_Size(*outbytes);
        7166                 :            :         if (outsize > PY_SSIZE_T_MAX - n) {
        7167                 :            :             PyErr_NoMemory();
        7168                 :            :             goto done;
        7169                 :            :         }
        7170                 :            :         if (_PyBytes_Resize(outbytes, n + outsize) < 0) {
        7171                 :            :             goto done;
        7172                 :            :         }
        7173                 :            :         out = PyBytes_AS_STRING(*outbytes) + n;
        7174                 :            :     }
        7175                 :            :
        7176                 :            :     /* Do the conversion */
        7177                 :            :     outsize = WideCharToMultiByte(code_page, flags,
        7178                 :            :                                   p, (int)size,
        7179                 :            :                                   out, outsize,
        7180                 :            :                                   NULL, pusedDefaultChar);
        7181                 :            :     if (outsize <= 0)
        7182                 :            :         goto error;
        7183                 :            :     if (pusedDefaultChar && *pusedDefaultChar) {
        7184                 :            :         ret = -2;
        7185                 :            :         goto done;
        7186                 :            :     }
        7187                 :            :     ret = 0;
        7188                 :            :
        7189                 :            : done:
        7190                 :            :     PyMem_Free(p);
        7191                 :            :     return ret;
        7192                 :            :
        7193                 :            : error:
        7194                 :            :     if (GetLastError() == ERROR_NO_UNICODE_TRANSLATION) {
        7195                 :            :         ret = -2;
        7196                 :            :         goto done;
        7197                 :            :     }
        7198                 :            :     PyErr_SetFromWindowsErr(0);
        7199                 :            :     goto done;
        7200                 :            : }
        7201                 :            :
        7202                 :            : /*
        7203                 :            :  * Encode a Unicode string to a Windows code page into a byte string using an
        7204                 :            :  * error handler.
        7205                 :            :  *
        7206                 :            :  * Returns consumed characters if succeed, or raise an OSError and returns
        7207                 :            :  * -1 on other error.
        7208                 :            :  */
        7209                 :            : static int
        7210                 :            : encode_code_page_errors(UINT code_page, PyObject **outbytes,
        7211                 :            :                         PyObject *unicode, Py_ssize_t unicode_offset,
        7212                 :            :                         Py_ssize_t insize, const char* errors)
        7213                 :            : {
        7214                 :            :     const DWORD flags = encode_code_page_flags(code_page, errors);
        7215                 :            :     Py_ssize_t pos = unicode_offset;
        7216                 :            :     Py_ssize_t endin = unicode_offset + insize;
        7217                 :            :     /* Ideally, we should get reason from FormatMessage. This is the Windows
        7218                 :            :        2000 English version of the message. */
        7219                 :            :     const char *reason = "invalid character";
        7220                 :            :     /* 4=maximum length of a UTF-8 sequence */
        7221                 :            :     char buffer[4];
        7222                 :            :     BOOL usedDefaultChar = FALSE, *pusedDefaultChar;
        7223                 :            :     Py_ssize_t outsize;
        7224                 :            :     char *out;
        7225                 :            :     PyObject *errorHandler = NULL;
        7226                 :            :     PyObject *exc = NULL;
        7227                 :            :     PyObject *encoding_obj = NULL;
        7228                 :            :     const char *encoding;
        7229                 :            :     Py_ssize_t newpos, newoutsize;
        7230                 :            :     PyObject *rep;
        7231                 :            :     int ret = -1;
        7232                 :            :
        7233                 :            :     assert(insize > 0);
        7234                 :            :
        7235                 :            :     encoding = code_page_name(code_page, &encoding_obj);
        7236                 :            :     if (encoding == NULL)
        7237                 :            :         return -1;
        7238                 :            :
        7239                 :            :     if (errors == NULL || strcmp(errors, "strict") == 0) {
        7240                 :            :         /* The last error was ERROR_NO_UNICODE_TRANSLATION,
        7241                 :            :            then we raise a UnicodeEncodeError. */
        7242                 :            :         make_encode_exception(&exc, encoding, unicode, 0, 0, reason);
        7243                 :            :         if (exc != NULL) {
        7244                 :            :             PyCodec_StrictErrors(exc);
        7245                 :            :             Py_DECREF(exc);
        7246                 :            :         }
        7247                 :            :         Py_XDECREF(encoding_obj);
        7248                 :            :         return -1;
        7249                 :            :     }
        7250                 :            :
        7251                 :            :     if (code_page != CP_UTF8 && code_page != CP_UTF7)
        7252                 :            :         pusedDefaultChar = &usedDefaultChar;
        7253                 :            :     else
        7254                 :            :         pusedDefaultChar = NULL;
        7255                 :            :
        7256                 :            :     if (Py_ARRAY_LENGTH(buffer) > PY_SSIZE_T_MAX / insize) {
        7257                 :            :         PyErr_NoMemory();
        7258                 :            :         goto error;
        7259                 :            :     }
        7260                 :            :     outsize = insize * Py_ARRAY_LENGTH(buffer);
        7261                 :            :
        7262                 :            :     if (*outbytes == NULL) {
        7263                 :            :         /* Create string object */
        7264                 :            :         *outbytes = PyBytes_FromStringAndSize(NULL, outsize);
        7265                 :            :         if (*outbytes == NULL)
        7266                 :            :             goto error;
        7267                 :            :         out = PyBytes_AS_STRING(*outbytes);
        7268                 :            :     }
        7269                 :            :     else {
        7270                 :            :         /* Extend string object */
        7271                 :            :         Py_ssize_t n = PyBytes_Size(*outbytes);
        7272                 :            :         if (n > PY_SSIZE_T_MAX - outsize) {
        7273                 :            :             PyErr_NoMemory();
        7274                 :            :             goto error;
        7275                 :            :         }
        7276                 :            :         if (_PyBytes_Resize(outbytes, n + outsize) < 0)
        7277                 :            :             goto error;
        7278                 :            :         out = PyBytes_AS_STRING(*outbytes) + n;
        7279                 :            :     }
        7280                 :            :
        7281                 :            :     /* Encode the string character per character */
        7282                 :            :     while (pos < endin)
        7283                 :            :     {
        7284                 :            :         Py_UCS4 ch = PyUnicode_READ_CHAR(unicode, pos);
        7285                 :            :         wchar_t chars[2];
        7286                 :            :         int charsize;
        7287                 :            :         if (ch < 0x10000) {
        7288                 :            :             chars[0] = (wchar_t)ch;
        7289                 :            :             charsize = 1;
        7290                 :            :         }
        7291                 :            :         else {
        7292                 :            :             chars[0] = Py_UNICODE_HIGH_SURROGATE(ch);
        7293                 :            :             chars[1] = Py_UNICODE_LOW_SURROGATE(ch);
        7294                 :            :             charsize = 2;
        7295                 :            :         }
        7296                 :            :
        7297                 :            :         outsize = WideCharToMultiByte(code_page, flags,
        7298                 :            :                                       chars, charsize,
        7299                 :            :                                       buffer, Py_ARRAY_LENGTH(buffer),
        7300                 :            :                                       NULL, pusedDefaultChar);
        7301                 :            :         if (outsize > 0) {
        7302                 :            :             if (pusedDefaultChar == NULL || !(*pusedDefaultChar))
        7303                 :            :             {
        7304                 :            :                 pos++;
        7305                 :            :                 memcpy(out, buffer, outsize);
        7306                 :            :                 out += outsize;
        7307                 :            :                 continue;
        7308                 :            :             }
        7309                 :            :         }
        7310                 :            :         else if (GetLastError() != ERROR_NO_UNICODE_TRANSLATION) {
        7311                 :            :             PyErr_SetFromWindowsErr(0);
        7312                 :            :             goto error;
        7313                 :            :         }
        7314                 :            :
        7315                 :            :         rep = unicode_encode_call_errorhandler(
        7316                 :            :                   errors, &errorHandler, encoding, reason,
        7317                 :            :                   unicode, &exc,
        7318                 :            :                   pos, pos + 1, &newpos);
        7319                 :            :         if (rep == NULL)
        7320                 :            :             goto error;
        7321                 :            :
        7322                 :            :         Py_ssize_t morebytes = pos - newpos;
        7323                 :            :         if (PyBytes_Check(rep)) {
        7324                 :            :             outsize = PyBytes_GET_SIZE(rep);
        7325                 :            :             morebytes += outsize;
        7326                 :            :             if (morebytes > 0) {
        7327                 :            :                 Py_ssize_t offset = out - PyBytes_AS_STRING(*outbytes);
        7328                 :            :                 newoutsize = PyBytes_GET_SIZE(*outbytes) + morebytes;
        7329                 :            :                 if (_PyBytes_Resize(outbytes, newoutsize) < 0) {
        7330                 :            :                     Py_DECREF(rep);
        7331                 :            :                     goto error;
        7332                 :            :                 }
        7333                 :            :                 out = PyBytes_AS_STRING(*outbytes) + offset;
        7334                 :            :             }
        7335                 :            :             memcpy(out, PyBytes_AS_STRING(rep), outsize);
        7336                 :            :             out += outsize;
        7337                 :            :         }
        7338                 :            :         else {
        7339                 :            :             Py_ssize_t i;
        7340                 :            :             int kind;
        7341                 :            :             const void *data;
        7342                 :            :
        7343                 :            :             outsize = PyUnicode_GET_LENGTH(rep);
        7344                 :            :             morebytes += outsize;
        7345                 :            :             if (morebytes > 0) {
        7346                 :            :                 Py_ssize_t offset = out - PyBytes_AS_STRING(*outbytes);
        7347                 :            :                 newoutsize = PyBytes_GET_SIZE(*outbytes) + morebytes;
        7348                 :            :                 if (_PyBytes_Resize(outbytes, newoutsize) < 0) {
        7349                 :            :                     Py_DECREF(rep);
        7350                 :            :                     goto error;
        7351                 :            :                 }
        7352                 :            :                 out = PyBytes_AS_STRING(*outbytes) + offset;
        7353                 :            :             }
        7354                 :            :             kind = PyUnicode_KIND(rep);
        7355                 :            :             data = PyUnicode_DATA(rep);
        7356                 :            :             for (i=0; i < outsize; i++) {
        7357                 :            :                 Py_UCS4 ch = PyUnicode_READ(kind, data, i);
        7358                 :            :                 if (ch > 127) {
        7359                 :            :                     raise_encode_exception(&exc,
        7360                 :            :                         encoding, unicode,
        7361                 :            :                         pos, pos + 1,
        7362                 :            :                         "unable to encode error handler result to ASCII");
        7363                 :            :                     Py_DECREF(rep);
        7364                 :            :                     goto error;
        7365                 :            :                 }
        7366                 :            :                 *out = (unsigned char)ch;
        7367                 :            :                 out++;
        7368                 :            :             }
        7369                 :            :         }
        7370                 :            :         pos = newpos;
        7371                 :            :         Py_DECREF(rep);
        7372                 :            :     }
        7373                 :            :     /* write a NUL byte */
        7374                 :            :     *out = 0;
        7375                 :            :     outsize = out - PyBytes_AS_STRING(*outbytes);
        7376                 :            :     assert(outsize <= PyBytes_GET_SIZE(*outbytes));
        7377                 :            :     if (_PyBytes_Resize(outbytes, outsize) < 0)
        7378                 :            :         goto error;
        7379                 :            :     ret = 0;
        7380                 :            :
        7381                 :            : error:
        7382                 :            :     Py_XDECREF(encoding_obj);
        7383                 :            :     Py_XDECREF(errorHandler);
        7384                 :            :     Py_XDECREF(exc);
        7385                 :            :     return ret;
        7386                 :            : }
        7387                 :            :
        7388                 :            : static PyObject *
        7389                 :            : encode_code_page(int code_page,
        7390                 :            :                  PyObject *unicode,
        7391                 :            :                  const char *errors)
        7392                 :            : {
        7393                 :            :     Py_ssize_t len;
        7394                 :            :     PyObject *outbytes = NULL;
        7395                 :            :     Py_ssize_t offset;
        7396                 :            :     int chunk_len, ret, done;
        7397                 :            :
        7398                 :            :     if (!PyUnicode_Check(unicode)) {
        7399                 :            :         PyErr_BadArgument();
        7400                 :            :         return NULL;
        7401                 :            :     }
        7402                 :            :
        7403                 :            :     len = PyUnicode_GET_LENGTH(unicode);
        7404                 :            :
        7405                 :            :     if (code_page < 0) {
        7406                 :            :         PyErr_SetString(PyExc_ValueError, "invalid code page number");
        7407                 :            :         return NULL;
        7408                 :            :     }
        7409                 :            :
        7410                 :            :     if (len == 0)
        7411                 :            :         return PyBytes_FromStringAndSize(NULL, 0);
        7412                 :            :
        7413                 :            :     offset = 0;
        7414                 :            :     do
        7415                 :            :     {
        7416                 :            : #ifdef NEED_RETRY
        7417                 :            :         if (len > DECODING_CHUNK_SIZE) {
        7418                 :            :             chunk_len = DECODING_CHUNK_SIZE;
        7419                 :            :             done = 0;
        7420                 :            :         }
        7421                 :            :         else
        7422                 :            : #endif
        7423                 :            :         {
        7424                 :            :             chunk_len = (int)len;
        7425                 :            :             done = 1;
        7426                 :            :         }
        7427                 :            :
        7428                 :            :         ret = encode_code_page_strict(code_page, &outbytes,
        7429                 :            :                                       unicode, offset, chunk_len,
        7430                 :            :                                       errors);
        7431                 :            :         if (ret == -2)
        7432                 :            :             ret = encode_code_page_errors(code_page, &outbytes,
        7433                 :            :                                           unicode, offset,
        7434                 :            :                                           chunk_len, errors);
        7435                 :            :         if (ret < 0) {
        7436                 :            :             Py_XDECREF(outbytes);
        7437                 :            :             return NULL;
        7438                 :            :         }
        7439                 :            :
        7440                 :            :         offset += chunk_len;
        7441                 :            :         len -= chunk_len;
        7442                 :            :     } while (!done);
        7443                 :            :
        7444                 :            :     return outbytes;
        7445                 :            : }
        7446                 :            :
        7447                 :            : PyObject *
        7448                 :            : PyUnicode_EncodeCodePage(int code_page,
        7449                 :            :                          PyObject *unicode,
        7450                 :            :                          const char *errors)
        7451                 :            : {
        7452                 :            :     return encode_code_page(code_page, unicode, errors);
        7453                 :            : }
        7454                 :            :
        7455                 :            : PyObject *
        7456                 :            : PyUnicode_AsMBCSString(PyObject *unicode)
        7457                 :            : {
        7458                 :            :     return PyUnicode_EncodeCodePage(CP_ACP, unicode, NULL);
        7459                 :            : }
        7460                 :            :
        7461                 :            : #undef NEED_RETRY
        7462                 :            :
        7463                 :            : #endif /* MS_WINDOWS */
        7464                 :            :
        7465                 :            : /* --- Character Mapping Codec -------------------------------------------- */
        7466                 :            :
        7467                 :            : static int
        7468                 :          0 : charmap_decode_string(const char *s,
        7469                 :            :                       Py_ssize_t size,
        7470                 :            :                       PyObject *mapping,
        7471                 :            :                       const char *errors,
        7472                 :            :                       _PyUnicodeWriter *writer)
        7473                 :            : {
        7474                 :          0 :     const char *starts = s;
        7475                 :            :     const char *e;
        7476                 :            :     Py_ssize_t startinpos, endinpos;
        7477                 :          0 :     PyObject *errorHandler = NULL, *exc = NULL;
        7478                 :            :     Py_ssize_t maplen;
        7479                 :            :     int mapkind;
        7480                 :            :     const void *mapdata;
        7481                 :            :     Py_UCS4 x;
        7482                 :            :     unsigned char ch;
        7483                 :            :
        7484                 :          0 :     maplen = PyUnicode_GET_LENGTH(mapping);
        7485                 :          0 :     mapdata = PyUnicode_DATA(mapping);
        7486                 :          0 :     mapkind = PyUnicode_KIND(mapping);
        7487                 :            :
        7488                 :          0 :     e = s + size;
        7489                 :            :
        7490   [ #  #  #  # ]:          0 :     if (mapkind == PyUnicode_1BYTE_KIND && maplen >= 256) {
        7491                 :            :         /* fast-path for cp037, cp500 and iso8859_1 encodings. iso8859_1
        7492                 :            :          * is disabled in encoding aliases, latin1 is preferred because
        7493                 :            :          * its implementation is faster. */
        7494                 :          0 :         const Py_UCS1 *mapdata_ucs1 = (const Py_UCS1 *)mapdata;
        7495                 :          0 :         Py_UCS1 *outdata = (Py_UCS1 *)writer->data;
        7496                 :          0 :         Py_UCS4 maxchar = writer->maxchar;
        7497                 :            :
        7498                 :            :         assert (writer->kind == PyUnicode_1BYTE_KIND);
        7499         [ #  # ]:          0 :         while (s < e) {
        7500                 :          0 :             ch = *s;
        7501                 :          0 :             x = mapdata_ucs1[ch];
        7502         [ #  # ]:          0 :             if (x > maxchar) {
        7503   [ #  #  #  #  :          0 :                 if (_PyUnicodeWriter_Prepare(writer, 1, 0xff) == -1)
                       #  # ]
        7504                 :          0 :                     goto onError;
        7505                 :          0 :                 maxchar = writer->maxchar;
        7506                 :          0 :                 outdata = (Py_UCS1 *)writer->data;
        7507                 :            :             }
        7508                 :          0 :             outdata[writer->pos] = x;
        7509                 :          0 :             writer->pos++;
        7510                 :          0 :             ++s;
        7511                 :            :         }
        7512                 :          0 :         return 0;
        7513                 :            :     }
        7514                 :            :
        7515         [ #  # ]:          0 :     while (s < e) {
        7516   [ #  #  #  # ]:          0 :         if (mapkind == PyUnicode_2BYTE_KIND && maplen >= 256) {
        7517                 :          0 :             int outkind = writer->kind;
        7518                 :          0 :             const Py_UCS2 *mapdata_ucs2 = (const Py_UCS2 *)mapdata;
        7519         [ #  # ]:          0 :             if (outkind == PyUnicode_1BYTE_KIND) {
        7520                 :          0 :                 Py_UCS1 *outdata = (Py_UCS1 *)writer->data;
        7521                 :          0 :                 Py_UCS4 maxchar = writer->maxchar;
        7522         [ #  # ]:          0 :                 while (s < e) {
        7523                 :          0 :                     ch = *s;
        7524                 :          0 :                     x = mapdata_ucs2[ch];
        7525         [ #  # ]:          0 :                     if (x > maxchar)
        7526                 :          0 :                         goto Error;
        7527                 :          0 :                     outdata[writer->pos] = x;
        7528                 :          0 :                     writer->pos++;
        7529                 :          0 :                     ++s;
        7530                 :            :                 }
        7531                 :          0 :                 break;
        7532                 :            :             }
        7533         [ #  # ]:          0 :             else if (outkind == PyUnicode_2BYTE_KIND) {
        7534                 :          0 :                 Py_UCS2 *outdata = (Py_UCS2 *)writer->data;
        7535         [ #  # ]:          0 :                 while (s < e) {
        7536                 :          0 :                     ch = *s;
        7537                 :          0 :                     x = mapdata_ucs2[ch];
        7538         [ #  # ]:          0 :                     if (x == 0xFFFE)
        7539                 :          0 :                         goto Error;
        7540                 :          0 :                     outdata[writer->pos] = x;
        7541                 :          0 :                     writer->pos++;
        7542                 :          0 :                     ++s;
        7543                 :            :                 }
        7544                 :          0 :                 break;
        7545                 :            :             }
        7546                 :            :         }
        7547                 :          0 :         ch = *s;
        7548                 :            :
        7549         [ #  # ]:          0 :         if (ch < maplen)
        7550                 :          0 :             x = PyUnicode_READ(mapkind, mapdata, ch);
        7551                 :            :         else
        7552                 :          0 :             x = 0xfffe; /* invalid value */
        7553                 :          0 : Error:
        7554         [ #  # ]:          0 :         if (x == 0xfffe)
        7555                 :            :         {
        7556                 :            :             /* undefined mapping */
        7557                 :          0 :             startinpos = s-starts;
        7558                 :          0 :             endinpos = startinpos+1;
        7559         [ #  # ]:          0 :             if (unicode_decode_call_errorhandler_writer(
        7560                 :            :                     errors, &errorHandler,
        7561                 :            :                     "charmap", "character maps to <undefined>",
        7562                 :            :                     &starts, &e, &startinpos, &endinpos, &exc, &s,
        7563                 :            :                     writer)) {
        7564                 :          0 :                 goto onError;
        7565                 :            :             }
        7566                 :          0 :             continue;
        7567                 :            :         }
        7568                 :            :
        7569         [ #  # ]:          0 :         if (_PyUnicodeWriter_WriteCharInline(writer, x) < 0)
        7570                 :          0 :             goto onError;
        7571                 :          0 :         ++s;
        7572                 :            :     }
        7573                 :          0 :     Py_XDECREF(errorHandler);
        7574                 :          0 :     Py_XDECREF(exc);
        7575                 :          0 :     return 0;
        7576                 :            :
        7577                 :          0 : onError:
        7578                 :          0 :     Py_XDECREF(errorHandler);
        7579                 :          0 :     Py_XDECREF(exc);
        7580                 :          0 :     return -1;
        7581                 :            : }
        7582                 :            :
        7583                 :            : static int
        7584                 :          0 : charmap_decode_mapping(const char *s,
        7585                 :            :                        Py_ssize_t size,
        7586                 :            :                        PyObject *mapping,
        7587                 :            :                        const char *errors,
        7588                 :            :                        _PyUnicodeWriter *writer)
        7589                 :            : {
        7590                 :          0 :     const char *starts = s;
        7591                 :            :     const char *e;
        7592                 :            :     Py_ssize_t startinpos, endinpos;
        7593                 :          0 :     PyObject *errorHandler = NULL, *exc = NULL;
        7594                 :            :     unsigned char ch;
        7595                 :          0 :     PyObject *key, *item = NULL;
        7596                 :            :
        7597                 :          0 :     e = s + size;
        7598                 :            :
        7599         [ #  # ]:          0 :     while (s < e) {
        7600                 :          0 :         ch = *s;
        7601                 :            :
        7602                 :            :         /* Get mapping (char ordinal -> integer, Unicode char or None) */
        7603                 :          0 :         key = PyLong_FromLong((long)ch);
        7604         [ #  # ]:          0 :         if (key == NULL)
        7605                 :          0 :             goto onError;
        7606                 :            :
        7607                 :          0 :         item = PyObject_GetItem(mapping, key);
        7608                 :          0 :         Py_DECREF(key);
        7609         [ #  # ]:          0 :         if (item == NULL) {
        7610         [ #  # ]:          0 :             if (PyErr_ExceptionMatches(PyExc_LookupError)) {
        7611                 :            :                 /* No mapping found means: mapping is undefined. */
        7612                 :          0 :                 PyErr_Clear();
        7613                 :          0 :                 goto Undefined;
        7614                 :            :             } else
        7615                 :          0 :                 goto onError;
        7616                 :            :         }
        7617                 :            :
        7618                 :            :         /* Apply mapping */
        7619         [ #  # ]:          0 :         if (item == Py_None)
        7620                 :          0 :             goto Undefined;
        7621         [ #  # ]:          0 :         if (PyLong_Check(item)) {
        7622                 :          0 :             long value = PyLong_AS_LONG(item);
        7623         [ #  # ]:          0 :             if (value == 0xFFFE)
        7624                 :          0 :                 goto Undefined;
        7625   [ #  #  #  # ]:          0 :             if (value < 0 || value > MAX_UNICODE) {
        7626                 :          0 :                 PyErr_Format(PyExc_TypeError,
        7627                 :            :                              "character mapping must be in range(0x%x)",
        7628                 :            :                              (unsigned long)MAX_UNICODE + 1);
        7629                 :          0 :                 goto onError;
        7630                 :            :             }
        7631                 :            :
        7632         [ #  # ]:          0 :             if (_PyUnicodeWriter_WriteCharInline(writer, value) < 0)
        7633                 :          0 :                 goto onError;
        7634                 :            :         }
        7635         [ #  # ]:          0 :         else if (PyUnicode_Check(item)) {
        7636         [ #  # ]:          0 :             if (PyUnicode_GET_LENGTH(item) == 1) {
        7637                 :          0 :                 Py_UCS4 value = PyUnicode_READ_CHAR(item, 0);
        7638         [ #  # ]:          0 :                 if (value == 0xFFFE)
        7639                 :          0 :                     goto Undefined;
        7640         [ #  # ]:          0 :                 if (_PyUnicodeWriter_WriteCharInline(writer, value) < 0)
        7641                 :          0 :                     goto onError;
        7642                 :            :             }
        7643                 :            :             else {
        7644                 :          0 :                 writer->overallocate = 1;
        7645         [ #  # ]:          0 :                 if (_PyUnicodeWriter_WriteStr(writer, item) == -1)
        7646                 :          0 :                     goto onError;
        7647                 :            :             }
        7648                 :            :         }
        7649                 :            :         else {
        7650                 :            :             /* wrong return value */
        7651                 :          0 :             PyErr_SetString(PyExc_TypeError,
        7652                 :            :                             "character mapping must return integer, None or str");
        7653                 :          0 :             goto onError;
        7654                 :            :         }
        7655         [ #  # ]:          0 :         Py_CLEAR(item);
        7656                 :          0 :         ++s;
        7657                 :          0 :         continue;
        7658                 :            :
        7659                 :          0 : Undefined:
        7660                 :            :         /* undefined mapping */
        7661         [ #  # ]:          0 :         Py_CLEAR(item);
        7662                 :          0 :         startinpos = s-starts;
        7663                 :          0 :         endinpos = startinpos+1;
        7664         [ #  # ]:          0 :         if (unicode_decode_call_errorhandler_writer(
        7665                 :            :                 errors, &errorHandler,
        7666                 :            :                 "charmap", "character maps to <undefined>",
        7667                 :            :                 &starts, &e, &startinpos, &endinpos, &exc, &s,
        7668                 :            :                 writer)) {
        7669                 :          0 :             goto onError;
        7670                 :            :         }
        7671                 :            :     }
        7672                 :          0 :     Py_XDECREF(errorHandler);
        7673                 :          0 :     Py_XDECREF(exc);
        7674                 :          0 :     return 0;
        7675                 :            :
        7676                 :          0 : onError:
        7677                 :          0 :     Py_XDECREF(item);
        7678                 :          0 :     Py_XDECREF(errorHandler);
        7679                 :          0 :     Py_XDECREF(exc);
        7680                 :          0 :     return -1;
        7681                 :            : }
        7682                 :            :
        7683                 :            : PyObject *
        7684                 :          0 : PyUnicode_DecodeCharmap(const char *s,
        7685                 :            :                         Py_ssize_t size,
        7686                 :            :                         PyObject *mapping,
        7687                 :            :                         const char *errors)
        7688                 :            : {
        7689                 :            :     _PyUnicodeWriter writer;
        7690                 :            :
        7691                 :            :     /* Default to Latin-1 */
        7692         [ #  # ]:          0 :     if (mapping == NULL)
        7693                 :          0 :         return PyUnicode_DecodeLatin1(s, size, errors);
        7694                 :            :
        7695         [ #  # ]:          0 :     if (size == 0)
        7696                 :          0 :         _Py_RETURN_UNICODE_EMPTY();
        7697                 :          0 :     _PyUnicodeWriter_Init(&writer);
        7698                 :          0 :     writer.min_length = size;
        7699   [ #  #  #  #  :          0 :     if (_PyUnicodeWriter_Prepare(&writer, writer.min_length, 127) == -1)
                 #  #  #  # ]
        7700                 :          0 :         goto onError;
        7701                 :            :
        7702         [ #  # ]:          0 :     if (PyUnicode_CheckExact(mapping)) {
        7703         [ #  # ]:          0 :         if (charmap_decode_string(s, size, mapping, errors, &writer) < 0)
        7704                 :          0 :             goto onError;
        7705                 :            :     }
        7706                 :            :     else {
        7707         [ #  # ]:          0 :         if (charmap_decode_mapping(s, size, mapping, errors, &writer) < 0)
        7708                 :          0 :             goto onError;
        7709                 :            :     }
        7710                 :          0 :     return _PyUnicodeWriter_Finish(&writer);
        7711                 :            :
        7712                 :          0 :   onError:
        7713                 :          0 :     _PyUnicodeWriter_Dealloc(&writer);
        7714                 :          0 :     return NULL;
        7715                 :            : }
        7716                 :            :
        7717                 :            : /* Charmap encoding: the lookup table */
        7718                 :            :
        7719                 :            : /*[clinic input]
        7720                 :            : class EncodingMap "struct encoding_map *" "&EncodingMapType"
        7721                 :            : [clinic start generated code]*/
        7722                 :            : /*[clinic end generated code: output=da39a3ee5e6b4b0d input=14e46bbb6c522d22]*/
        7723                 :            :
        7724                 :            : struct encoding_map {
        7725                 :            :     PyObject_HEAD
        7726                 :            :     unsigned char level1[32];
        7727                 :            :     int count2, count3;
        7728                 :            :     unsigned char level23[1];
        7729                 :            : };
        7730                 :            :
        7731                 :            : /*[clinic input]
        7732                 :            : EncodingMap.size
        7733                 :            :
        7734                 :            : Return the size (in bytes) of this object.
        7735                 :            : [clinic start generated code]*/
        7736                 :            :
        7737                 :            : static PyObject *
        7738                 :          0 : EncodingMap_size_impl(struct encoding_map *self)
        7739                 :            : /*[clinic end generated code: output=c4c969e4c99342a4 input=004ff13f26bb5366]*/
        7740                 :            : {
        7741                 :          0 :     return PyLong_FromLong((sizeof(*self) - 1) + 16*self->count2 +
        7742                 :          0 :                            128*self->count3);
        7743                 :            : }
        7744                 :            :
        7745                 :            : static PyMethodDef encoding_map_methods[] = {
        7746                 :            :     ENCODINGMAP_SIZE_METHODDEF
        7747                 :            :     {NULL, NULL}
        7748                 :            : };
        7749                 :            :
        7750                 :            : static PyTypeObject EncodingMapType = {
        7751                 :            :     PyVarObject_HEAD_INIT(NULL, 0)
        7752                 :            :     .tp_name = "EncodingMap",
        7753                 :            :     .tp_basicsize = sizeof(struct encoding_map),
        7754                 :            :     /* methods */
        7755                 :            :     .tp_flags = Py_TPFLAGS_DEFAULT,
        7756                 :            :     .tp_methods = encoding_map_methods,
        7757                 :            : };
        7758                 :            :
        7759                 :            : PyObject*
        7760                 :          0 : PyUnicode_BuildEncodingMap(PyObject* string)
        7761                 :            : {
        7762                 :            :     PyObject *result;
        7763                 :            :     struct encoding_map *mresult;
        7764                 :            :     int i;
        7765                 :          0 :     int need_dict = 0;
        7766                 :            :     unsigned char level1[32];
        7767                 :            :     unsigned char level2[512];
        7768                 :            :     unsigned char *mlevel1, *mlevel2, *mlevel3;
        7769                 :          0 :     int count2 = 0, count3 = 0;
        7770                 :            :     int kind;
        7771                 :            :     const void *data;
        7772                 :            :     Py_ssize_t length;
        7773                 :            :     Py_UCS4 ch;
        7774                 :            :
        7775   [ #  #  #  # ]:          0 :     if (!PyUnicode_Check(string) || !PyUnicode_GET_LENGTH(string)) {
        7776                 :          0 :         PyErr_BadArgument();
        7777                 :          0 :         return NULL;
        7778                 :            :     }
        7779                 :          0 :     kind = PyUnicode_KIND(string);
        7780                 :          0 :     data = PyUnicode_DATA(string);
        7781                 :          0 :     length = PyUnicode_GET_LENGTH(string);
        7782                 :          0 :     length = Py_MIN(length, 256);
        7783                 :          0 :     memset(level1, 0xFF, sizeof level1);
        7784                 :          0 :     memset(level2, 0xFF, sizeof level2);
        7785                 :            :
        7786                 :            :     /* If there isn't a one-to-one mapping of NULL to \0,
        7787                 :            :        or if there are non-BMP characters, we need to use
        7788                 :            :        a mapping dictionary. */
        7789         [ #  # ]:          0 :     if (PyUnicode_READ(kind, data, 0) != 0)
        7790                 :          0 :         need_dict = 1;
        7791         [ #  # ]:          0 :     for (i = 1; i < length; i++) {
        7792                 :            :         int l1, l2;
        7793                 :          0 :         ch = PyUnicode_READ(kind, data, i);
        7794   [ #  #  #  # ]:          0 :         if (ch == 0 || ch > 0xFFFF) {
        7795                 :          0 :             need_dict = 1;
        7796                 :          0 :             break;
        7797                 :            :         }
        7798         [ #  # ]:          0 :         if (ch == 0xFFFE)
        7799                 :            :             /* unmapped character */
        7800                 :          0 :             continue;
        7801                 :          0 :         l1 = ch >> 11;
        7802                 :          0 :         l2 = ch >> 7;
        7803         [ #  # ]:          0 :         if (level1[l1] == 0xFF)
        7804                 :          0 :             level1[l1] = count2++;
        7805         [ #  # ]:          0 :         if (level2[l2] == 0xFF)
        7806                 :          0 :             level2[l2] = count3++;
        7807                 :            :     }
        7808                 :            :
        7809   [ #  #  #  # ]:          0 :     if (count2 >= 0xFF || count3 >= 0xFF)
        7810                 :          0 :         need_dict = 1;
        7811                 :            :
        7812         [ #  # ]:          0 :     if (need_dict) {
        7813                 :          0 :         PyObject *result = PyDict_New();
        7814                 :            :         PyObject *key, *value;
        7815         [ #  # ]:          0 :         if (!result)
        7816                 :          0 :             return NULL;
        7817         [ #  # ]:          0 :         for (i = 0; i < length; i++) {
        7818                 :          0 :             key = PyLong_FromLong(PyUnicode_READ(kind, data, i));
        7819                 :          0 :             value = PyLong_FromLong(i);
        7820   [ #  #  #  # ]:          0 :             if (!key || !value)
        7821                 :          0 :                 goto failed1;
        7822         [ #  # ]:          0 :             if (PyDict_SetItem(result, key, value) == -1)
        7823                 :          0 :                 goto failed1;
        7824                 :          0 :             Py_DECREF(key);
        7825                 :          0 :             Py_DECREF(value);
        7826                 :            :         }
        7827                 :          0 :         return result;
        7828                 :          0 :       failed1:
        7829                 :          0 :         Py_XDECREF(key);
        7830                 :          0 :         Py_XDECREF(value);
        7831                 :          0 :         Py_DECREF(result);
        7832                 :          0 :         return NULL;
        7833                 :            :     }
        7834                 :            :
        7835                 :            :     /* Create a three-level trie */
        7836                 :          0 :     result = PyObject_Malloc(sizeof(struct encoding_map) +
        7837                 :          0 :                              16*count2 + 128*count3 - 1);
        7838         [ #  # ]:          0 :     if (!result) {
        7839                 :          0 :         return PyErr_NoMemory();
        7840                 :            :     }
        7841                 :            :
        7842                 :          0 :     _PyObject_Init(result, &EncodingMapType);
        7843                 :          0 :     mresult = (struct encoding_map*)result;
        7844                 :          0 :     mresult->count2 = count2;
        7845                 :          0 :     mresult->count3 = count3;
        7846                 :          0 :     mlevel1 = mresult->level1;
        7847                 :          0 :     mlevel2 = mresult->level23;
        7848                 :          0 :     mlevel3 = mresult->level23 + 16*count2;
        7849                 :          0 :     memcpy(mlevel1, level1, 32);
        7850                 :          0 :     memset(mlevel2, 0xFF, 16*count2);
        7851                 :          0 :     memset(mlevel3, 0, 128*count3);
        7852                 :          0 :     count3 = 0;
        7853         [ #  # ]:          0 :     for (i = 1; i < length; i++) {
        7854                 :            :         int o1, o2, o3, i2, i3;
        7855                 :          0 :         Py_UCS4 ch = PyUnicode_READ(kind, data, i);
        7856         [ #  # ]:          0 :         if (ch == 0xFFFE)
        7857                 :            :             /* unmapped character */
        7858                 :          0 :             continue;
        7859                 :          0 :         o1 = ch>>11;
        7860                 :          0 :         o2 = (ch>>7) & 0xF;
        7861                 :          0 :         i2 = 16*mlevel1[o1] + o2;
        7862         [ #  # ]:          0 :         if (mlevel2[i2] == 0xFF)
        7863                 :          0 :             mlevel2[i2] = count3++;
        7864                 :          0 :         o3 = ch & 0x7F;
        7865                 :          0 :         i3 = 128*mlevel2[i2] + o3;
        7866                 :          0 :         mlevel3[i3] = i;
        7867                 :            :     }
        7868                 :          0 :     return result;
        7869                 :            : }
        7870                 :            :
        7871                 :            : static int
        7872                 :          0 : encoding_map_lookup(Py_UCS4 c, PyObject *mapping)
        7873                 :            : {
        7874                 :          0 :     struct encoding_map *map = (struct encoding_map*)mapping;
        7875                 :          0 :     int l1 = c>>11;
        7876                 :          0 :     int l2 = (c>>7) & 0xF;
        7877                 :          0 :     int l3 = c & 0x7F;
        7878                 :            :     int i;
        7879                 :            :
        7880         [ #  # ]:          0 :     if (c > 0xFFFF)
        7881                 :          0 :         return -1;
        7882         [ #  # ]:          0 :     if (c == 0)
        7883                 :          0 :         return 0;
        7884                 :            :     /* level 1*/
        7885                 :          0 :     i = map->level1[l1];
        7886         [ #  # ]:          0 :     if (i == 0xFF) {
        7887                 :          0 :         return -1;
        7888                 :            :     }
        7889                 :            :     /* level 2*/
        7890                 :          0 :     i = map->level23[16*i+l2];
        7891         [ #  # ]:          0 :     if (i == 0xFF) {
        7892                 :          0 :         return -1;
        7893                 :            :     }
        7894                 :            :     /* level 3 */
        7895                 :          0 :     i = map->level23[16*map->count2 + 128*i + l3];
        7896         [ #  # ]:          0 :     if (i == 0) {
        7897                 :          0 :         return -1;
        7898                 :            :     }
        7899                 :          0 :     return i;
        7900                 :            : }
        7901                 :            :
        7902                 :            : /* Lookup the character ch in the mapping. If the character
        7903                 :            :    can't be found, Py_None is returned (or NULL, if another
        7904                 :            :    error occurred). */
        7905                 :            : static PyObject *
        7906                 :          0 : charmapencode_lookup(Py_UCS4 c, PyObject *mapping)
        7907                 :            : {
        7908                 :          0 :     PyObject *w = PyLong_FromLong((long)c);
        7909                 :            :     PyObject *x;
        7910                 :            :
        7911         [ #  # ]:          0 :     if (w == NULL)
        7912                 :          0 :         return NULL;
        7913                 :          0 :     x = PyObject_GetItem(mapping, w);
        7914                 :          0 :     Py_DECREF(w);
        7915         [ #  # ]:          0 :     if (x == NULL) {
        7916         [ #  # ]:          0 :         if (PyErr_ExceptionMatches(PyExc_LookupError)) {
        7917                 :            :             /* No mapping found means: mapping is undefined. */
        7918                 :          0 :             PyErr_Clear();
        7919                 :          0 :             Py_RETURN_NONE;
        7920                 :            :         } else
        7921                 :          0 :             return NULL;
        7922                 :            :     }
        7923         [ #  # ]:          0 :     else if (x == Py_None)
        7924                 :          0 :         return x;
        7925         [ #  # ]:          0 :     else if (PyLong_Check(x)) {
        7926                 :          0 :         long value = PyLong_AS_LONG(x);
        7927   [ #  #  #  # ]:          0 :         if (value < 0 || value > 255) {
        7928                 :          0 :             PyErr_SetString(PyExc_TypeError,
        7929                 :            :                             "character mapping must be in range(256)");
        7930                 :          0 :             Py_DECREF(x);
        7931                 :          0 :             return NULL;
        7932                 :            :         }
        7933                 :          0 :         return x;
        7934                 :            :     }
        7935         [ #  # ]:          0 :     else if (PyBytes_Check(x))
        7936                 :          0 :         return x;
        7937                 :            :     else {
        7938                 :            :         /* wrong return value */
        7939                 :          0 :         PyErr_Format(PyExc_TypeError,
        7940                 :            :                      "character mapping must return integer, bytes or None, not %.400s",
        7941                 :          0 :                      Py_TYPE(x)->tp_name);
        7942                 :          0 :         Py_DECREF(x);
        7943                 :          0 :         return NULL;
        7944                 :            :     }
        7945                 :            : }
        7946                 :            :
        7947                 :            : static int
        7948                 :          0 : charmapencode_resize(PyObject **outobj, Py_ssize_t *outpos, Py_ssize_t requiredsize)
        7949                 :            : {
        7950                 :          0 :     Py_ssize_t outsize = PyBytes_GET_SIZE(*outobj);
        7951                 :            :     /* exponentially overallocate to minimize reallocations */
        7952         [ #  # ]:          0 :     if (requiredsize < 2*outsize)
        7953                 :          0 :         requiredsize = 2*outsize;
        7954         [ #  # ]:          0 :     if (_PyBytes_Resize(outobj, requiredsize))
        7955                 :          0 :         return -1;
        7956                 :          0 :     return 0;
        7957                 :            : }
        7958                 :            :
        7959                 :            : typedef enum charmapencode_result {
        7960                 :            :     enc_SUCCESS, enc_FAILED, enc_EXCEPTION
        7961                 :            : } charmapencode_result;
        7962                 :            : /* lookup the character, put the result in the output string and adjust
        7963                 :            :    various state variables. Resize the output bytes object if not enough
        7964                 :            :    space is available. Return a new reference to the object that
        7965                 :            :    was put in the output buffer, or Py_None, if the mapping was undefined
        7966                 :            :    (in which case no character was written) or NULL, if a
        7967                 :            :    reallocation error occurred. The caller must decref the result */
        7968                 :            : static charmapencode_result
        7969                 :          0 : charmapencode_output(Py_UCS4 c, PyObject *mapping,
        7970                 :            :                      PyObject **outobj, Py_ssize_t *outpos)
        7971                 :            : {
        7972                 :            :     PyObject *rep;
        7973                 :            :     char *outstart;
        7974                 :          0 :     Py_ssize_t outsize = PyBytes_GET_SIZE(*outobj);
        7975                 :            :
        7976         [ #  # ]:          0 :     if (Py_IS_TYPE(mapping, &EncodingMapType)) {
        7977                 :          0 :         int res = encoding_map_lookup(c, mapping);
        7978                 :          0 :         Py_ssize_t requiredsize = *outpos+1;
        7979         [ #  # ]:          0 :         if (res == -1)
        7980                 :          0 :             return enc_FAILED;
        7981         [ #  # ]:          0 :         if (outsize<requiredsize)
        7982         [ #  # ]:          0 :             if (charmapencode_resize(outobj, outpos, requiredsize))
        7983                 :          0 :                 return enc_EXCEPTION;
        7984                 :          0 :         outstart = PyBytes_AS_STRING(*outobj);
        7985                 :          0 :         outstart[(*outpos)++] = (char)res;
        7986                 :          0 :         return enc_SUCCESS;
        7987                 :            :     }
        7988                 :            :
        7989                 :          0 :     rep = charmapencode_lookup(c, mapping);
        7990         [ #  # ]:          0 :     if (rep==NULL)
        7991                 :          0 :         return enc_EXCEPTION;
        7992         [ #  # ]:          0 :     else if (rep==Py_None) {
        7993                 :          0 :         Py_DECREF(rep);
        7994                 :          0 :         return enc_FAILED;
        7995                 :            :     } else {
        7996         [ #  # ]:          0 :         if (PyLong_Check(rep)) {
        7997                 :          0 :             Py_ssize_t requiredsize = *outpos+1;
        7998         [ #  # ]:          0 :             if (outsize<requiredsize)
        7999         [ #  # ]:          0 :                 if (charmapencode_resize(outobj, outpos, requiredsize)) {
        8000                 :          0 :                     Py_DECREF(rep);
        8001                 :          0 :                     return enc_EXCEPTION;
        8002                 :            :                 }
        8003                 :          0 :             outstart = PyBytes_AS_STRING(*outobj);
        8004                 :          0 :             outstart[(*outpos)++] = (char)PyLong_AS_LONG(rep);
        8005                 :            :         }
        8006                 :            :         else {
        8007                 :          0 :             const char *repchars = PyBytes_AS_STRING(rep);
        8008                 :          0 :             Py_ssize_t repsize = PyBytes_GET_SIZE(rep);
        8009                 :          0 :             Py_ssize_t requiredsize = *outpos+repsize;
        8010         [ #  # ]:          0 :             if (outsize<requiredsize)
        8011         [ #  # ]:          0 :                 if (charmapencode_resize(outobj, outpos, requiredsize)) {
        8012                 :          0 :                     Py_DECREF(rep);
        8013                 :          0 :                     return enc_EXCEPTION;
        8014                 :            :                 }
        8015                 :          0 :             outstart = PyBytes_AS_STRING(*outobj);
        8016                 :          0 :             memcpy(outstart + *outpos, repchars, repsize);
        8017                 :          0 :             *outpos += repsize;
        8018                 :            :         }
        8019                 :            :     }
        8020                 :          0 :     Py_DECREF(rep);
        8021                 :          0 :     return enc_SUCCESS;
        8022                 :            : }
        8023                 :            :
        8024                 :            : /* handle an error in PyUnicode_EncodeCharmap
        8025                 :            :    Return 0 on success, -1 on error */
        8026                 :            : static int
        8027                 :          0 : charmap_encoding_error(
        8028                 :            :     PyObject *unicode, Py_ssize_t *inpos, PyObject *mapping,
        8029                 :            :     PyObject **exceptionObject,
        8030                 :            :     _Py_error_handler *error_handler, PyObject **error_handler_obj, const char *errors,
        8031                 :            :     PyObject **res, Py_ssize_t *respos)
        8032                 :            : {
        8033                 :          0 :     PyObject *repunicode = NULL; /* initialize to prevent gcc warning */
        8034                 :            :     Py_ssize_t size, repsize;
        8035                 :            :     Py_ssize_t newpos;
        8036                 :            :     int kind;
        8037                 :            :     const void *data;
        8038                 :            :     Py_ssize_t index;
        8039                 :            :     /* startpos for collecting unencodable chars */
        8040                 :          0 :     Py_ssize_t collstartpos = *inpos;
        8041                 :          0 :     Py_ssize_t collendpos = *inpos+1;
        8042                 :            :     Py_ssize_t collpos;
        8043                 :          0 :     const char *encoding = "charmap";
        8044                 :          0 :     const char *reason = "character maps to <undefined>";
        8045                 :            :     charmapencode_result x;
        8046                 :            :     Py_UCS4 ch;
        8047                 :            :     int val;
        8048                 :            :
        8049                 :          0 :     size = PyUnicode_GET_LENGTH(unicode);
        8050                 :            :     /* find all unencodable characters */
        8051         [ #  # ]:          0 :     while (collendpos < size) {
        8052                 :            :         PyObject *rep;
        8053         [ #  # ]:          0 :         if (Py_IS_TYPE(mapping, &EncodingMapType)) {
        8054                 :          0 :             ch = PyUnicode_READ_CHAR(unicode, collendpos);
        8055                 :          0 :             val = encoding_map_lookup(ch, mapping);
        8056         [ #  # ]:          0 :             if (val != -1)
        8057                 :          0 :                 break;
        8058                 :          0 :             ++collendpos;
        8059                 :          0 :             continue;
        8060                 :            :         }
        8061                 :            :
        8062                 :          0 :         ch = PyUnicode_READ_CHAR(unicode, collendpos);
        8063                 :          0 :         rep = charmapencode_lookup(ch, mapping);
        8064         [ #  # ]:          0 :         if (rep==NULL)
        8065                 :          0 :             return -1;
        8066         [ #  # ]:          0 :         else if (rep!=Py_None) {
        8067                 :          0 :             Py_DECREF(rep);
        8068                 :          0 :             break;
        8069                 :            :         }
        8070                 :          0 :         Py_DECREF(rep);
        8071                 :          0 :         ++collendpos;
        8072                 :            :     }
        8073                 :            :     /* cache callback name lookup
        8074                 :            :      * (if not done yet, i.e. it's the first error) */
        8075         [ #  # ]:          0 :     if (*error_handler == _Py_ERROR_UNKNOWN)
        8076                 :          0 :         *error_handler = _Py_GetErrorHandler(errors);
        8077                 :            :
        8078   [ #  #  #  #  :          0 :     switch (*error_handler) {
                          # ]
        8079                 :          0 :     case _Py_ERROR_STRICT:
        8080                 :          0 :         raise_encode_exception(exceptionObject, encoding, unicode, collstartpos, collendpos, reason);
        8081                 :          0 :         return -1;
        8082                 :            :
        8083                 :          0 :     case _Py_ERROR_REPLACE:
        8084         [ #  # ]:          0 :         for (collpos = collstartpos; collpos<collendpos; ++collpos) {
        8085                 :          0 :             x = charmapencode_output('?', mapping, res, respos);
        8086         [ #  # ]:          0 :             if (x==enc_EXCEPTION) {
        8087                 :          0 :                 return -1;
        8088                 :            :             }
        8089         [ #  # ]:          0 :             else if (x==enc_FAILED) {
        8090                 :          0 :                 raise_encode_exception(exceptionObject, encoding, unicode, collstartpos, collendpos, reason);
        8091                 :          0 :                 return -1;
        8092                 :            :             }
        8093                 :            :         }
        8094                 :            :         /* fall through */
        8095                 :            :     case _Py_ERROR_IGNORE:
        8096                 :          0 :         *inpos = collendpos;
        8097                 :          0 :         break;
        8098                 :            :
        8099                 :          0 :     case _Py_ERROR_XMLCHARREFREPLACE:
        8100                 :            :         /* generate replacement (temporarily (mis)uses p) */
        8101         [ #  # ]:          0 :         for (collpos = collstartpos; collpos < collendpos; ++collpos) {
        8102                 :            :             char buffer[2+29+1+1];
        8103                 :            :             char *cp;
        8104                 :          0 :             sprintf(buffer, "&#%d;", (int)PyUnicode_READ_CHAR(unicode, collpos));
        8105         [ #  # ]:          0 :             for (cp = buffer; *cp; ++cp) {
        8106                 :          0 :                 x = charmapencode_output(*cp, mapping, res, respos);
        8107         [ #  # ]:          0 :                 if (x==enc_EXCEPTION)
        8108                 :          0 :                     return -1;
        8109         [ #  # ]:          0 :                 else if (x==enc_FAILED) {
        8110                 :          0 :                     raise_encode_exception(exceptionObject, encoding, unicode, collstartpos, collendpos, reason);
        8111                 :          0 :                     return -1;
        8112                 :            :                 }
        8113                 :            :             }
        8114                 :            :         }
        8115                 :          0 :         *inpos = collendpos;
        8116                 :          0 :         break;
        8117                 :            :
        8118                 :          0 :     default:
        8119                 :          0 :         repunicode = unicode_encode_call_errorhandler(errors, error_handler_obj,
        8120                 :            :                                                       encoding, reason, unicode, exceptionObject,
        8121                 :            :                                                       collstartpos, collendpos, &newpos);
        8122         [ #  # ]:          0 :         if (repunicode == NULL)
        8123                 :          0 :             return -1;
        8124         [ #  # ]:          0 :         if (PyBytes_Check(repunicode)) {
        8125                 :            :             /* Directly copy bytes result to output. */
        8126                 :          0 :             Py_ssize_t outsize = PyBytes_Size(*res);
        8127                 :            :             Py_ssize_t requiredsize;
        8128                 :          0 :             repsize = PyBytes_Size(repunicode);
        8129                 :          0 :             requiredsize = *respos + repsize;
        8130         [ #  # ]:          0 :             if (requiredsize > outsize)
        8131                 :            :                 /* Make room for all additional bytes. */
        8132         [ #  # ]:          0 :                 if (charmapencode_resize(res, respos, requiredsize)) {
        8133                 :          0 :                     Py_DECREF(repunicode);
        8134                 :          0 :                     return -1;
        8135                 :            :                 }
        8136                 :          0 :             memcpy(PyBytes_AsString(*res) + *respos,
        8137                 :          0 :                    PyBytes_AsString(repunicode),  repsize);
        8138                 :          0 :             *respos += repsize;
        8139                 :          0 :             *inpos = newpos;
        8140                 :          0 :             Py_DECREF(repunicode);
        8141                 :          0 :             break;
        8142                 :            :         }
        8143                 :            :         /* generate replacement  */
        8144                 :          0 :         repsize = PyUnicode_GET_LENGTH(repunicode);
        8145                 :          0 :         data = PyUnicode_DATA(repunicode);
        8146                 :          0 :         kind = PyUnicode_KIND(repunicode);
        8147         [ #  # ]:          0 :         for (index = 0; index < repsize; index++) {
        8148                 :          0 :             Py_UCS4 repch = PyUnicode_READ(kind, data, index);
        8149                 :          0 :             x = charmapencode_output(repch, mapping, res, respos);
        8150         [ #  # ]:          0 :             if (x==enc_EXCEPTION) {
        8151                 :          0 :                 Py_DECREF(repunicode);
        8152                 :          0 :                 return -1;
        8153                 :            :             }
        8154         [ #  # ]:          0 :             else if (x==enc_FAILED) {
        8155                 :          0 :                 Py_DECREF(repunicode);
        8156                 :          0 :                 raise_encode_exception(exceptionObject, encoding, unicode, collstartpos, collendpos, reason);
        8157                 :          0 :                 return -1;
        8158                 :            :             }
        8159                 :            :         }
        8160                 :          0 :         *inpos = newpos;
        8161                 :          0 :         Py_DECREF(repunicode);
        8162                 :            :     }
        8163                 :          0 :     return 0;
        8164                 :            : }
        8165                 :            :
        8166                 :            : PyObject *
        8167                 :          0 : _PyUnicode_EncodeCharmap(PyObject *unicode,
        8168                 :            :                          PyObject *mapping,
        8169                 :            :                          const char *errors)
        8170                 :            : {
        8171                 :            :     /* output object */
        8172                 :          0 :     PyObject *res = NULL;
        8173                 :            :     /* current input position */
        8174                 :          0 :     Py_ssize_t inpos = 0;
        8175                 :            :     Py_ssize_t size;
        8176                 :            :     /* current output position */
        8177                 :          0 :     Py_ssize_t respos = 0;
        8178                 :          0 :     PyObject *error_handler_obj = NULL;
        8179                 :          0 :     PyObject *exc = NULL;
        8180                 :          0 :     _Py_error_handler error_handler = _Py_ERROR_UNKNOWN;
        8181                 :            :     const void *data;
        8182                 :            :     int kind;
        8183                 :            :
        8184                 :          0 :     size = PyUnicode_GET_LENGTH(unicode);
        8185                 :          0 :     data = PyUnicode_DATA(unicode);
        8186                 :          0 :     kind = PyUnicode_KIND(unicode);
        8187                 :            :
        8188                 :            :     /* Default to Latin-1 */
        8189         [ #  # ]:          0 :     if (mapping == NULL)
        8190                 :          0 :         return unicode_encode_ucs1(unicode, errors, 256);
        8191                 :            :
        8192                 :            :     /* allocate enough for a simple encoding without
        8193                 :            :        replacements, if we need more, we'll resize */
        8194                 :          0 :     res = PyBytes_FromStringAndSize(NULL, size);
        8195         [ #  # ]:          0 :     if (res == NULL)
        8196                 :          0 :         goto onError;
        8197         [ #  # ]:          0 :     if (size == 0)
        8198                 :          0 :         return res;
        8199                 :            :
        8200         [ #  # ]:          0 :     while (inpos<size) {
        8201                 :          0 :         Py_UCS4 ch = PyUnicode_READ(kind, data, inpos);
        8202                 :            :         /* try to encode it */
        8203                 :          0 :         charmapencode_result x = charmapencode_output(ch, mapping, &res, &respos);
        8204         [ #  # ]:          0 :         if (x==enc_EXCEPTION) /* error */
        8205                 :          0 :             goto onError;
        8206         [ #  # ]:          0 :         if (x==enc_FAILED) { /* unencodable character */
        8207         [ #  # ]:          0 :             if (charmap_encoding_error(unicode, &inpos, mapping,
        8208                 :            :                                        &exc,
        8209                 :            :                                        &error_handler, &error_handler_obj, errors,
        8210                 :            :                                        &res, &respos)) {
        8211                 :          0 :                 goto onError;
        8212                 :            :             }
        8213                 :            :         }
        8214                 :            :         else
        8215                 :            :             /* done with this character => adjust input position */
        8216                 :          0 :             ++inpos;
        8217                 :            :     }
        8218                 :            :
        8219                 :            :     /* Resize if we allocated to much */
        8220         [ #  # ]:          0 :     if (respos<PyBytes_GET_SIZE(res))
        8221         [ #  # ]:          0 :         if (_PyBytes_Resize(&res, respos) < 0)
        8222                 :          0 :             goto onError;
        8223                 :            :
        8224                 :          0 :     Py_XDECREF(exc);
        8225                 :          0 :     Py_XDECREF(error_handler_obj);
        8226                 :          0 :     return res;
        8227                 :            :
        8228                 :          0 :   onError:
        8229                 :          0 :     Py_XDECREF(res);
        8230                 :          0 :     Py_XDECREF(exc);
        8231                 :          0 :     Py_XDECREF(error_handler_obj);
        8232                 :          0 :     return NULL;
        8233                 :            : }
        8234                 :            :
        8235                 :            : PyObject *
        8236                 :          0 : PyUnicode_AsCharmapString(PyObject *unicode,
        8237                 :            :                           PyObject *mapping)
        8238                 :            : {
        8239   [ #  #  #  # ]:          0 :     if (!PyUnicode_Check(unicode) || mapping == NULL) {
        8240                 :          0 :         PyErr_BadArgument();
        8241                 :          0 :         return NULL;
        8242                 :            :     }
        8243                 :          0 :     return _PyUnicode_EncodeCharmap(unicode, mapping, NULL);
        8244                 :            : }
        8245                 :            :
        8246                 :            : /* create or adjust a UnicodeTranslateError */
        8247                 :            : static void
        8248                 :          0 : make_translate_exception(PyObject **exceptionObject,
        8249                 :            :                          PyObject *unicode,
        8250                 :            :                          Py_ssize_t startpos, Py_ssize_t endpos,
        8251                 :            :                          const char *reason)
        8252                 :            : {
        8253         [ #  # ]:          0 :     if (*exceptionObject == NULL) {
        8254                 :          0 :         *exceptionObject = _PyUnicodeTranslateError_Create(
        8255                 :            :             unicode, startpos, endpos, reason);
        8256                 :            :     }
        8257                 :            :     else {
        8258         [ #  # ]:          0 :         if (PyUnicodeTranslateError_SetStart(*exceptionObject, startpos))
        8259                 :          0 :             goto onError;
        8260         [ #  # ]:          0 :         if (PyUnicodeTranslateError_SetEnd(*exceptionObject, endpos))
        8261                 :          0 :             goto onError;
        8262         [ #  # ]:          0 :         if (PyUnicodeTranslateError_SetReason(*exceptionObject, reason))
        8263                 :          0 :             goto onError;
        8264                 :          0 :         return;
        8265                 :          0 :       onError:
        8266         [ #  # ]:          0 :         Py_CLEAR(*exceptionObject);
        8267                 :            :     }
        8268                 :            : }
        8269                 :            :
        8270                 :            : /* error handling callback helper:
        8271                 :            :    build arguments, call the callback and check the arguments,
        8272                 :            :    put the result into newpos and return the replacement string, which
        8273                 :            :    has to be freed by the caller */
        8274                 :            : static PyObject *
        8275                 :          0 : unicode_translate_call_errorhandler(const char *errors,
        8276                 :            :                                     PyObject **errorHandler,
        8277                 :            :                                     const char *reason,
        8278                 :            :                                     PyObject *unicode, PyObject **exceptionObject,
        8279                 :            :                                     Py_ssize_t startpos, Py_ssize_t endpos,
        8280                 :            :                                     Py_ssize_t *newpos)
        8281                 :            : {
        8282                 :            :     static const char *argparse = "Un;translating error handler must return (str, int) tuple";
        8283                 :            :
        8284                 :            :     Py_ssize_t i_newpos;
        8285                 :            :     PyObject *restuple;
        8286                 :            :     PyObject *resunicode;
        8287                 :            :
        8288         [ #  # ]:          0 :     if (*errorHandler == NULL) {
        8289                 :          0 :         *errorHandler = PyCodec_LookupError(errors);
        8290         [ #  # ]:          0 :         if (*errorHandler == NULL)
        8291                 :          0 :             return NULL;
        8292                 :            :     }
        8293                 :            :
        8294                 :          0 :     make_translate_exception(exceptionObject,
        8295                 :            :                              unicode, startpos, endpos, reason);
        8296         [ #  # ]:          0 :     if (*exceptionObject == NULL)
        8297                 :          0 :         return NULL;
        8298                 :            :
        8299                 :          0 :     restuple = PyObject_CallOneArg(*errorHandler, *exceptionObject);
        8300         [ #  # ]:          0 :     if (restuple == NULL)
        8301                 :          0 :         return NULL;
        8302         [ #  # ]:          0 :     if (!PyTuple_Check(restuple)) {
        8303                 :          0 :         PyErr_SetString(PyExc_TypeError, &argparse[3]);
        8304                 :          0 :         Py_DECREF(restuple);
        8305                 :          0 :         return NULL;
        8306                 :            :     }
        8307         [ #  # ]:          0 :     if (!PyArg_ParseTuple(restuple, argparse,
        8308                 :            :                           &resunicode, &i_newpos)) {
        8309                 :          0 :         Py_DECREF(restuple);
        8310                 :          0 :         return NULL;
        8311                 :            :     }
        8312         [ #  # ]:          0 :     if (i_newpos<0)
        8313                 :          0 :         *newpos = PyUnicode_GET_LENGTH(unicode)+i_newpos;
        8314                 :            :     else
        8315                 :          0 :         *newpos = i_newpos;
        8316   [ #  #  #  # ]:          0 :     if (*newpos<0 || *newpos>PyUnicode_GET_LENGTH(unicode)) {
        8317                 :          0 :         PyErr_Format(PyExc_IndexError, "position %zd from error handler out of bounds", *newpos);
        8318                 :          0 :         Py_DECREF(restuple);
        8319                 :          0 :         return NULL;
        8320                 :            :     }
        8321                 :          0 :     Py_INCREF(resunicode);
        8322                 :          0 :     Py_DECREF(restuple);
        8323                 :          0 :     return resunicode;
        8324                 :            : }
        8325                 :            :
        8326                 :            : /* Lookup the character ch in the mapping and put the result in result,
        8327                 :            :    which must be decrefed by the caller.
        8328                 :            :    Return 0 on success, -1 on error */
        8329                 :            : static int
        8330                 :        297 : charmaptranslate_lookup(Py_UCS4 c, PyObject *mapping, PyObject **result)
        8331                 :            : {
        8332                 :        297 :     PyObject *w = PyLong_FromLong((long)c);
        8333                 :            :     PyObject *x;
        8334                 :            :
        8335         [ -  + ]:        297 :     if (w == NULL)
        8336                 :          0 :         return -1;
        8337                 :        297 :     x = PyObject_GetItem(mapping, w);
        8338                 :        297 :     Py_DECREF(w);
        8339         [ +  + ]:        297 :     if (x == NULL) {
        8340         [ +  - ]:        123 :         if (PyErr_ExceptionMatches(PyExc_LookupError)) {
        8341                 :            :             /* No mapping found means: use 1:1 mapping. */
        8342                 :        123 :             PyErr_Clear();
        8343                 :        123 :             *result = NULL;
        8344                 :        123 :             return 0;
        8345                 :            :         } else
        8346                 :          0 :             return -1;
        8347                 :            :     }
        8348         [ -  + ]:        174 :     else if (x == Py_None) {
        8349                 :          0 :         *result = x;
        8350                 :          0 :         return 0;
        8351                 :            :     }
        8352         [ -  + ]:        174 :     else if (PyLong_Check(x)) {
        8353                 :          0 :         long value = PyLong_AS_LONG(x);
        8354   [ #  #  #  # ]:          0 :         if (value < 0 || value > MAX_UNICODE) {
        8355                 :          0 :             PyErr_Format(PyExc_ValueError,
        8356                 :            :                          "character mapping must be in range(0x%x)",
        8357                 :            :                          MAX_UNICODE+1);
        8358                 :          0 :             Py_DECREF(x);
        8359                 :          0 :             return -1;
        8360                 :            :         }
        8361                 :          0 :         *result = x;
        8362                 :          0 :         return 0;
        8363                 :            :     }
        8364         [ +  - ]:        174 :     else if (PyUnicode_Check(x)) {
        8365                 :        174 :         *result = x;
        8366                 :        174 :         return 0;
        8367                 :            :     }
        8368                 :            :     else {
        8369                 :            :         /* wrong return value */
        8370                 :          0 :         PyErr_SetString(PyExc_TypeError,
        8371                 :            :                         "character mapping must return integer, None or str");
        8372                 :          0 :         Py_DECREF(x);
        8373                 :          0 :         return -1;
        8374                 :            :     }
        8375                 :            : }
        8376                 :            :
        8377                 :            : /* lookup the character, write the result into the writer.
        8378                 :            :    Return 1 if the result was written into the writer, return 0 if the mapping
        8379                 :            :    was undefined, raise an exception return -1 on error. */
        8380                 :            : static int
        8381                 :        122 : charmaptranslate_output(Py_UCS4 ch, PyObject *mapping,
        8382                 :            :                         _PyUnicodeWriter *writer)
        8383                 :            : {
        8384                 :            :     PyObject *item;
        8385                 :            :
        8386         [ -  + ]:        122 :     if (charmaptranslate_lookup(ch, mapping, &item))
        8387                 :          0 :         return -1;
        8388                 :            :
        8389         [ +  + ]:        122 :     if (item == NULL) {
        8390                 :            :         /* not found => default to 1:1 mapping */
        8391         [ -  + ]:         24 :         if (_PyUnicodeWriter_WriteCharInline(writer, ch) < 0) {
        8392                 :          0 :             return -1;
        8393                 :            :         }
        8394                 :         24 :         return 1;
        8395                 :            :     }
        8396                 :            :
        8397         [ -  + ]:         98 :     if (item == Py_None) {
        8398                 :          0 :         Py_DECREF(item);
        8399                 :          0 :         return 0;
        8400                 :            :     }
        8401                 :            :
        8402         [ -  + ]:         98 :     if (PyLong_Check(item)) {
        8403                 :          0 :         long ch = (Py_UCS4)PyLong_AS_LONG(item);
        8404                 :            :         /* PyLong_AS_LONG() cannot fail, charmaptranslate_lookup() already
        8405                 :            :            used it */
        8406         [ #  # ]:          0 :         if (_PyUnicodeWriter_WriteCharInline(writer, ch) < 0) {
        8407                 :          0 :             Py_DECREF(item);
        8408                 :          0 :             return -1;
        8409                 :            :         }
        8410                 :          0 :         Py_DECREF(item);
        8411                 :          0 :         return 1;
        8412                 :            :     }
        8413                 :            :
        8414         [ -  + ]:         98 :     if (!PyUnicode_Check(item)) {
        8415                 :          0 :         Py_DECREF(item);
        8416                 :          0 :         return -1;
        8417                 :            :     }
        8418                 :            :
        8419         [ -  + ]:         98 :     if (_PyUnicodeWriter_WriteStr(writer, item) < 0) {
        8420                 :          0 :         Py_DECREF(item);
        8421                 :          0 :         return -1;
        8422                 :            :     }
        8423                 :            :
        8424                 :         98 :     Py_DECREF(item);
        8425                 :         98 :     return 1;
        8426                 :            : }
        8427                 :            :
        8428                 :            : static int
        8429                 :        175 : unicode_fast_translate_lookup(PyObject *mapping, Py_UCS1 ch,
        8430                 :            :                               Py_UCS1 *translate)
        8431                 :            : {
        8432                 :        175 :     PyObject *item = NULL;
        8433                 :        175 :     int ret = 0;
        8434                 :            :
        8435         [ -  + ]:        175 :     if (charmaptranslate_lookup(ch, mapping, &item)) {
        8436                 :          0 :         return -1;
        8437                 :            :     }
        8438                 :            :
        8439         [ -  + ]:        175 :     if (item == Py_None) {
        8440                 :            :         /* deletion */
        8441                 :          0 :         translate[ch] = 0xfe;
        8442                 :            :     }
        8443         [ +  + ]:        175 :     else if (item == NULL) {
        8444                 :            :         /* not found => default to 1:1 mapping */
        8445                 :         99 :         translate[ch] = ch;
        8446                 :         99 :         return 1;
        8447                 :            :     }
        8448         [ -  + ]:         76 :     else if (PyLong_Check(item)) {
        8449                 :          0 :         long replace = PyLong_AS_LONG(item);
        8450                 :            :         /* PyLong_AS_LONG() cannot fail, charmaptranslate_lookup() already
        8451                 :            :            used it */
        8452         [ #  # ]:          0 :         if (127 < replace) {
        8453                 :            :             /* invalid character or character outside ASCII:
        8454                 :            :                skip the fast translate */
        8455                 :          0 :             goto exit;
        8456                 :            :         }
        8457                 :          0 :         translate[ch] = (Py_UCS1)replace;
        8458                 :            :     }
        8459         [ +  - ]:         76 :     else if (PyUnicode_Check(item)) {
        8460                 :            :         Py_UCS4 replace;
        8461                 :            :
        8462         [ +  - ]:         76 :         if (PyUnicode_GET_LENGTH(item) != 1)
        8463                 :         76 :             goto exit;
        8464                 :            :
        8465                 :          0 :         replace = PyUnicode_READ_CHAR(item, 0);
        8466         [ #  # ]:          0 :         if (replace > 127)
        8467                 :          0 :             goto exit;
        8468                 :          0 :         translate[ch] = (Py_UCS1)replace;
        8469                 :            :     }
        8470                 :            :     else {
        8471                 :            :         /* not None, NULL, long or unicode */
        8472                 :          0 :         goto exit;
        8473                 :            :     }
        8474                 :          0 :     ret = 1;
        8475                 :            :
        8476                 :         76 :   exit:
        8477                 :         76 :     Py_DECREF(item);
        8478                 :         76 :     return ret;
        8479                 :            : }
        8480                 :            :
        8481                 :            : /* Fast path for ascii => ascii translation. Return 1 if the whole string
        8482                 :            :    was translated into writer, return 0 if the input string was partially
        8483                 :            :    translated into writer, raise an exception and return -1 on error. */
        8484                 :            : static int
        8485                 :        145 : unicode_fast_translate(PyObject *input, PyObject *mapping,
        8486                 :            :                        _PyUnicodeWriter *writer, int ignore,
        8487                 :            :                        Py_ssize_t *input_pos)
        8488                 :            : {
        8489                 :            :     Py_UCS1 ascii_table[128], ch, ch2;
        8490                 :            :     Py_ssize_t len;
        8491                 :            :     const Py_UCS1 *in, *end;
        8492                 :            :     Py_UCS1 *out;
        8493                 :        145 :     int res = 0;
        8494                 :            :
        8495                 :        145 :     len = PyUnicode_GET_LENGTH(input);
        8496                 :            :
        8497                 :        145 :     memset(ascii_table, 0xff, 128);
        8498                 :            :
        8499                 :        145 :     in = PyUnicode_1BYTE_DATA(input);
        8500                 :        145 :     end = in + len;
        8501                 :            :
        8502                 :            :     assert(PyUnicode_IS_ASCII(writer->buffer));
        8503                 :            :     assert(PyUnicode_GET_LENGTH(writer->buffer) == len);
        8504                 :        145 :     out = PyUnicode_1BYTE_DATA(writer->buffer);
        8505                 :            :
        8506         [ +  + ]:        265 :     for (; in < end; in++) {
        8507                 :        196 :         ch = *in;
        8508                 :        196 :         ch2 = ascii_table[ch];
        8509         [ +  + ]:        196 :         if (ch2 == 0xff) {
        8510                 :        175 :             int translate = unicode_fast_translate_lookup(mapping, ch,
        8511                 :            :                                                           ascii_table);
        8512         [ -  + ]:        175 :             if (translate < 0)
        8513                 :          0 :                 return -1;
        8514         [ +  + ]:        175 :             if (translate == 0)
        8515                 :         76 :                 goto exit;
        8516                 :         99 :             ch2 = ascii_table[ch];
        8517                 :            :         }
        8518         [ -  + ]:        120 :         if (ch2 == 0xfe) {
        8519         [ #  # ]:          0 :             if (ignore)
        8520                 :          0 :                 continue;
        8521                 :          0 :             goto exit;
        8522                 :            :         }
        8523                 :            :         assert(ch2 < 128);
        8524                 :        120 :         *out = ch2;
        8525                 :        120 :         out++;
        8526                 :            :     }
        8527                 :         69 :     res = 1;
        8528                 :            :
        8529                 :        145 : exit:
        8530                 :        145 :     writer->pos = out - PyUnicode_1BYTE_DATA(writer->buffer);
        8531                 :        145 :     *input_pos = in - PyUnicode_1BYTE_DATA(input);
        8532                 :        145 :     return res;
        8533                 :            : }
        8534                 :            :
        8535                 :            : static PyObject *
        8536                 :        145 : _PyUnicode_TranslateCharmap(PyObject *input,
        8537                 :            :                             PyObject *mapping,
        8538                 :            :                             const char *errors)
        8539                 :            : {
        8540                 :            :     /* input object */
        8541                 :            :     const void *data;
        8542                 :            :     Py_ssize_t size, i;
        8543                 :            :     int kind;
        8544                 :            :     /* output buffer */
        8545                 :            :     _PyUnicodeWriter writer;
        8546                 :            :     /* error handler */
        8547                 :        145 :     const char *reason = "character maps to <undefined>";
        8548                 :        145 :     PyObject *errorHandler = NULL;
        8549                 :        145 :     PyObject *exc = NULL;
        8550                 :            :     int ignore;
        8551                 :            :     int res;
        8552                 :            :
        8553         [ -  + ]:        145 :     if (mapping == NULL) {
        8554                 :          0 :         PyErr_BadArgument();
        8555                 :          0 :         return NULL;
        8556                 :            :     }
        8557                 :            :
        8558                 :        145 :     data = PyUnicode_DATA(input);
        8559                 :        145 :     kind = PyUnicode_KIND(input);
        8560                 :        145 :     size = PyUnicode_GET_LENGTH(input);
        8561                 :            :
        8562         [ -  + ]:        145 :     if (size == 0)
        8563                 :          0 :         return PyUnicode_FromObject(input);
        8564                 :            :
        8565                 :            :     /* allocate enough for a simple 1:1 translation without
        8566                 :            :        replacements, if we need more, we'll resize */
        8567                 :        145 :     _PyUnicodeWriter_Init(&writer);
        8568   [ -  +  -  -  :        145 :     if (_PyUnicodeWriter_Prepare(&writer, size, 127) == -1)
                 +  -  -  + ]
        8569                 :          0 :         goto onError;
        8570                 :            :
        8571   [ +  -  +  - ]:        145 :     ignore = (errors != NULL && strcmp(errors, "ignore") == 0);
        8572                 :            :
        8573         [ +  - ]:        145 :     if (PyUnicode_IS_ASCII(input)) {
        8574                 :        145 :         res = unicode_fast_translate(input, mapping, &writer, ignore, &i);
        8575         [ -  + ]:        145 :         if (res < 0) {
        8576                 :          0 :             _PyUnicodeWriter_Dealloc(&writer);
        8577                 :          0 :             return NULL;
        8578                 :            :         }
        8579         [ +  + ]:        145 :         if (res == 1)
        8580                 :         69 :             return _PyUnicodeWriter_Finish(&writer);
        8581                 :            :     }
        8582                 :            :     else {
        8583                 :          0 :         i = 0;
        8584                 :            :     }
        8585                 :            :
        8586         [ +  + ]:        198 :     while (i<size) {
        8587                 :            :         /* try to encode it */
        8588                 :            :         int translate;
        8589                 :        122 :         PyObject *repunicode = NULL; /* initialize to prevent gcc warning */
        8590                 :            :         Py_ssize_t newpos;
        8591                 :            :         /* startpos for collecting untranslatable chars */
        8592                 :            :         Py_ssize_t collstart;
        8593                 :            :         Py_ssize_t collend;
        8594                 :            :         Py_UCS4 ch;
        8595                 :            :
        8596                 :        122 :         ch = PyUnicode_READ(kind, data, i);
        8597                 :        122 :         translate = charmaptranslate_output(ch, mapping, &writer);
        8598         [ -  + ]:        122 :         if (translate < 0)
        8599                 :          0 :             goto onError;
        8600                 :            :
        8601         [ +  - ]:        122 :         if (translate != 0) {
        8602                 :            :             /* it worked => adjust input pointer */
        8603                 :        122 :             ++i;
        8604                 :        122 :             continue;
        8605                 :            :         }
        8606                 :            :
        8607                 :            :         /* untranslatable character */
        8608                 :          0 :         collstart = i;
        8609                 :          0 :         collend = i+1;
        8610                 :            :
        8611                 :            :         /* find all untranslatable characters */
        8612         [ #  # ]:          0 :         while (collend < size) {
        8613                 :            :             PyObject *x;
        8614                 :          0 :             ch = PyUnicode_READ(kind, data, collend);
        8615         [ #  # ]:          0 :             if (charmaptranslate_lookup(ch, mapping, &x))
        8616                 :          0 :                 goto onError;
        8617                 :          0 :             Py_XDECREF(x);
        8618         [ #  # ]:          0 :             if (x != Py_None)
        8619                 :          0 :                 break;
        8620                 :          0 :             ++collend;
        8621                 :            :         }
        8622                 :            :
        8623         [ #  # ]:          0 :         if (ignore) {
        8624                 :          0 :             i = collend;
        8625                 :            :         }
        8626                 :            :         else {
        8627                 :          0 :             repunicode = unicode_translate_call_errorhandler(errors, &errorHandler,
        8628                 :            :                                                              reason, input, &exc,
        8629                 :            :                                                              collstart, collend, &newpos);
        8630         [ #  # ]:          0 :             if (repunicode == NULL)
        8631                 :          0 :                 goto onError;
        8632         [ #  # ]:          0 :             if (_PyUnicodeWriter_WriteStr(&writer, repunicode) < 0) {
        8633                 :          0 :                 Py_DECREF(repunicode);
        8634                 :          0 :                 goto onError;
        8635                 :            :             }
        8636                 :          0 :             Py_DECREF(repunicode);
        8637                 :          0 :             i = newpos;
        8638                 :            :         }
        8639                 :            :     }
        8640                 :         76 :     Py_XDECREF(exc);
        8641                 :         76 :     Py_XDECREF(errorHandler);
        8642                 :         76 :     return _PyUnicodeWriter_Finish(&writer);
        8643                 :            :
        8644                 :          0 :   onError:
        8645                 :          0 :     _PyUnicodeWriter_Dealloc(&writer);
        8646                 :          0 :     Py_XDECREF(exc);
        8647                 :          0 :     Py_XDECREF(errorHandler);
        8648                 :          0 :     return NULL;
        8649                 :            : }
        8650                 :            :
        8651                 :            : PyObject *
        8652                 :          0 : PyUnicode_Translate(PyObject *str,
        8653                 :            :                     PyObject *mapping,
        8654                 :            :                     const char *errors)
        8655                 :            : {
        8656         [ #  # ]:          0 :     if (ensure_unicode(str) < 0)
        8657                 :          0 :         return NULL;
        8658                 :          0 :     return _PyUnicode_TranslateCharmap(str, mapping, errors);
        8659                 :            : }
        8660                 :            :
        8661                 :            : PyObject *
        8662                 :      10184 : _PyUnicode_TransformDecimalAndSpaceToASCII(PyObject *unicode)
        8663                 :            : {
        8664         [ -  + ]:      10184 :     if (!PyUnicode_Check(unicode)) {
        8665                 :          0 :         PyErr_BadInternalCall();
        8666                 :          0 :         return NULL;
        8667                 :            :     }
        8668         [ +  - ]:      10184 :     if (PyUnicode_IS_ASCII(unicode)) {
        8669                 :            :         /* If the string is already ASCII, just return the same string */
        8670                 :      10184 :         return Py_NewRef(unicode);
        8671                 :            :     }
        8672                 :            :
        8673                 :          0 :     Py_ssize_t len = PyUnicode_GET_LENGTH(unicode);
        8674                 :          0 :     PyObject *result = PyUnicode_New(len, 127);
        8675         [ #  # ]:          0 :     if (result == NULL) {
        8676                 :          0 :         return NULL;
        8677                 :            :     }
        8678                 :            :
        8679                 :          0 :     Py_UCS1 *out = PyUnicode_1BYTE_DATA(result);
        8680                 :          0 :     int kind = PyUnicode_KIND(unicode);
        8681                 :          0 :     const void *data = PyUnicode_DATA(unicode);
        8682                 :            :     Py_ssize_t i;
        8683         [ #  # ]:          0 :     for (i = 0; i < len; ++i) {
        8684                 :          0 :         Py_UCS4 ch = PyUnicode_READ(kind, data, i);
        8685         [ #  # ]:          0 :         if (ch < 127) {
        8686                 :          0 :             out[i] = ch;
        8687                 :            :         }
        8688         [ #  # ]:          0 :         else if (Py_UNICODE_ISSPACE(ch)) {
        8689                 :          0 :             out[i] = ' ';
        8690                 :            :         }
        8691                 :            :         else {
        8692                 :          0 :             int decimal = Py_UNICODE_TODECIMAL(ch);
        8693         [ #  # ]:          0 :             if (decimal < 0) {
        8694                 :          0 :                 out[i] = '?';
        8695                 :          0 :                 out[i+1] = '\0';
        8696                 :          0 :                 _PyUnicode_LENGTH(result) = i + 1;
        8697                 :          0 :                 break;
        8698                 :            :             }
        8699                 :          0 :             out[i] = '0' + decimal;
        8700                 :            :         }
        8701                 :            :     }
        8702                 :            :
        8703                 :            :     assert(_PyUnicode_CheckConsistency(result, 1));
        8704                 :          0 :     return result;
        8705                 :            : }
        8706                 :            :
        8707                 :            : /* --- Helpers ------------------------------------------------------------ */
        8708                 :            :
        8709                 :            : /* helper macro to fixup start/end slice values */
        8710                 :            : #define ADJUST_INDICES(start, end, len)         \
        8711                 :            :     if (end > len)                              \
        8712                 :            :         end = len;                              \
        8713                 :            :     else if (end < 0) {                         \
        8714                 :            :         end += len;                             \
        8715                 :            :         if (end < 0)                            \
        8716                 :            :             end = 0;                            \
        8717                 :            :     }                                           \
        8718                 :            :     if (start < 0) {                            \
        8719                 :            :         start += len;                           \
        8720                 :            :         if (start < 0)                          \
        8721                 :            :             start = 0;                          \
        8722                 :            :     }
        8723                 :            :
        8724                 :            : static Py_ssize_t
        8725                 :       2963 : any_find_slice(PyObject* s1, PyObject* s2,
        8726                 :            :                Py_ssize_t start,
        8727                 :            :                Py_ssize_t end,
        8728                 :            :                int direction)
        8729                 :            : {
        8730                 :            :     int kind1, kind2;
        8731                 :            :     const void *buf1, *buf2;
        8732                 :            :     Py_ssize_t len1, len2, result;
        8733                 :            :
        8734                 :       2963 :     kind1 = PyUnicode_KIND(s1);
        8735                 :       2963 :     kind2 = PyUnicode_KIND(s2);
        8736         [ -  + ]:       2963 :     if (kind1 < kind2)
        8737                 :          0 :         return -1;
        8738                 :            :
        8739                 :       2963 :     len1 = PyUnicode_GET_LENGTH(s1);
        8740                 :       2963 :     len2 = PyUnicode_GET_LENGTH(s2);
        8741   [ +  +  -  +  :       2963 :     ADJUST_INDICES(start, end, len1);
              -  -  -  +  -
                          - ]
        8742         [ -  + ]:       2963 :     if (end - start < len2)
        8743                 :          0 :         return -1;
        8744                 :            :
        8745                 :       2963 :     buf1 = PyUnicode_DATA(s1);
        8746                 :       2963 :     buf2 = PyUnicode_DATA(s2);
        8747         [ +  + ]:       2963 :     if (len2 == 1) {
        8748                 :       2836 :         Py_UCS4 ch = PyUnicode_READ(kind2, buf2, 0);
        8749                 :       2836 :         result = findchar((const char *)buf1 + kind1*start,
        8750                 :            :                           kind1, end - start, ch, direction);
        8751         [ +  + ]:       2836 :         if (result == -1)
        8752                 :        692 :             return -1;
        8753                 :            :         else
        8754                 :       2144 :             return start + result;
        8755                 :            :     }
        8756                 :            :
        8757         [ -  + ]:        127 :     if (kind2 != kind1) {
        8758                 :          0 :         buf2 = unicode_askind(kind2, buf2, len2, kind1);
        8759         [ #  # ]:          0 :         if (!buf2)
        8760                 :          0 :             return -2;
        8761                 :            :     }
        8762                 :            :
        8763         [ +  - ]:        127 :     if (direction > 0) {
        8764   [ +  -  -  - ]:        127 :         switch (kind1) {
        8765                 :        127 :         case PyUnicode_1BYTE_KIND:
        8766   [ +  -  +  - ]:        127 :             if (PyUnicode_IS_ASCII(s1) && PyUnicode_IS_ASCII(s2))
        8767                 :        127 :                 result = asciilib_find_slice(buf1, len1, buf2, len2, start, end);
        8768                 :            :             else
        8769                 :          0 :                 result = ucs1lib_find_slice(buf1, len1, buf2, len2, start, end);
        8770                 :        127 :             break;
        8771                 :          0 :         case PyUnicode_2BYTE_KIND:
        8772                 :          0 :             result = ucs2lib_find_slice(buf1, len1, buf2, len2, start, end);
        8773                 :          0 :             break;
        8774                 :          0 :         case PyUnicode_4BYTE_KIND:
        8775                 :          0 :             result = ucs4lib_find_slice(buf1, len1, buf2, len2, start, end);
        8776                 :          0 :             break;
        8777                 :          0 :         default:
        8778                 :          0 :             Py_UNREACHABLE();
        8779                 :            :         }
        8780                 :            :     }
        8781                 :            :     else {
        8782   [ #  #  #  # ]:          0 :         switch (kind1) {
        8783                 :          0 :         case PyUnicode_1BYTE_KIND:
        8784   [ #  #  #  # ]:          0 :             if (PyUnicode_IS_ASCII(s1) && PyUnicode_IS_ASCII(s2))
        8785                 :          0 :                 result = asciilib_rfind_slice(buf1, len1, buf2, len2, start, end);
        8786                 :            :             else
        8787                 :          0 :                 result = ucs1lib_rfind_slice(buf1, len1, buf2, len2, start, end);
        8788                 :          0 :             break;
        8789                 :          0 :         case PyUnicode_2BYTE_KIND:
        8790                 :          0 :             result = ucs2lib_rfind_slice(buf1, len1, buf2, len2, start, end);
        8791                 :          0 :             break;
        8792                 :          0 :         case PyUnicode_4BYTE_KIND:
        8793                 :          0 :             result = ucs4lib_rfind_slice(buf1, len1, buf2, len2, start, end);
        8794                 :          0 :             break;
        8795                 :          0 :         default:
        8796                 :          0 :             Py_UNREACHABLE();
        8797                 :            :         }
        8798                 :            :     }
        8799                 :            :
        8800                 :            :     assert((kind2 != kind1) == (buf2 != PyUnicode_DATA(s2)));
        8801         [ -  + ]:        127 :     if (kind2 != kind1)
        8802                 :          0 :         PyMem_Free((void *)buf2);
        8803                 :            :
        8804                 :        127 :     return result;
        8805                 :            : }
        8806                 :            :
        8807                 :            : /* _PyUnicode_InsertThousandsGrouping() helper functions */
        8808                 :            : #include "stringlib/localeutil.h"
        8809                 :            :
        8810                 :            : /**
        8811                 :            :  * InsertThousandsGrouping:
        8812                 :            :  * @writer: Unicode writer.
        8813                 :            :  * @n_buffer: Number of characters in @buffer.
        8814                 :            :  * @digits: Digits we're reading from. If count is non-NULL, this is unused.
        8815                 :            :  * @d_pos: Start of digits string.
        8816                 :            :  * @n_digits: The number of digits in the string, in which we want
        8817                 :            :  *            to put the grouping chars.
        8818                 :            :  * @min_width: The minimum width of the digits in the output string.
        8819                 :            :  *             Output will be zero-padded on the left to fill.
        8820                 :            :  * @grouping: see definition in localeconv().
        8821                 :            :  * @thousands_sep: see definition in localeconv().
        8822                 :            :  *
        8823                 :            :  * There are 2 modes: counting and filling. If @writer is NULL,
        8824                 :            :  *  we are in counting mode, else filling mode.
        8825                 :            :  * If counting, the required buffer size is returned.
        8826                 :            :  * If filling, we know the buffer will be large enough, so we don't
        8827                 :            :  *  need to pass in the buffer size.
        8828                 :            :  * Inserts thousand grouping characters (as defined by grouping and
        8829                 :            :  *  thousands_sep) into @writer.
        8830                 :            :  *
        8831                 :            :  * Return value: -1 on error, number of characters otherwise.
        8832                 :            :  **/
        8833                 :            : Py_ssize_t
        8834                 :     536542 : _PyUnicode_InsertThousandsGrouping(
        8835                 :            :     _PyUnicodeWriter *writer,
        8836                 :            :     Py_ssize_t n_buffer,
        8837                 :            :     PyObject *digits,
        8838                 :            :     Py_ssize_t d_pos,
        8839                 :            :     Py_ssize_t n_digits,
        8840                 :            :     Py_ssize_t min_width,
        8841                 :            :     const char *grouping,
        8842                 :            :     PyObject *thousands_sep,
        8843                 :            :     Py_UCS4 *maxchar)
        8844                 :            : {
        8845                 :     536542 :     min_width = Py_MAX(0, min_width);
        8846                 :            :     if (writer) {
        8847                 :            :         assert(digits != NULL);
        8848                 :            :         assert(maxchar == NULL);
        8849                 :            :     }
        8850                 :            :     else {
        8851                 :            :         assert(digits == NULL);
        8852                 :            :         assert(maxchar != NULL);
        8853                 :            :     }
        8854                 :            :     assert(0 <= d_pos);
        8855                 :            :     assert(0 <= n_digits);
        8856                 :            :     assert(grouping != NULL);
        8857                 :            :
        8858                 :     536542 :     Py_ssize_t count = 0;
        8859                 :            :     Py_ssize_t n_zeros;
        8860                 :     536542 :     int loop_broken = 0;
        8861                 :     536542 :     int use_separator = 0; /* First time through, don't append the
        8862                 :            :                               separator. They only go between
        8863                 :            :                               groups. */
        8864                 :            :     Py_ssize_t buffer_pos;
        8865                 :            :     Py_ssize_t digits_pos;
        8866                 :            :     Py_ssize_t len;
        8867                 :            :     Py_ssize_t n_chars;
        8868                 :     536542 :     Py_ssize_t remaining = n_digits; /* Number of chars remaining to
        8869                 :            :                                         be looked at */
        8870                 :            :     /* A generator that returns all of the grouping widths, until it
        8871                 :            :        returns 0. */
        8872                 :            :     GroupGenerator groupgen;
        8873                 :     536542 :     GroupGenerator_init(&groupgen, grouping);
        8874                 :     536542 :     const Py_ssize_t thousands_sep_len = PyUnicode_GET_LENGTH(thousands_sep);
        8875                 :            :
        8876                 :            :     /* if digits are not grouped, thousands separator
        8877                 :            :        should be an empty string */
        8878                 :            :     assert(!(grouping[0] == CHAR_MAX && thousands_sep_len != 0));
        8879                 :            :
        8880                 :     536542 :     digits_pos = d_pos + n_digits;
        8881         [ +  + ]:     536542 :     if (writer) {
        8882                 :     268271 :         buffer_pos = writer->pos + n_buffer;
        8883                 :            :         assert(buffer_pos <= PyUnicode_GET_LENGTH(writer->buffer));
        8884                 :            :         assert(digits_pos <= PyUnicode_GET_LENGTH(digits));
        8885                 :            :     }
        8886                 :            :     else {
        8887                 :     268271 :         buffer_pos = n_buffer;
        8888                 :            :     }
        8889                 :            :
        8890         [ +  + ]:     536542 :     if (!writer) {
        8891                 :     268271 :         *maxchar = 127;
        8892                 :            :     }
        8893                 :            :
        8894         [ -  + ]:     536542 :     while ((len = GroupGenerator_next(&groupgen)) > 0) {
        8895                 :          0 :         len = Py_MIN(len, Py_MAX(Py_MAX(remaining, min_width), 1));
        8896                 :          0 :         n_zeros = Py_MAX(0, len - remaining);
        8897                 :          0 :         n_chars = Py_MAX(0, Py_MIN(remaining, len));
        8898                 :            :
        8899                 :            :         /* Use n_zero zero's and n_chars chars */
        8900                 :            :
        8901                 :            :         /* Count only, don't do anything. */
        8902         [ #  # ]:          0 :         count += (use_separator ? thousands_sep_len : 0) + n_zeros + n_chars;
        8903                 :            :
        8904                 :            :         /* Copy into the writer. */
        8905         [ #  # ]:          0 :         InsertThousandsGrouping_fill(writer, &buffer_pos,
        8906                 :            :                                      digits, &digits_pos,
        8907                 :            :                                      n_chars, n_zeros,
        8908                 :            :                                      use_separator ? thousands_sep : NULL,
        8909                 :            :                                      thousands_sep_len, maxchar);
        8910                 :            :
        8911                 :            :         /* Use a separator next time. */
        8912                 :          0 :         use_separator = 1;
        8913                 :            :
        8914                 :          0 :         remaining -= n_chars;
        8915                 :          0 :         min_width -= len;
        8916                 :            :
        8917   [ #  #  #  # ]:          0 :         if (remaining <= 0 && min_width <= 0) {
        8918                 :          0 :             loop_broken = 1;
        8919                 :          0 :             break;
        8920                 :            :         }
        8921                 :          0 :         min_width -= thousands_sep_len;
        8922                 :            :     }
        8923         [ +  - ]:     536542 :     if (!loop_broken) {
        8924                 :            :         /* We left the loop without using a break statement. */
        8925                 :            :
        8926                 :     536542 :         len = Py_MAX(Py_MAX(remaining, min_width), 1);
        8927                 :     536542 :         n_zeros = Py_MAX(0, len - remaining);
        8928                 :     536542 :         n_chars = Py_MAX(0, Py_MIN(remaining, len));
        8929                 :            :
        8930                 :            :         /* Use n_zero zero's and n_chars chars */
        8931         [ -  + ]:     536542 :         count += (use_separator ? thousands_sep_len : 0) + n_zeros + n_chars;
        8932                 :            :
        8933                 :            :         /* Copy into the writer. */
        8934         [ -  + ]:     536542 :         InsertThousandsGrouping_fill(writer, &buffer_pos,
        8935                 :            :                                      digits, &digits_pos,
        8936                 :            :                                      n_chars, n_zeros,
        8937                 :            :                                      use_separator ? thousands_sep : NULL,
        8938                 :            :                                      thousands_sep_len, maxchar);
        8939                 :            :     }
        8940                 :     536542 :     return count;
        8941                 :            : }
        8942                 :            :
        8943                 :            : static Py_ssize_t
        8944                 :        112 : unicode_count_impl(PyObject *str,
        8945                 :            :                    PyObject *substr,
        8946                 :            :                    Py_ssize_t start,
        8947                 :            :                    Py_ssize_t end)
        8948                 :            : {
        8949                 :            :     assert(PyUnicode_Check(str));
        8950                 :            :     assert(PyUnicode_Check(substr));
        8951                 :            :
        8952                 :            :     Py_ssize_t result;
        8953                 :            :     int kind1, kind2;
        8954                 :        112 :     const void *buf1 = NULL, *buf2 = NULL;
        8955                 :            :     Py_ssize_t len1, len2;
        8956                 :            :
        8957                 :        112 :     kind1 = PyUnicode_KIND(str);
        8958                 :        112 :     kind2 = PyUnicode_KIND(substr);
        8959         [ -  + ]:        112 :     if (kind1 < kind2)
        8960                 :          0 :         return 0;
        8961                 :            :
        8962                 :        112 :     len1 = PyUnicode_GET_LENGTH(str);
        8963                 :        112 :     len2 = PyUnicode_GET_LENGTH(substr);
        8964   [ -  +  -  +  :        112 :     ADJUST_INDICES(start, end, len1);
              -  -  -  +  -
                          - ]
        8965         [ +  + ]:        112 :     if (end - start < len2)
        8966                 :         42 :         return 0;
        8967                 :            :
        8968                 :         70 :     buf1 = PyUnicode_DATA(str);
        8969                 :         70 :     buf2 = PyUnicode_DATA(substr);
        8970         [ -  + ]:         70 :     if (kind2 != kind1) {
        8971                 :          0 :         buf2 = unicode_askind(kind2, buf2, len2, kind1);
        8972         [ #  # ]:          0 :         if (!buf2)
        8973                 :          0 :             goto onError;
        8974                 :            :     }
        8975                 :            :
        8976                 :            :     // We don't reuse `anylib_count` here because of the explicit casts.
        8977   [ +  -  -  - ]:         70 :     switch (kind1) {
        8978                 :         70 :     case PyUnicode_1BYTE_KIND:
        8979                 :         70 :         result = ucs1lib_count(
        8980                 :            :             ((const Py_UCS1*)buf1) + start, end - start,
        8981                 :            :             buf2, len2, PY_SSIZE_T_MAX
        8982                 :            :             );
        8983                 :         70 :         break;
        8984                 :          0 :     case PyUnicode_2BYTE_KIND:
        8985                 :          0 :         result = ucs2lib_count(
        8986                 :          0 :             ((const Py_UCS2*)buf1) + start, end - start,
        8987                 :            :             buf2, len2, PY_SSIZE_T_MAX
        8988                 :            :             );
        8989                 :          0 :         break;
        8990                 :          0 :     case PyUnicode_4BYTE_KIND:
        8991                 :          0 :         result = ucs4lib_count(
        8992                 :          0 :             ((const Py_UCS4*)buf1) + start, end - start,
        8993                 :            :             buf2, len2, PY_SSIZE_T_MAX
        8994                 :            :             );
        8995                 :          0 :         break;
        8996                 :          0 :     default:
        8997                 :          0 :         Py_UNREACHABLE();
        8998                 :            :     }
        8999                 :            :
        9000                 :            :     assert((kind2 != kind1) == (buf2 != PyUnicode_DATA(substr)));
        9001         [ -  + ]:         70 :     if (kind2 != kind1)
        9002                 :          0 :         PyMem_Free((void *)buf2);
        9003                 :            :
        9004                 :         70 :     return result;
        9005                 :          0 :   onError:
        9006                 :            :     assert((kind2 != kind1) == (buf2 != PyUnicode_DATA(substr)));
        9007         [ #  # ]:          0 :     if (kind2 != kind1)
        9008                 :          0 :         PyMem_Free((void *)buf2);
        9009                 :          0 :     return -1;
        9010                 :            : }
        9011                 :            :
        9012                 :            : Py_ssize_t
        9013                 :          0 : PyUnicode_Count(PyObject *str,
        9014                 :            :                 PyObject *substr,
        9015                 :            :                 Py_ssize_t start,
        9016                 :            :                 Py_ssize_t end)
        9017                 :            : {
        9018   [ #  #  #  # ]:          0 :     if (ensure_unicode(str) < 0 || ensure_unicode(substr) < 0)
        9019                 :          0 :         return -1;
        9020                 :            :
        9021                 :          0 :     return unicode_count_impl(str, substr, start, end);
        9022                 :            : }
        9023                 :            :
        9024                 :            : Py_ssize_t
        9025                 :          0 : PyUnicode_Find(PyObject *str,
        9026                 :            :                PyObject *substr,
        9027                 :            :                Py_ssize_t start,
        9028                 :            :                Py_ssize_t end,
        9029                 :            :                int direction)
        9030                 :            : {
        9031   [ #  #  #  # ]:          0 :     if (ensure_unicode(str) < 0 || ensure_unicode(substr) < 0)
        9032                 :          0 :         return -2;
        9033                 :            :
        9034                 :          0 :     return any_find_slice(str, substr, start, end, direction);
        9035                 :            : }
        9036                 :            :
        9037                 :            : Py_ssize_t
        9038                 :       9439 : PyUnicode_FindChar(PyObject *str, Py_UCS4 ch,
        9039                 :            :                    Py_ssize_t start, Py_ssize_t end,
        9040                 :            :                    int direction)
        9041                 :            : {
        9042                 :            :     int kind;
        9043                 :            :     Py_ssize_t len, result;
        9044                 :       9439 :     len = PyUnicode_GET_LENGTH(str);
        9045   [ -  +  -  +  :       9439 :     ADJUST_INDICES(start, end, len);
              -  -  -  +  -
                          - ]
        9046         [ -  + ]:       9439 :     if (end - start < 1)
        9047                 :          0 :         return -1;
        9048                 :       9439 :     kind = PyUnicode_KIND(str);
        9049                 :       9439 :     result = findchar(PyUnicode_1BYTE_DATA(str) + kind*start,
        9050                 :            :                       kind, end-start, ch, direction);
        9051         [ +  + ]:       9439 :     if (result == -1)
        9052                 :       9056 :         return -1;
        9053                 :            :     else
        9054                 :        383 :         return start + result;
        9055                 :            : }
        9056                 :            :
        9057                 :            : static int
        9058                 :      21222 : tailmatch(PyObject *self,
        9059                 :            :           PyObject *substring,
        9060                 :            :           Py_ssize_t start,
        9061                 :            :           Py_ssize_t end,
        9062                 :            :           int direction)
        9063                 :            : {
        9064                 :            :     int kind_self;
        9065                 :            :     int kind_sub;
        9066                 :            :     const void *data_self;
        9067                 :            :     const void *data_sub;
        9068                 :            :     Py_ssize_t offset;
        9069                 :            :     Py_ssize_t i;
        9070                 :            :     Py_ssize_t end_sub;
        9071                 :            :
        9072   [ +  -  -  -  :      21222 :     ADJUST_INDICES(start, end, PyUnicode_GET_LENGTH(self));
              -  -  -  +  -
                          - ]
        9073                 :      21222 :     end -= PyUnicode_GET_LENGTH(substring);
        9074         [ +  + ]:      21222 :     if (end < start)
        9075                 :        655 :         return 0;
        9076                 :            :
        9077         [ +  + ]:      20567 :     if (PyUnicode_GET_LENGTH(substring) == 0)
        9078                 :         65 :         return 1;
        9079                 :            :
        9080                 :      20502 :     kind_self = PyUnicode_KIND(self);
        9081                 :      20502 :     data_self = PyUnicode_DATA(self);
        9082                 :      20502 :     kind_sub = PyUnicode_KIND(substring);
        9083                 :      20502 :     data_sub = PyUnicode_DATA(substring);
        9084                 :      20502 :     end_sub = PyUnicode_GET_LENGTH(substring) - 1;
        9085                 :            :
        9086         [ +  + ]:      20502 :     if (direction > 0)
        9087                 :       5561 :         offset = end;
        9088                 :            :     else
        9089                 :      14941 :         offset = start;
        9090                 :            :
        9091         [ +  + ]:      41004 :     if (PyUnicode_READ(kind_self, data_self, offset) ==
        9092         [ +  + ]:      27514 :         PyUnicode_READ(kind_sub, data_sub, 0) &&
        9093                 :       7012 :         PyUnicode_READ(kind_self, data_self, offset + end_sub) ==
        9094                 :       7012 :         PyUnicode_READ(kind_sub, data_sub, end_sub)) {
        9095                 :            :         /* If both are of the same kind, memcmp is sufficient */
        9096         [ +  - ]:       5480 :         if (kind_self == kind_sub) {
        9097                 :       5480 :             return ! memcmp((char *)data_self +
        9098                 :       5480 :                                 (offset * PyUnicode_KIND(substring)),
        9099                 :            :                             data_sub,
        9100                 :       5480 :                             PyUnicode_GET_LENGTH(substring) *
        9101                 :       5480 :                                 PyUnicode_KIND(substring));
        9102                 :            :         }
        9103                 :            :         /* otherwise we have to compare each character by first accessing it */
        9104                 :            :         else {
        9105                 :            :             /* We do not need to compare 0 and len(substring)-1 because
        9106                 :            :                the if statement above ensured already that they are equal
        9107                 :            :                when we end up here. */
        9108         [ #  # ]:          0 :             for (i = 1; i < end_sub; ++i) {
        9109         [ #  # ]:          0 :                 if (PyUnicode_READ(kind_self, data_self, offset + i) !=
        9110                 :          0 :                     PyUnicode_READ(kind_sub, data_sub, i))
        9111                 :          0 :                     return 0;
        9112                 :            :             }
        9113                 :          0 :             return 1;
        9114                 :            :         }
        9115                 :            :     }
        9116                 :            :
        9117                 :      15022 :     return 0;
        9118                 :            : }
        9119                 :            :
        9120                 :            : Py_ssize_t
        9121                 :         22 : PyUnicode_Tailmatch(PyObject *str,
        9122                 :            :                     PyObject *substr,
        9123                 :            :                     Py_ssize_t start,
        9124                 :            :                     Py_ssize_t end,
        9125                 :            :                     int direction)
        9126                 :            : {
        9127   [ +  -  -  + ]:         22 :     if (ensure_unicode(str) < 0 || ensure_unicode(substr) < 0)
        9128                 :          0 :         return -1;
        9129                 :            :
        9130                 :         22 :     return tailmatch(str, substr, start, end, direction);
        9131                 :            : }
        9132                 :            :
        9133                 :            : static PyObject *
        9134                 :        235 : ascii_upper_or_lower(PyObject *self, int lower)
        9135                 :            : {
        9136                 :        235 :     Py_ssize_t len = PyUnicode_GET_LENGTH(self);
        9137                 :        235 :     const char *data = PyUnicode_DATA(self);
        9138                 :            :     char *resdata;
        9139                 :            :     PyObject *res;
        9140                 :            :
        9141                 :        235 :     res = PyUnicode_New(len, 127);
        9142         [ -  + ]:        235 :     if (res == NULL)
        9143                 :          0 :         return NULL;
        9144                 :        235 :     resdata = PyUnicode_DATA(res);
        9145         [ +  + ]:        235 :     if (lower)
        9146                 :        127 :         _Py_bytes_lower(resdata, data, len);
        9147                 :            :     else
        9148                 :        108 :         _Py_bytes_upper(resdata, data, len);
        9149                 :        235 :     return res;
        9150                 :            : }
        9151                 :            :
        9152                 :            : static Py_UCS4
        9153                 :          0 : handle_capital_sigma(int kind, const void *data, Py_ssize_t length, Py_ssize_t i)
        9154                 :            : {
        9155                 :            :     Py_ssize_t j;
        9156                 :            :     int final_sigma;
        9157                 :          0 :     Py_UCS4 c = 0;   /* initialize to prevent gcc warning */
        9158                 :            :     /* U+03A3 is in the Final_Sigma context when, it is found like this:
        9159                 :            :
        9160                 :            :      \p{cased}\p{case-ignorable}*U+03A3!(\p{case-ignorable}*\p{cased})
        9161                 :            :
        9162                 :            :     where ! is a negation and \p{xxx} is a character with property xxx.
        9163                 :            :     */
        9164         [ #  # ]:          0 :     for (j = i - 1; j >= 0; j--) {
        9165                 :          0 :         c = PyUnicode_READ(kind, data, j);
        9166         [ #  # ]:          0 :         if (!_PyUnicode_IsCaseIgnorable(c))
        9167                 :          0 :             break;
        9168                 :            :     }
        9169   [ #  #  #  # ]:          0 :     final_sigma = j >= 0 && _PyUnicode_IsCased(c);
        9170         [ #  # ]:          0 :     if (final_sigma) {
        9171         [ #  # ]:          0 :         for (j = i + 1; j < length; j++) {
        9172                 :          0 :             c = PyUnicode_READ(kind, data, j);
        9173         [ #  # ]:          0 :             if (!_PyUnicode_IsCaseIgnorable(c))
        9174                 :          0 :                 break;
        9175                 :            :         }
        9176   [ #  #  #  # ]:          0 :         final_sigma = j == length || !_PyUnicode_IsCased(c);
        9177                 :            :     }
        9178         [ #  # ]:          0 :     return (final_sigma) ? 0x3C2 : 0x3C3;
        9179                 :            : }
        9180                 :            :
        9181                 :            : static int
        9182                 :          0 : lower_ucs4(int kind, const void *data, Py_ssize_t length, Py_ssize_t i,
        9183                 :            :            Py_UCS4 c, Py_UCS4 *mapped)
        9184                 :            : {
        9185                 :            :     /* Obscure special case. */
        9186         [ #  # ]:          0 :     if (c == 0x3A3) {
        9187                 :          0 :         mapped[0] = handle_capital_sigma(kind, data, length, i);
        9188                 :          0 :         return 1;
        9189                 :            :     }
        9190                 :          0 :     return _PyUnicode_ToLowerFull(c, mapped);
        9191                 :            : }
        9192                 :            :
        9193                 :            : static Py_ssize_t
        9194                 :          0 : do_capitalize(int kind, const void *data, Py_ssize_t length, Py_UCS4 *res, Py_UCS4 *maxchar)
        9195                 :            : {
        9196                 :          0 :     Py_ssize_t i, k = 0;
        9197                 :            :     int n_res, j;
        9198                 :            :     Py_UCS4 c, mapped[3];
        9199                 :            :
        9200                 :          0 :     c = PyUnicode_READ(kind, data, 0);
        9201                 :          0 :     n_res = _PyUnicode_ToTitleFull(c, mapped);
        9202         [ #  # ]:          0 :     for (j = 0; j < n_res; j++) {
        9203                 :          0 :         *maxchar = Py_MAX(*maxchar, mapped[j]);
        9204                 :          0 :         res[k++] = mapped[j];
        9205                 :            :     }
        9206         [ #  # ]:          0 :     for (i = 1; i < length; i++) {
        9207                 :          0 :         c = PyUnicode_READ(kind, data, i);
        9208                 :          0 :         n_res = lower_ucs4(kind, data, length, i, c, mapped);
        9209         [ #  # ]:          0 :         for (j = 0; j < n_res; j++) {
        9210                 :          0 :             *maxchar = Py_MAX(*maxchar, mapped[j]);
        9211                 :          0 :             res[k++] = mapped[j];
        9212                 :            :         }
        9213                 :            :     }
        9214                 :          0 :     return k;
        9215                 :            : }
        9216                 :            :
        9217                 :            : static Py_ssize_t
        9218                 :          0 : do_swapcase(int kind, const void *data, Py_ssize_t length, Py_UCS4 *res, Py_UCS4 *maxchar) {
        9219                 :          0 :     Py_ssize_t i, k = 0;
        9220                 :            :
        9221         [ #  # ]:          0 :     for (i = 0; i < length; i++) {
        9222                 :          0 :         Py_UCS4 c = PyUnicode_READ(kind, data, i), mapped[3];
        9223                 :            :         int n_res, j;
        9224         [ #  # ]:          0 :         if (Py_UNICODE_ISUPPER(c)) {
        9225                 :          0 :             n_res = lower_ucs4(kind, data, length, i, c, mapped);
        9226                 :            :         }
        9227         [ #  # ]:          0 :         else if (Py_UNICODE_ISLOWER(c)) {
        9228                 :          0 :             n_res = _PyUnicode_ToUpperFull(c, mapped);
        9229                 :            :         }
        9230                 :            :         else {
        9231                 :          0 :             n_res = 1;
        9232                 :          0 :             mapped[0] = c;
        9233                 :            :         }
        9234         [ #  # ]:          0 :         for (j = 0; j < n_res; j++) {
        9235                 :          0 :             *maxchar = Py_MAX(*maxchar, mapped[j]);
        9236                 :          0 :             res[k++] = mapped[j];
        9237                 :            :         }
        9238                 :            :     }
        9239                 :          0 :     return k;
        9240                 :            : }
        9241                 :            :
        9242                 :            : static Py_ssize_t
        9243                 :          0 : do_upper_or_lower(int kind, const void *data, Py_ssize_t length, Py_UCS4 *res,
        9244                 :            :                   Py_UCS4 *maxchar, int lower)
        9245                 :            : {
        9246                 :          0 :     Py_ssize_t i, k = 0;
        9247                 :            :
        9248         [ #  # ]:          0 :     for (i = 0; i < length; i++) {
        9249                 :          0 :         Py_UCS4 c = PyUnicode_READ(kind, data, i), mapped[3];
        9250                 :            :         int n_res, j;
        9251         [ #  # ]:          0 :         if (lower)
        9252                 :          0 :             n_res = lower_ucs4(kind, data, length, i, c, mapped);
        9253                 :            :         else
        9254                 :          0 :             n_res = _PyUnicode_ToUpperFull(c, mapped);
        9255         [ #  # ]:          0 :         for (j = 0; j < n_res; j++) {
        9256                 :          0 :             *maxchar = Py_MAX(*maxchar, mapped[j]);
        9257                 :          0 :             res[k++] = mapped[j];
        9258                 :            :         }
        9259                 :            :     }
        9260                 :          0 :     return k;
        9261                 :            : }
        9262                 :            :
        9263                 :            : static Py_ssize_t
        9264                 :          0 : do_upper(int kind, const void *data, Py_ssize_t length, Py_UCS4 *res, Py_UCS4 *maxchar)
        9265                 :            : {
        9266                 :          0 :     return do_upper_or_lower(kind, data, length, res, maxchar, 0);
        9267                 :            : }
        9268                 :            :
        9269                 :            : static Py_ssize_t
        9270                 :          0 : do_lower(int kind, const void *data, Py_ssize_t length, Py_UCS4 *res, Py_UCS4 *maxchar)
        9271                 :            : {
        9272                 :          0 :     return do_upper_or_lower(kind, data, length, res, maxchar, 1);
        9273                 :            : }
        9274                 :            :
        9275                 :            : static Py_ssize_t
        9276                 :          0 : do_casefold(int kind, const void *data, Py_ssize_t length, Py_UCS4 *res, Py_UCS4 *maxchar)
        9277                 :            : {
        9278                 :          0 :     Py_ssize_t i, k = 0;
        9279                 :            :
        9280         [ #  # ]:          0 :     for (i = 0; i < length; i++) {
        9281                 :          0 :         Py_UCS4 c = PyUnicode_READ(kind, data, i);
        9282                 :            :         Py_UCS4 mapped[3];
        9283                 :          0 :         int j, n_res = _PyUnicode_ToFoldedFull(c, mapped);
        9284         [ #  # ]:          0 :         for (j = 0; j < n_res; j++) {
        9285                 :          0 :             *maxchar = Py_MAX(*maxchar, mapped[j]);
        9286                 :          0 :             res[k++] = mapped[j];
        9287                 :            :         }
        9288                 :            :     }
        9289                 :          0 :     return k;
        9290                 :            : }
        9291                 :            :
        9292                 :            : static Py_ssize_t
        9293                 :          0 : do_title(int kind, const void *data, Py_ssize_t length, Py_UCS4 *res, Py_UCS4 *maxchar)
        9294                 :            : {
        9295                 :          0 :     Py_ssize_t i, k = 0;
        9296                 :            :     int previous_is_cased;
        9297                 :            :
        9298                 :          0 :     previous_is_cased = 0;
        9299         [ #  # ]:          0 :     for (i = 0; i < length; i++) {
        9300                 :          0 :         const Py_UCS4 c = PyUnicode_READ(kind, data, i);
        9301                 :            :         Py_UCS4 mapped[3];
        9302                 :            :         int n_res, j;
        9303                 :            :
        9304         [ #  # ]:          0 :         if (previous_is_cased)
        9305                 :          0 :             n_res = lower_ucs4(kind, data, length, i, c, mapped);
        9306                 :            :         else
        9307                 :          0 :             n_res = _PyUnicode_ToTitleFull(c, mapped);
        9308                 :            :
        9309         [ #  # ]:          0 :         for (j = 0; j < n_res; j++) {
        9310                 :          0 :             *maxchar = Py_MAX(*maxchar, mapped[j]);
        9311                 :          0 :             res[k++] = mapped[j];
        9312                 :            :         }
        9313                 :            :
        9314                 :          0 :         previous_is_cased = _PyUnicode_IsCased(c);
        9315                 :            :     }
        9316                 :          0 :     return k;
        9317                 :            : }
        9318                 :            :
        9319                 :            : static PyObject *
        9320                 :          0 : case_operation(PyObject *self,
        9321                 :            :                Py_ssize_t (*perform)(int, const void *, Py_ssize_t, Py_UCS4 *, Py_UCS4 *))
        9322                 :            : {
        9323                 :          0 :     PyObject *res = NULL;
        9324                 :          0 :     Py_ssize_t length, newlength = 0;
        9325                 :            :     int kind, outkind;
        9326                 :            :     const void *data;
        9327                 :            :     void *outdata;
        9328                 :          0 :     Py_UCS4 maxchar = 0, *tmp, *tmpend;
        9329                 :            :
        9330                 :          0 :     kind = PyUnicode_KIND(self);
        9331                 :          0 :     data = PyUnicode_DATA(self);
        9332                 :          0 :     length = PyUnicode_GET_LENGTH(self);
        9333         [ #  # ]:          0 :     if ((size_t) length > PY_SSIZE_T_MAX / (3 * sizeof(Py_UCS4))) {
        9334                 :          0 :         PyErr_SetString(PyExc_OverflowError, "string is too long");
        9335                 :          0 :         return NULL;
        9336                 :            :     }
        9337                 :          0 :     tmp = PyMem_Malloc(sizeof(Py_UCS4) * 3 * length);
        9338         [ #  # ]:          0 :     if (tmp == NULL)
        9339                 :          0 :         return PyErr_NoMemory();
        9340                 :          0 :     newlength = perform(kind, data, length, tmp, &maxchar);
        9341                 :          0 :     res = PyUnicode_New(newlength, maxchar);
        9342         [ #  # ]:          0 :     if (res == NULL)
        9343                 :          0 :         goto leave;
        9344                 :          0 :     tmpend = tmp + newlength;
        9345                 :          0 :     outdata = PyUnicode_DATA(res);
        9346                 :          0 :     outkind = PyUnicode_KIND(res);
        9347   [ #  #  #  # ]:          0 :     switch (outkind) {
        9348                 :          0 :     case PyUnicode_1BYTE_KIND:
        9349   [ #  #  #  # ]:          0 :         _PyUnicode_CONVERT_BYTES(Py_UCS4, Py_UCS1, tmp, tmpend, outdata);
        9350                 :          0 :         break;
        9351                 :          0 :     case PyUnicode_2BYTE_KIND:
        9352   [ #  #  #  # ]:          0 :         _PyUnicode_CONVERT_BYTES(Py_UCS4, Py_UCS2, tmp, tmpend, outdata);
        9353                 :          0 :         break;
        9354                 :          0 :     case PyUnicode_4BYTE_KIND:
        9355                 :          0 :         memcpy(outdata, tmp, sizeof(Py_UCS4) * newlength);
        9356                 :          0 :         break;
        9357                 :          0 :     default:
        9358                 :          0 :         Py_UNREACHABLE();
        9359                 :            :     }
        9360                 :          0 :   leave:
        9361                 :          0 :     PyMem_Free(tmp);
        9362                 :          0 :     return res;
        9363                 :            : }
        9364                 :            :
        9365                 :            : PyObject *
        9366                 :      30284 : PyUnicode_Join(PyObject *separator, PyObject *seq)
        9367                 :            : {
        9368                 :            :     PyObject *res;
        9369                 :            :     PyObject *fseq;
        9370                 :            :     Py_ssize_t seqlen;
        9371                 :            :     PyObject **items;
        9372                 :            :
        9373                 :      30284 :     fseq = PySequence_Fast(seq, "can only join an iterable");
        9374         [ -  + ]:      30284 :     if (fseq == NULL) {
        9375                 :          0 :         return NULL;
        9376                 :            :     }
        9377                 :            :
        9378                 :            :     /* NOTE: the following code can't call back into Python code,
        9379                 :            :      * so we are sure that fseq won't be mutated.
        9380                 :            :      */
        9381                 :            :
        9382         [ +  + ]:      30284 :     items = PySequence_Fast_ITEMS(fseq);
        9383         [ +  + ]:      30284 :     seqlen = PySequence_Fast_GET_SIZE(fseq);
        9384                 :      30284 :     res = _PyUnicode_JoinArray(separator, items, seqlen);
        9385                 :      30284 :     Py_DECREF(fseq);
        9386                 :      30284 :     return res;
        9387                 :            : }
        9388                 :            :
        9389                 :            : PyObject *
        9390                 :     372318 : _PyUnicode_JoinArray(PyObject *separator, PyObject *const *items, Py_ssize_t seqlen)
        9391                 :            : {
        9392                 :     372318 :     PyObject *res = NULL; /* the result */
        9393                 :     372318 :     PyObject *sep = NULL;
        9394                 :            :     Py_ssize_t seplen;
        9395                 :            :     PyObject *item;
        9396                 :            :     Py_ssize_t sz, i, res_offset;
        9397                 :            :     Py_UCS4 maxchar;
        9398                 :            :     Py_UCS4 item_maxchar;
        9399                 :            :     int use_memcpy;
        9400                 :     372318 :     unsigned char *res_data = NULL, *sep_data = NULL;
        9401                 :            :     PyObject *last_obj;
        9402                 :     372318 :     int kind = 0;
        9403                 :            :
        9404                 :            :     /* If empty sequence, return u"". */
        9405         [ +  + ]:     372318 :     if (seqlen == 0) {
        9406                 :          9 :         _Py_RETURN_UNICODE_EMPTY();
        9407                 :            :     }
        9408                 :            :
        9409                 :            :     /* If singleton sequence with an exact Unicode, return that. */
        9410                 :     372309 :     last_obj = NULL;
        9411         [ +  + ]:     372309 :     if (seqlen == 1) {
        9412         [ +  - ]:        272 :         if (PyUnicode_CheckExact(items[0])) {
        9413                 :        272 :             res = items[0];
        9414                 :        272 :             return Py_NewRef(res);
        9415                 :            :         }
        9416                 :          0 :         seplen = 0;
        9417                 :          0 :         maxchar = 0;
        9418                 :            :     }
        9419                 :            :     else {
        9420                 :            :         /* Set up sep and seplen */
        9421         [ -  + ]:     372037 :         if (separator == NULL) {
        9422                 :            :             /* fall back to a blank space separator */
        9423                 :          0 :             sep = PyUnicode_FromOrdinal(' ');
        9424         [ #  # ]:          0 :             if (!sep)
        9425                 :          0 :                 goto onError;
        9426                 :          0 :             seplen = 1;
        9427                 :          0 :             maxchar = 32;
        9428                 :            :         }
        9429                 :            :         else {
        9430         [ -  + ]:     372037 :             if (!PyUnicode_Check(separator)) {
        9431                 :          0 :                 PyErr_Format(PyExc_TypeError,
        9432                 :            :                              "separator: expected str instance,"
        9433                 :            :                              " %.80s found",
        9434                 :          0 :                              Py_TYPE(separator)->tp_name);
        9435                 :          0 :                 goto onError;
        9436                 :            :             }
        9437                 :     372037 :             sep = separator;
        9438                 :     372037 :             seplen = PyUnicode_GET_LENGTH(separator);
        9439                 :     372037 :             maxchar = PyUnicode_MAX_CHAR_VALUE(separator);
        9440                 :            :             /* inc refcount to keep this code path symmetric with the
        9441                 :            :                above case of a blank separator */
        9442                 :     372037 :             Py_INCREF(sep);
        9443                 :            :         }
        9444                 :     372037 :         last_obj = sep;
        9445                 :            :     }
        9446                 :            :
        9447                 :            :     /* There are at least two things to join, or else we have a subclass
        9448                 :            :      * of str in the sequence.
        9449                 :            :      * Do a pre-pass to figure out the total amount of space we'll
        9450                 :            :      * need (sz), and see whether all argument are strings.
        9451                 :            :      */
        9452                 :     372037 :     sz = 0;
        9453                 :            : #ifdef Py_DEBUG
        9454                 :            :     use_memcpy = 0;
        9455                 :            : #else
        9456                 :     372037 :     use_memcpy = 1;
        9457                 :            : #endif
        9458         [ +  + ]:    1724357 :     for (i = 0; i < seqlen; i++) {
        9459                 :            :         size_t add_sz;
        9460                 :    1352320 :         item = items[i];
        9461         [ -  + ]:    1352320 :         if (!PyUnicode_Check(item)) {
        9462                 :          0 :             PyErr_Format(PyExc_TypeError,
        9463                 :            :                          "sequence item %zd: expected str instance,"
        9464                 :            :                          " %.80s found",
        9465                 :          0 :                          i, Py_TYPE(item)->tp_name);
        9466                 :          0 :             goto onError;
        9467                 :            :         }
        9468                 :    1352320 :         add_sz = PyUnicode_GET_LENGTH(item);
        9469                 :    1352320 :         item_maxchar = PyUnicode_MAX_CHAR_VALUE(item);
        9470                 :    1352320 :         maxchar = Py_MAX(maxchar, item_maxchar);
        9471         [ +  + ]:    1352320 :         if (i != 0) {
        9472                 :     980283 :             add_sz += seplen;
        9473                 :            :         }
        9474         [ -  + ]:    1352320 :         if (add_sz > (size_t)(PY_SSIZE_T_MAX - sz)) {
        9475                 :          0 :             PyErr_SetString(PyExc_OverflowError,
        9476                 :            :                             "join() result is too long for a Python string");
        9477                 :          0 :             goto onError;
        9478                 :            :         }
        9479                 :    1352320 :         sz += add_sz;
        9480   [ +  +  +  - ]:    1352320 :         if (use_memcpy && last_obj != NULL) {
        9481         [ +  + ]:    1352305 :             if (PyUnicode_KIND(last_obj) != PyUnicode_KIND(item))
        9482                 :         15 :                 use_memcpy = 0;
        9483                 :            :         }
        9484                 :    1352320 :         last_obj = item;
        9485                 :            :     }
        9486                 :            :
        9487                 :     372037 :     res = PyUnicode_New(sz, maxchar);
        9488         [ -  + ]:     372037 :     if (res == NULL)
        9489                 :          0 :         goto onError;
        9490                 :            :
        9491                 :            :     /* Catenate everything. */
        9492                 :            : #ifdef Py_DEBUG
        9493                 :            :     use_memcpy = 0;
        9494                 :            : #else
        9495         [ +  + ]:     372037 :     if (use_memcpy) {
        9496                 :     372022 :         res_data = PyUnicode_1BYTE_DATA(res);
        9497                 :     372022 :         kind = PyUnicode_KIND(res);
        9498         [ +  + ]:     372022 :         if (seplen != 0)
        9499                 :      21748 :             sep_data = PyUnicode_1BYTE_DATA(sep);
        9500                 :            :     }
        9501                 :            : #endif
        9502         [ +  + ]:     372037 :     if (use_memcpy) {
        9503         [ +  + ]:    1724297 :         for (i = 0; i < seqlen; ++i) {
        9504                 :            :             Py_ssize_t itemlen;
        9505                 :    1352275 :             item = items[i];
        9506                 :            :
        9507                 :            :             /* Copy item, and maybe the separator. */
        9508   [ +  +  +  + ]:    1352275 :             if (i && seplen != 0) {
        9509                 :     253735 :                 memcpy(res_data,
        9510                 :            :                           sep_data,
        9511                 :     253735 :                           kind * seplen);
        9512                 :     253735 :                 res_data += kind * seplen;
        9513                 :            :             }
        9514                 :            :
        9515                 :    1352275 :             itemlen = PyUnicode_GET_LENGTH(item);
        9516         [ +  + ]:    1352275 :             if (itemlen != 0) {
        9517                 :    2704532 :                 memcpy(res_data,
        9518                 :    1352266 :                           PyUnicode_DATA(item),
        9519                 :    1352266 :                           kind * itemlen);
        9520                 :    1352266 :                 res_data += kind * itemlen;
        9521                 :            :             }
        9522                 :            :         }
        9523                 :            :         assert(res_data == PyUnicode_1BYTE_DATA(res)
        9524                 :            :                            + kind * PyUnicode_GET_LENGTH(res));
        9525                 :            :     }
        9526                 :            :     else {
        9527         [ +  + ]:         60 :         for (i = 0, res_offset = 0; i < seqlen; ++i) {
        9528                 :            :             Py_ssize_t itemlen;
        9529                 :         45 :             item = items[i];
        9530                 :            :
        9531                 :            :             /* Copy item, and maybe the separator. */
        9532   [ +  +  -  + ]:         45 :             if (i && seplen != 0) {
        9533                 :          0 :                 _PyUnicode_FastCopyCharacters(res, res_offset, sep, 0, seplen);
        9534                 :          0 :                 res_offset += seplen;
        9535                 :            :             }
        9536                 :            :
        9537                 :         45 :             itemlen = PyUnicode_GET_LENGTH(item);
        9538         [ +  - ]:         45 :             if (itemlen != 0) {
        9539                 :         45 :                 _PyUnicode_FastCopyCharacters(res, res_offset, item, 0, itemlen);
        9540                 :         45 :                 res_offset += itemlen;
        9541                 :            :             }
        9542                 :            :         }
        9543                 :            :         assert(res_offset == PyUnicode_GET_LENGTH(res));
        9544                 :            :     }
        9545                 :            :
        9546                 :     372037 :     Py_XDECREF(sep);
        9547                 :            :     assert(_PyUnicode_CheckConsistency(res, 1));
        9548                 :     372037 :     return res;
        9549                 :            :
        9550                 :          0 :   onError:
        9551                 :          0 :     Py_XDECREF(sep);
        9552                 :          0 :     Py_XDECREF(res);
        9553                 :          0 :     return NULL;
        9554                 :            : }
        9555                 :            :
        9556                 :            : void
        9557                 :          0 : _PyUnicode_FastFill(PyObject *unicode, Py_ssize_t start, Py_ssize_t length,
        9558                 :            :                     Py_UCS4 fill_char)
        9559                 :            : {
        9560                 :          0 :     const int kind = PyUnicode_KIND(unicode);
        9561                 :          0 :     void *data = PyUnicode_DATA(unicode);
        9562                 :            :     assert(unicode_modifiable(unicode));
        9563                 :            :     assert(fill_char <= PyUnicode_MAX_CHAR_VALUE(unicode));
        9564                 :            :     assert(start >= 0);
        9565                 :            :     assert(start + length <= PyUnicode_GET_LENGTH(unicode));
        9566                 :          0 :     unicode_fill(kind, data, fill_char, start, length);
        9567                 :          0 : }
        9568                 :            :
        9569                 :            : Py_ssize_t
        9570                 :          0 : PyUnicode_Fill(PyObject *unicode, Py_ssize_t start, Py_ssize_t length,
        9571                 :            :                Py_UCS4 fill_char)
        9572                 :            : {
        9573                 :            :     Py_ssize_t maxlen;
        9574                 :            :
        9575         [ #  # ]:          0 :     if (!PyUnicode_Check(unicode)) {
        9576                 :          0 :         PyErr_BadInternalCall();
        9577                 :          0 :         return -1;
        9578                 :            :     }
        9579         [ #  # ]:          0 :     if (unicode_check_modifiable(unicode))
        9580                 :          0 :         return -1;
        9581                 :            :
        9582         [ #  # ]:          0 :     if (start < 0) {
        9583                 :          0 :         PyErr_SetString(PyExc_IndexError, "string index out of range");
        9584                 :          0 :         return -1;
        9585                 :            :     }
        9586         [ #  # ]:          0 :     if (fill_char > PyUnicode_MAX_CHAR_VALUE(unicode)) {
        9587                 :          0 :         PyErr_SetString(PyExc_ValueError,
        9588                 :            :                          "fill character is bigger than "
        9589                 :            :                          "the string maximum character");
        9590                 :          0 :         return -1;
        9591                 :            :     }
        9592                 :            :
        9593                 :          0 :     maxlen = PyUnicode_GET_LENGTH(unicode) - start;
        9594                 :          0 :     length = Py_MIN(maxlen, length);
        9595         [ #  # ]:          0 :     if (length <= 0)
        9596                 :          0 :         return 0;
        9597                 :            :
        9598                 :          0 :     _PyUnicode_FastFill(unicode, start, length, fill_char);
        9599                 :          0 :     return length;
        9600                 :            : }
        9601                 :            :
        9602                 :            : static PyObject *
        9603                 :          0 : pad(PyObject *self,
        9604                 :            :     Py_ssize_t left,
        9605                 :            :     Py_ssize_t right,
        9606                 :            :     Py_UCS4 fill)
        9607                 :            : {
        9608                 :            :     PyObject *u;
        9609                 :            :     Py_UCS4 maxchar;
        9610                 :            :     int kind;
        9611                 :            :     void *data;
        9612                 :            :
        9613         [ #  # ]:          0 :     if (left < 0)
        9614                 :          0 :         left = 0;
        9615         [ #  # ]:          0 :     if (right < 0)
        9616                 :          0 :         right = 0;
        9617                 :            :
        9618   [ #  #  #  # ]:          0 :     if (left == 0 && right == 0)
        9619                 :          0 :         return unicode_result_unchanged(self);
        9620                 :            :
        9621         [ #  # ]:          0 :     if (left > PY_SSIZE_T_MAX - _PyUnicode_LENGTH(self) ||
        9622         [ #  # ]:          0 :         right > PY_SSIZE_T_MAX - (left + _PyUnicode_LENGTH(self))) {
        9623                 :          0 :         PyErr_SetString(PyExc_OverflowError, "padded string is too long");
        9624                 :          0 :         return NULL;
        9625                 :            :     }
        9626                 :          0 :     maxchar = PyUnicode_MAX_CHAR_VALUE(self);
        9627                 :          0 :     maxchar = Py_MAX(maxchar, fill);
        9628                 :          0 :     u = PyUnicode_New(left + _PyUnicode_LENGTH(self) + right, maxchar);
        9629         [ #  # ]:          0 :     if (!u)
        9630                 :          0 :         return NULL;
        9631                 :            :
        9632                 :          0 :     kind = PyUnicode_KIND(u);
        9633                 :          0 :     data = PyUnicode_DATA(u);
        9634         [ #  # ]:          0 :     if (left)
        9635                 :          0 :         unicode_fill(kind, data, fill, 0, left);
        9636         [ #  # ]:          0 :     if (right)
        9637                 :          0 :         unicode_fill(kind, data, fill, left + _PyUnicode_LENGTH(self), right);
        9638                 :          0 :     _PyUnicode_FastCopyCharacters(u, left, self, 0, _PyUnicode_LENGTH(self));
        9639                 :            :     assert(_PyUnicode_CheckConsistency(u, 1));
        9640                 :          0 :     return u;
        9641                 :            : }
        9642                 :            :
        9643                 :            : PyObject *
        9644                 :        108 : PyUnicode_Splitlines(PyObject *string, int keepends)
        9645                 :            : {
        9646                 :            :     PyObject *list;
        9647                 :            :
        9648         [ -  + ]:        108 :     if (ensure_unicode(string) < 0)
        9649                 :          0 :         return NULL;
        9650                 :            :
        9651   [ +  -  -  - ]:        108 :     switch (PyUnicode_KIND(string)) {
        9652                 :        108 :     case PyUnicode_1BYTE_KIND:
        9653         [ +  - ]:        108 :         if (PyUnicode_IS_ASCII(string))
        9654                 :        216 :             list = asciilib_splitlines(
        9655                 :        108 :                 string, PyUnicode_1BYTE_DATA(string),
        9656                 :            :                 PyUnicode_GET_LENGTH(string), keepends);
        9657                 :            :         else
        9658                 :          0 :             list = ucs1lib_splitlines(
        9659                 :          0 :                 string, PyUnicode_1BYTE_DATA(string),
        9660                 :            :                 PyUnicode_GET_LENGTH(string), keepends);
        9661                 :        108 :         break;
        9662                 :          0 :     case PyUnicode_2BYTE_KIND:
        9663                 :          0 :         list = ucs2lib_splitlines(
        9664                 :          0 :             string, PyUnicode_2BYTE_DATA(string),
        9665                 :            :             PyUnicode_GET_LENGTH(string), keepends);
        9666                 :          0 :         break;
        9667                 :          0 :     case PyUnicode_4BYTE_KIND:
        9668                 :          0 :         list = ucs4lib_splitlines(
        9669                 :          0 :             string, PyUnicode_4BYTE_DATA(string),
        9670                 :            :             PyUnicode_GET_LENGTH(string), keepends);
        9671                 :          0 :         break;
        9672                 :          0 :     default:
        9673                 :          0 :         Py_UNREACHABLE();
        9674                 :            :     }
        9675                 :        108 :     return list;
        9676                 :            : }
        9677                 :            :
        9678                 :            : static PyObject *
        9679                 :       8074 : split(PyObject *self,
        9680                 :            :       PyObject *substring,
        9681                 :            :       Py_ssize_t maxcount)
        9682                 :            : {
        9683                 :            :     int kind1, kind2;
        9684                 :            :     const void *buf1, *buf2;
        9685                 :            :     Py_ssize_t len1, len2;
        9686                 :            :     PyObject* out;
        9687                 :       8074 :     len1 = PyUnicode_GET_LENGTH(self);
        9688                 :       8074 :     kind1 = PyUnicode_KIND(self);
        9689                 :            :
        9690         [ +  + ]:       8074 :     if (substring == NULL) {
        9691         [ +  + ]:       5258 :         if (maxcount < 0) {
        9692                 :       5257 :             maxcount = (len1 - 1) / 2 + 1;
        9693                 :            :         }
        9694   [ +  -  -  - ]:       5258 :         switch (kind1) {
        9695                 :       5258 :         case PyUnicode_1BYTE_KIND:
        9696         [ +  - ]:       5258 :             if (PyUnicode_IS_ASCII(self))
        9697                 :       5258 :                 return asciilib_split_whitespace(
        9698                 :       5258 :                     self,  PyUnicode_1BYTE_DATA(self),
        9699                 :            :                     len1, maxcount
        9700                 :            :                     );
        9701                 :            :             else
        9702                 :          0 :                 return ucs1lib_split_whitespace(
        9703                 :          0 :                     self,  PyUnicode_1BYTE_DATA(self),
        9704                 :            :                     len1, maxcount
        9705                 :            :                     );
        9706                 :          0 :         case PyUnicode_2BYTE_KIND:
        9707                 :          0 :             return ucs2lib_split_whitespace(
        9708                 :          0 :                 self,  PyUnicode_2BYTE_DATA(self),
        9709                 :            :                 len1, maxcount
        9710                 :            :                 );
        9711                 :          0 :         case PyUnicode_4BYTE_KIND:
        9712                 :          0 :             return ucs4lib_split_whitespace(
        9713                 :          0 :                 self,  PyUnicode_4BYTE_DATA(self),
        9714                 :            :                 len1, maxcount
        9715                 :            :                 );
        9716                 :          0 :         default:
        9717                 :          0 :             Py_UNREACHABLE();
        9718                 :            :         }
        9719                 :            :     }
        9720                 :            :
        9721                 :       2816 :     kind2 = PyUnicode_KIND(substring);
        9722                 :       2816 :     len2 = PyUnicode_GET_LENGTH(substring);
        9723         [ +  - ]:       2816 :     if (maxcount < 0) {
        9724                 :            :         // if len2 == 0, it will raise ValueError.
        9725         [ +  - ]:       2816 :         maxcount = len2 == 0 ? 0 : (len1 / len2) + 1;
        9726                 :            :         // handle expected overflow case: (Py_SSIZE_T_MAX / 1) + 1
        9727         [ -  + ]:       2816 :         maxcount = maxcount < 0 ? len1 : maxcount;
        9728                 :            :     }
        9729   [ +  -  +  + ]:       2816 :     if (kind1 < kind2 || len1 < len2) {
        9730                 :          9 :         out = PyList_New(1);
        9731         [ -  + ]:          9 :         if (out == NULL)
        9732                 :          0 :             return NULL;
        9733                 :          9 :         PyList_SET_ITEM(out, 0, Py_NewRef(self));
        9734                 :          9 :         return out;
        9735                 :            :     }
        9736                 :       2807 :     buf1 = PyUnicode_DATA(self);
        9737                 :       2807 :     buf2 = PyUnicode_DATA(substring);
        9738         [ -  + ]:       2807 :     if (kind2 != kind1) {
        9739                 :          0 :         buf2 = unicode_askind(kind2, buf2, len2, kind1);
        9740         [ #  # ]:          0 :         if (!buf2)
        9741                 :          0 :             return NULL;
        9742                 :            :     }
        9743                 :            :
        9744   [ +  -  -  - ]:       2807 :     switch (kind1) {
        9745                 :       2807 :     case PyUnicode_1BYTE_KIND:
        9746   [ +  -  +  - ]:       2807 :         if (PyUnicode_IS_ASCII(self) && PyUnicode_IS_ASCII(substring))
        9747                 :       2807 :             out = asciilib_split(
        9748                 :            :                 self,  buf1, len1, buf2, len2, maxcount);
        9749                 :            :         else
        9750                 :          0 :             out = ucs1lib_split(
        9751                 :            :                 self,  buf1, len1, buf2, len2, maxcount);
        9752                 :       2807 :         break;
        9753                 :          0 :     case PyUnicode_2BYTE_KIND:
        9754                 :          0 :         out = ucs2lib_split(
        9755                 :            :             self,  buf1, len1, buf2, len2, maxcount);
        9756                 :          0 :         break;
        9757                 :          0 :     case PyUnicode_4BYTE_KIND:
        9758                 :          0 :         out = ucs4lib_split(
        9759                 :            :             self,  buf1, len1, buf2, len2, maxcount);
        9760                 :          0 :         break;
        9761                 :          0 :     default:
        9762                 :          0 :         out = NULL;
        9763                 :            :     }
        9764                 :            :     assert((kind2 != kind1) == (buf2 != PyUnicode_DATA(substring)));
        9765         [ -  + ]:       2807 :     if (kind2 != kind1)
        9766                 :          0 :         PyMem_Free((void *)buf2);
        9767                 :       2807 :     return out;
        9768                 :            : }
        9769                 :            :
        9770                 :            : static PyObject *
        9771                 :         23 : rsplit(PyObject *self,
        9772                 :            :        PyObject *substring,
        9773                 :            :        Py_ssize_t maxcount)
        9774                 :            : {
        9775                 :            :     int kind1, kind2;
        9776                 :            :     const void *buf1, *buf2;
        9777                 :            :     Py_ssize_t len1, len2;
        9778                 :            :     PyObject* out;
        9779                 :            :
        9780                 :         23 :     len1 = PyUnicode_GET_LENGTH(self);
        9781                 :         23 :     kind1 = PyUnicode_KIND(self);
        9782                 :            :
        9783         [ -  + ]:         23 :     if (substring == NULL) {
        9784         [ #  # ]:          0 :         if (maxcount < 0) {
        9785                 :          0 :             maxcount = (len1 - 1) / 2 + 1;
        9786                 :            :         }
        9787   [ #  #  #  # ]:          0 :         switch (kind1) {
        9788                 :          0 :         case PyUnicode_1BYTE_KIND:
        9789         [ #  # ]:          0 :             if (PyUnicode_IS_ASCII(self))
        9790                 :          0 :                 return asciilib_rsplit_whitespace(
        9791                 :          0 :                     self,  PyUnicode_1BYTE_DATA(self),
        9792                 :            :                     len1, maxcount
        9793                 :            :                     );
        9794                 :            :             else
        9795                 :          0 :                 return ucs1lib_rsplit_whitespace(
        9796                 :          0 :                     self,  PyUnicode_1BYTE_DATA(self),
        9797                 :            :                     len1, maxcount
        9798                 :            :                     );
        9799                 :          0 :         case PyUnicode_2BYTE_KIND:
        9800                 :          0 :             return ucs2lib_rsplit_whitespace(
        9801                 :          0 :                 self,  PyUnicode_2BYTE_DATA(self),
        9802                 :            :                 len1, maxcount
        9803                 :            :                 );
        9804                 :          0 :         case PyUnicode_4BYTE_KIND:
        9805                 :          0 :             return ucs4lib_rsplit_whitespace(
        9806                 :          0 :                 self,  PyUnicode_4BYTE_DATA(self),
        9807                 :            :                 len1, maxcount
        9808                 :            :                 );
        9809                 :          0 :         default:
        9810                 :          0 :             Py_UNREACHABLE();
        9811                 :            :         }
        9812                 :            :     }
        9813                 :         23 :     kind2 = PyUnicode_KIND(substring);
        9814                 :         23 :     len2 = PyUnicode_GET_LENGTH(substring);
        9815         [ -  + ]:         23 :     if (maxcount < 0) {
        9816                 :            :         // if len2 == 0, it will raise ValueError.
        9817         [ #  # ]:          0 :         maxcount = len2 == 0 ? 0 : (len1 / len2) + 1;
        9818                 :            :         // handle expected overflow case: (Py_SSIZE_T_MAX / 1) + 1
        9819         [ #  # ]:          0 :         maxcount = maxcount < 0 ? len1 : maxcount;
        9820                 :            :     }
        9821   [ +  -  -  + ]:         23 :     if (kind1 < kind2 || len1 < len2) {
        9822                 :          0 :         out = PyList_New(1);
        9823         [ #  # ]:          0 :         if (out == NULL)
        9824                 :          0 :             return NULL;
        9825                 :          0 :         PyList_SET_ITEM(out, 0, Py_NewRef(self));
        9826                 :          0 :         return out;
        9827                 :            :     }
        9828                 :         23 :     buf1 = PyUnicode_DATA(self);
        9829                 :         23 :     buf2 = PyUnicode_DATA(substring);
        9830         [ -  + ]:         23 :     if (kind2 != kind1) {
        9831                 :          0 :         buf2 = unicode_askind(kind2, buf2, len2, kind1);
        9832         [ #  # ]:          0 :         if (!buf2)
        9833                 :          0 :             return NULL;
        9834                 :            :     }
        9835                 :            :
        9836   [ +  -  -  - ]:         23 :     switch (kind1) {
        9837                 :         23 :     case PyUnicode_1BYTE_KIND:
        9838   [ +  -  +  - ]:         23 :         if (PyUnicode_IS_ASCII(self) && PyUnicode_IS_ASCII(substring))
        9839                 :         23 :             out = asciilib_rsplit(
        9840                 :            :                 self,  buf1, len1, buf2, len2, maxcount);
        9841                 :            :         else
        9842                 :          0 :             out = ucs1lib_rsplit(
        9843                 :            :                 self,  buf1, len1, buf2, len2, maxcount);
        9844                 :         23 :         break;
        9845                 :          0 :     case PyUnicode_2BYTE_KIND:
        9846                 :          0 :         out = ucs2lib_rsplit(
        9847                 :            :             self,  buf1, len1, buf2, len2, maxcount);
        9848                 :          0 :         break;
        9849                 :          0 :     case PyUnicode_4BYTE_KIND:
        9850                 :          0 :         out = ucs4lib_rsplit(
        9851                 :            :             self,  buf1, len1, buf2, len2, maxcount);
        9852                 :          0 :         break;
        9853                 :          0 :     default:
        9854                 :          0 :         out = NULL;
        9855                 :            :     }
        9856                 :            :     assert((kind2 != kind1) == (buf2 != PyUnicode_DATA(substring)));
        9857         [ -  + ]:         23 :     if (kind2 != kind1)
        9858                 :          0 :         PyMem_Free((void *)buf2);
        9859                 :         23 :     return out;
        9860                 :            : }
        9861                 :            :
        9862                 :            : static Py_ssize_t
        9863                 :        136 : anylib_find(int kind, PyObject *str1, const void *buf1, Py_ssize_t len1,
        9864                 :            :             PyObject *str2, const void *buf2, Py_ssize_t len2, Py_ssize_t offset)
        9865                 :            : {
        9866   [ +  -  -  - ]:        136 :     switch (kind) {
        9867                 :        136 :     case PyUnicode_1BYTE_KIND:
        9868   [ +  -  +  - ]:        136 :         if (PyUnicode_IS_ASCII(str1) && PyUnicode_IS_ASCII(str2))
        9869                 :        136 :             return asciilib_find(buf1, len1, buf2, len2, offset);
        9870                 :            :         else
        9871                 :          0 :             return ucs1lib_find(buf1, len1, buf2, len2, offset);
        9872                 :          0 :     case PyUnicode_2BYTE_KIND:
        9873                 :          0 :         return ucs2lib_find(buf1, len1, buf2, len2, offset);
        9874                 :          0 :     case PyUnicode_4BYTE_KIND:
        9875                 :          0 :         return ucs4lib_find(buf1, len1, buf2, len2, offset);
        9876                 :            :     }
        9877                 :          0 :     Py_UNREACHABLE();
        9878                 :            : }
        9879                 :            :
        9880                 :            : static Py_ssize_t
        9881                 :       5256 : anylib_count(int kind, PyObject *sstr, const void* sbuf, Py_ssize_t slen,
        9882                 :            :              PyObject *str1, const void *buf1, Py_ssize_t len1, Py_ssize_t maxcount)
        9883                 :            : {
        9884   [ +  -  -  - ]:       5256 :     switch (kind) {
        9885                 :       5256 :     case PyUnicode_1BYTE_KIND:
        9886                 :       5256 :         return ucs1lib_count(sbuf, slen, buf1, len1, maxcount);
        9887                 :          0 :     case PyUnicode_2BYTE_KIND:
        9888                 :          0 :         return ucs2lib_count(sbuf, slen, buf1, len1, maxcount);
        9889                 :          0 :     case PyUnicode_4BYTE_KIND:
        9890                 :          0 :         return ucs4lib_count(sbuf, slen, buf1, len1, maxcount);
        9891                 :            :     }
        9892                 :          0 :     Py_UNREACHABLE();
        9893                 :            : }
        9894                 :            :
        9895                 :            : static void
        9896                 :         98 : replace_1char_inplace(PyObject *u, Py_ssize_t pos,
        9897                 :            :                       Py_UCS4 u1, Py_UCS4 u2, Py_ssize_t maxcount)
        9898                 :            : {
        9899                 :         98 :     int kind = PyUnicode_KIND(u);
        9900                 :         98 :     void *data = PyUnicode_DATA(u);
        9901                 :         98 :     Py_ssize_t len = PyUnicode_GET_LENGTH(u);
        9902         [ +  - ]:         98 :     if (kind == PyUnicode_1BYTE_KIND) {
        9903                 :         98 :         ucs1lib_replace_1char_inplace((Py_UCS1 *)data + pos,
        9904                 :            :                                       (Py_UCS1 *)data + len,
        9905                 :            :                                       u1, u2, maxcount);
        9906                 :            :     }
        9907         [ #  # ]:          0 :     else if (kind == PyUnicode_2BYTE_KIND) {
        9908                 :          0 :         ucs2lib_replace_1char_inplace((Py_UCS2 *)data + pos,
        9909                 :          0 :                                       (Py_UCS2 *)data + len,
        9910                 :            :                                       u1, u2, maxcount);
        9911                 :            :     }
        9912                 :            :     else {
        9913                 :            :         assert(kind == PyUnicode_4BYTE_KIND);
        9914                 :          0 :         ucs4lib_replace_1char_inplace((Py_UCS4 *)data + pos,
        9915                 :          0 :                                       (Py_UCS4 *)data + len,
        9916                 :            :                                       u1, u2, maxcount);
        9917                 :            :     }
        9918                 :         98 : }
        9919                 :            :
        9920                 :            : static PyObject *
        9921                 :       5728 : replace(PyObject *self, PyObject *str1,
        9922                 :            :         PyObject *str2, Py_ssize_t maxcount)
        9923                 :            : {
        9924                 :            :     PyObject *u;
        9925                 :       5728 :     const char *sbuf = PyUnicode_DATA(self);
        9926                 :       5728 :     const void *buf1 = PyUnicode_DATA(str1);
        9927                 :       5728 :     const void *buf2 = PyUnicode_DATA(str2);
        9928                 :       5728 :     int srelease = 0, release1 = 0, release2 = 0;
        9929                 :       5728 :     int skind = PyUnicode_KIND(self);
        9930                 :       5728 :     int kind1 = PyUnicode_KIND(str1);
        9931                 :       5728 :     int kind2 = PyUnicode_KIND(str2);
        9932                 :       5728 :     Py_ssize_t slen = PyUnicode_GET_LENGTH(self);
        9933                 :       5728 :     Py_ssize_t len1 = PyUnicode_GET_LENGTH(str1);
        9934                 :       5728 :     Py_ssize_t len2 = PyUnicode_GET_LENGTH(str2);
        9935                 :            :     int mayshrink;
        9936                 :            :     Py_UCS4 maxchar, maxchar_str1, maxchar_str2;
        9937                 :            :
        9938         [ +  + ]:       5728 :     if (slen < len1)
        9939                 :        166 :         goto nothing;
        9940                 :            :
        9941         [ +  - ]:       5562 :     if (maxcount < 0)
        9942                 :       5562 :         maxcount = PY_SSIZE_T_MAX;
        9943         [ #  # ]:          0 :     else if (maxcount == 0)
        9944                 :          0 :         goto nothing;
        9945                 :            :
        9946         [ -  + ]:       5562 :     if (str1 == str2)
        9947                 :          0 :         goto nothing;
        9948                 :            :
        9949                 :       5562 :     maxchar = PyUnicode_MAX_CHAR_VALUE(self);
        9950                 :       5562 :     maxchar_str1 = PyUnicode_MAX_CHAR_VALUE(str1);
        9951         [ -  + ]:       5562 :     if (maxchar < maxchar_str1)
        9952                 :            :         /* substring too wide to be present */
        9953                 :          0 :         goto nothing;
        9954                 :       5562 :     maxchar_str2 = PyUnicode_MAX_CHAR_VALUE(str2);
        9955                 :            :     /* Replacing str1 with str2 may cause a maxchar reduction in the
        9956                 :            :        result string. */
        9957   [ -  +  -  - ]:       5562 :     mayshrink = (maxchar_str2 < maxchar_str1) && (maxchar == maxchar_str1);
        9958                 :       5562 :     maxchar = Py_MAX(maxchar, maxchar_str2);
        9959                 :            :
        9960         [ +  + ]:       5562 :     if (len1 == len2) {
        9961                 :            :         /* same length */
        9962         [ -  + ]:        306 :         if (len1 == 0)
        9963                 :          0 :             goto nothing;
        9964         [ +  - ]:        306 :         if (len1 == 1) {
        9965                 :            :             /* replace characters */
        9966                 :            :             Py_UCS4 u1, u2;
        9967                 :            :             Py_ssize_t pos;
        9968                 :            :
        9969                 :        306 :             u1 = PyUnicode_READ(kind1, buf1, 0);
        9970                 :        306 :             pos = findchar(sbuf, skind, slen, u1, 1);
        9971         [ +  + ]:        306 :             if (pos < 0)
        9972                 :        208 :                 goto nothing;
        9973                 :         98 :             u2 = PyUnicode_READ(kind2, buf2, 0);
        9974                 :         98 :             u = PyUnicode_New(slen, maxchar);
        9975         [ -  + ]:         98 :             if (!u)
        9976                 :          0 :                 goto error;
        9977                 :            :
        9978                 :         98 :             _PyUnicode_FastCopyCharacters(u, 0, self, 0, slen);
        9979                 :         98 :             replace_1char_inplace(u, pos, u1, u2, maxcount);
        9980                 :            :         }
        9981                 :            :         else {
        9982                 :          0 :             int rkind = skind;
        9983                 :            :             char *res;
        9984                 :            :             Py_ssize_t i;
        9985                 :            :
        9986         [ #  # ]:          0 :             if (kind1 < rkind) {
        9987                 :            :                 /* widen substring */
        9988                 :          0 :                 buf1 = unicode_askind(kind1, buf1, len1, rkind);
        9989         [ #  # ]:          0 :                 if (!buf1) goto error;
        9990                 :          0 :                 release1 = 1;
        9991                 :            :             }
        9992                 :          0 :             i = anylib_find(rkind, self, sbuf, slen, str1, buf1, len1, 0);
        9993         [ #  # ]:          0 :             if (i < 0)
        9994                 :          0 :                 goto nothing;
        9995         [ #  # ]:          0 :             if (rkind > kind2) {
        9996                 :            :                 /* widen replacement */
        9997                 :          0 :                 buf2 = unicode_askind(kind2, buf2, len2, rkind);
        9998         [ #  # ]:          0 :                 if (!buf2) goto error;
        9999                 :          0 :                 release2 = 1;
       10000                 :            :             }
       10001         [ #  # ]:          0 :             else if (rkind < kind2) {
       10002                 :            :                 /* widen self and buf1 */
       10003                 :          0 :                 rkind = kind2;
       10004         [ #  # ]:          0 :                 if (release1) {
       10005                 :            :                     assert(buf1 != PyUnicode_DATA(str1));
       10006                 :          0 :                     PyMem_Free((void *)buf1);
       10007                 :          0 :                     buf1 = PyUnicode_DATA(str1);
       10008                 :          0 :                     release1 = 0;
       10009                 :            :                 }
       10010                 :          0 :                 sbuf = unicode_askind(skind, sbuf, slen, rkind);
       10011         [ #  # ]:          0 :                 if (!sbuf) goto error;
       10012                 :          0 :                 srelease = 1;
       10013                 :          0 :                 buf1 = unicode_askind(kind1, buf1, len1, rkind);
       10014         [ #  # ]:          0 :                 if (!buf1) goto error;
       10015                 :          0 :                 release1 = 1;
       10016                 :            :             }
       10017                 :          0 :             u = PyUnicode_New(slen, maxchar);
       10018         [ #  # ]:          0 :             if (!u)
       10019                 :          0 :                 goto error;
       10020                 :            :             assert(PyUnicode_KIND(u) == rkind);
       10021                 :          0 :             res = PyUnicode_DATA(u);
       10022                 :            :
       10023                 :          0 :             memcpy(res, sbuf, rkind * slen);
       10024                 :            :             /* change everything in-place, starting with this one */
       10025                 :          0 :             memcpy(res + rkind * i,
       10026                 :            :                    buf2,
       10027                 :          0 :                    rkind * len2);
       10028                 :          0 :             i += len1;
       10029                 :            :
       10030         [ #  # ]:          0 :             while ( --maxcount > 0) {
       10031                 :          0 :                 i = anylib_find(rkind, self,
       10032                 :          0 :                                 sbuf+rkind*i, slen-i,
       10033                 :            :                                 str1, buf1, len1, i);
       10034         [ #  # ]:          0 :                 if (i == -1)
       10035                 :          0 :                     break;
       10036                 :          0 :                 memcpy(res + rkind * i,
       10037                 :            :                        buf2,
       10038                 :          0 :                        rkind * len2);
       10039                 :          0 :                 i += len1;
       10040                 :            :             }
       10041                 :            :         }
       10042                 :            :     }
       10043                 :            :     else {
       10044                 :            :         Py_ssize_t n, i, j, ires;
       10045                 :            :         Py_ssize_t new_size;
       10046                 :       5256 :         int rkind = skind;
       10047                 :            :         char *res;
       10048                 :            :
       10049         [ -  + ]:       5256 :         if (kind1 < rkind) {
       10050                 :            :             /* widen substring */
       10051                 :          0 :             buf1 = unicode_askind(kind1, buf1, len1, rkind);
       10052         [ #  # ]:          0 :             if (!buf1) goto error;
       10053                 :          0 :             release1 = 1;
       10054                 :            :         }
       10055                 :       5256 :         n = anylib_count(rkind, self, sbuf, slen, str1, buf1, len1, maxcount);
       10056         [ +  + ]:       5256 :         if (n == 0)
       10057                 :       5153 :             goto nothing;
       10058         [ -  + ]:        103 :         if (kind2 < rkind) {
       10059                 :            :             /* widen replacement */
       10060                 :          0 :             buf2 = unicode_askind(kind2, buf2, len2, rkind);
       10061         [ #  # ]:          0 :             if (!buf2) goto error;
       10062                 :          0 :             release2 = 1;
       10063                 :            :         }
       10064         [ -  + ]:        103 :         else if (kind2 > rkind) {
       10065                 :            :             /* widen self and buf1 */
       10066                 :          0 :             rkind = kind2;
       10067                 :          0 :             sbuf = unicode_askind(skind, sbuf, slen, rkind);
       10068         [ #  # ]:          0 :             if (!sbuf) goto error;
       10069                 :          0 :             srelease = 1;
       10070         [ #  # ]:          0 :             if (release1) {
       10071                 :            :                 assert(buf1 != PyUnicode_DATA(str1));
       10072                 :          0 :                 PyMem_Free((void *)buf1);
       10073                 :          0 :                 buf1 = PyUnicode_DATA(str1);
       10074                 :          0 :                 release1 = 0;
       10075                 :            :             }
       10076                 :          0 :             buf1 = unicode_askind(kind1, buf1, len1, rkind);
       10077         [ #  # ]:          0 :             if (!buf1) goto error;
       10078                 :          0 :             release1 = 1;
       10079                 :            :         }
       10080                 :            :         /* new_size = PyUnicode_GET_LENGTH(self) + n * (PyUnicode_GET_LENGTH(str2) -
       10081                 :            :            PyUnicode_GET_LENGTH(str1)); */
       10082   [ +  +  -  + ]:        103 :         if (len1 < len2 && len2 - len1 > (PY_SSIZE_T_MAX - slen) / n) {
       10083                 :          0 :                 PyErr_SetString(PyExc_OverflowError,
       10084                 :            :                                 "replace string is too long");
       10085                 :          0 :                 goto error;
       10086                 :            :         }
       10087                 :        103 :         new_size = slen + n * (len2 - len1);
       10088         [ -  + ]:        103 :         if (new_size == 0) {
       10089                 :          0 :             u = unicode_new_empty();
       10090                 :          0 :             goto done;
       10091                 :            :         }
       10092         [ -  + ]:        103 :         if (new_size > (PY_SSIZE_T_MAX / rkind)) {
       10093                 :          0 :             PyErr_SetString(PyExc_OverflowError,
       10094                 :            :                             "replace string is too long");
       10095                 :          0 :             goto error;
       10096                 :            :         }
       10097                 :        103 :         u = PyUnicode_New(new_size, maxchar);
       10098         [ -  + ]:        103 :         if (!u)
       10099                 :          0 :             goto error;
       10100                 :            :         assert(PyUnicode_KIND(u) == rkind);
       10101                 :        103 :         res = PyUnicode_DATA(u);
       10102                 :        103 :         ires = i = 0;
       10103         [ +  - ]:        103 :         if (len1 > 0) {
       10104         [ +  + ]:        239 :             while (n-- > 0) {
       10105                 :            :                 /* look for next match */
       10106                 :        136 :                 j = anylib_find(rkind, self,
       10107                 :        136 :                                 sbuf + rkind * i, slen-i,
       10108                 :            :                                 str1, buf1, len1, i);
       10109         [ -  + ]:        136 :                 if (j == -1)
       10110                 :          0 :                     break;
       10111         [ +  + ]:        136 :                 else if (j > i) {
       10112                 :            :                     /* copy unchanged part [i:j] */
       10113                 :        112 :                     memcpy(res + rkind * ires,
       10114                 :        112 :                            sbuf + rkind * i,
       10115                 :        112 :                            rkind * (j-i));
       10116                 :        112 :                     ires += j - i;
       10117                 :            :                 }
       10118                 :            :                 /* copy substitution string */
       10119         [ +  + ]:        136 :                 if (len2 > 0) {
       10120                 :         62 :                     memcpy(res + rkind * ires,
       10121                 :            :                            buf2,
       10122                 :         62 :                            rkind * len2);
       10123                 :         62 :                     ires += len2;
       10124                 :            :                 }
       10125                 :        136 :                 i = j + len1;
       10126                 :            :             }
       10127         [ +  + ]:        103 :             if (i < slen)
       10128                 :            :                 /* copy tail [i:] */
       10129                 :         87 :                 memcpy(res + rkind * ires,
       10130                 :         87 :                        sbuf + rkind * i,
       10131                 :         87 :                        rkind * (slen-i));
       10132                 :            :         }
       10133                 :            :         else {
       10134                 :            :             /* interleave */
       10135         [ #  # ]:          0 :             while (n > 0) {
       10136                 :          0 :                 memcpy(res + rkind * ires,
       10137                 :            :                        buf2,
       10138                 :          0 :                        rkind * len2);
       10139                 :          0 :                 ires += len2;
       10140         [ #  # ]:          0 :                 if (--n <= 0)
       10141                 :          0 :                     break;
       10142                 :          0 :                 memcpy(res + rkind * ires,
       10143                 :          0 :                        sbuf + rkind * i,
       10144                 :            :                        rkind);
       10145                 :          0 :                 ires++;
       10146                 :          0 :                 i++;
       10147                 :            :             }
       10148                 :          0 :             memcpy(res + rkind * ires,
       10149                 :          0 :                    sbuf + rkind * i,
       10150                 :          0 :                    rkind * (slen-i));
       10151                 :            :         }
       10152                 :            :     }
       10153                 :            :
       10154         [ -  + ]:        201 :     if (mayshrink) {
       10155                 :          0 :         unicode_adjust_maxchar(&u);
       10156         [ #  # ]:          0 :         if (u == NULL)
       10157                 :          0 :             goto error;
       10158                 :            :     }
       10159                 :            :
       10160                 :        201 :   done:
       10161                 :            :     assert(srelease == (sbuf != PyUnicode_DATA(self)));
       10162                 :            :     assert(release1 == (buf1 != PyUnicode_DATA(str1)));
       10163                 :            :     assert(release2 == (buf2 != PyUnicode_DATA(str2)));
       10164         [ -  + ]:        201 :     if (srelease)
       10165                 :          0 :         PyMem_Free((void *)sbuf);
       10166         [ -  + ]:        201 :     if (release1)
       10167                 :          0 :         PyMem_Free((void *)buf1);
       10168         [ -  + ]:        201 :     if (release2)
       10169                 :          0 :         PyMem_Free((void *)buf2);
       10170                 :            :     assert(_PyUnicode_CheckConsistency(u, 1));
       10171                 :        201 :     return u;
       10172                 :            :
       10173                 :       5527 :   nothing:
       10174                 :            :     /* nothing to replace; return original string (when possible) */
       10175                 :            :     assert(srelease == (sbuf != PyUnicode_DATA(self)));
       10176                 :            :     assert(release1 == (buf1 != PyUnicode_DATA(str1)));
       10177                 :            :     assert(release2 == (buf2 != PyUnicode_DATA(str2)));
       10178         [ -  + ]:       5527 :     if (srelease)
       10179                 :          0 :         PyMem_Free((void *)sbuf);
       10180         [ -  + ]:       5527 :     if (release1)
       10181                 :          0 :         PyMem_Free((void *)buf1);
       10182         [ -  + ]:       5527 :     if (release2)
       10183                 :          0 :         PyMem_Free((void *)buf2);
       10184                 :       5527 :     return unicode_result_unchanged(self);
       10185                 :            :
       10186                 :          0 :   error:
       10187                 :            :     assert(srelease == (sbuf != PyUnicode_DATA(self)));
       10188                 :            :     assert(release1 == (buf1 != PyUnicode_DATA(str1)));
       10189                 :            :     assert(release2 == (buf2 != PyUnicode_DATA(str2)));
       10190         [ #  # ]:          0 :     if (srelease)
       10191                 :          0 :         PyMem_Free((void *)sbuf);
       10192         [ #  # ]:          0 :     if (release1)
       10193                 :          0 :         PyMem_Free((void *)buf1);
       10194         [ #  # ]:          0 :     if (release2)
       10195                 :          0 :         PyMem_Free((void *)buf2);
       10196                 :          0 :     return NULL;
       10197                 :            : }
       10198                 :            :
       10199                 :            : /* --- Unicode Object Methods --------------------------------------------- */
       10200                 :            :
       10201                 :            : /*[clinic input]
       10202                 :            : str.title as unicode_title
       10203                 :            :
       10204                 :            : Return a version of the string where each word is titlecased.
       10205                 :            :
       10206                 :            : More specifically, words start with uppercased characters and all remaining
       10207                 :            : cased characters have lower case.
       10208                 :            : [clinic start generated code]*/
       10209                 :            :
       10210                 :            : static PyObject *
       10211                 :          0 : unicode_title_impl(PyObject *self)
       10212                 :            : /*[clinic end generated code: output=c75ae03809574902 input=fa945d669b26e683]*/
       10213                 :            : {
       10214                 :          0 :     return case_operation(self, do_title);
       10215                 :            : }
       10216                 :            :
       10217                 :            : /*[clinic input]
       10218                 :            : str.capitalize as unicode_capitalize
       10219                 :            :
       10220                 :            : Return a capitalized version of the string.
       10221                 :            :
       10222                 :            : More specifically, make the first character have upper case and the rest lower
       10223                 :            : case.
       10224                 :            : [clinic start generated code]*/
       10225                 :            :
       10226                 :            : static PyObject *
       10227                 :          0 : unicode_capitalize_impl(PyObject *self)
       10228                 :            : /*[clinic end generated code: output=e49a4c333cdb7667 input=f4cbf1016938da6d]*/
       10229                 :            : {
       10230         [ #  # ]:          0 :     if (PyUnicode_GET_LENGTH(self) == 0)
       10231                 :          0 :         return unicode_result_unchanged(self);
       10232                 :          0 :     return case_operation(self, do_capitalize);
       10233                 :            : }
       10234                 :            :
       10235                 :            : /*[clinic input]
       10236                 :            : str.casefold as unicode_casefold
       10237                 :            :
       10238                 :            : Return a version of the string suitable for caseless comparisons.
       10239                 :            : [clinic start generated code]*/
       10240                 :            :
       10241                 :            : static PyObject *
       10242                 :          0 : unicode_casefold_impl(PyObject *self)
       10243                 :            : /*[clinic end generated code: output=0120daf657ca40af input=384d66cc2ae30daf]*/
       10244                 :            : {
       10245         [ #  # ]:          0 :     if (PyUnicode_IS_ASCII(self))
       10246                 :          0 :         return ascii_upper_or_lower(self, 1);
       10247                 :          0 :     return case_operation(self, do_casefold);
       10248                 :            : }
       10249                 :            :
       10250                 :            :
       10251                 :            : /* Argument converter. Accepts a single Unicode character. */
       10252                 :            :
       10253                 :            : static int
       10254                 :          0 : convert_uc(PyObject *obj, void *addr)
       10255                 :            : {
       10256                 :          0 :     Py_UCS4 *fillcharloc = (Py_UCS4 *)addr;
       10257                 :            :
       10258         [ #  # ]:          0 :     if (!PyUnicode_Check(obj)) {
       10259                 :          0 :         PyErr_Format(PyExc_TypeError,
       10260                 :            :                      "The fill character must be a unicode character, "
       10261                 :          0 :                      "not %.100s", Py_TYPE(obj)->tp_name);
       10262                 :          0 :         return 0;
       10263                 :            :     }
       10264         [ #  # ]:          0 :     if (PyUnicode_GET_LENGTH(obj) != 1) {
       10265                 :          0 :         PyErr_SetString(PyExc_TypeError,
       10266                 :            :                         "The fill character must be exactly one character long");
       10267                 :          0 :         return 0;
       10268                 :            :     }
       10269                 :          0 :     *fillcharloc = PyUnicode_READ_CHAR(obj, 0);
       10270                 :          0 :     return 1;
       10271                 :            : }
       10272                 :            :
       10273                 :            : /*[clinic input]
       10274                 :            : str.center as unicode_center
       10275                 :            :
       10276                 :            :     width: Py_ssize_t
       10277                 :            :     fillchar: Py_UCS4 = ' '
       10278                 :            :     /
       10279                 :            :
       10280                 :            : Return a centered string of length width.
       10281                 :            :
       10282                 :            : Padding is done using the specified fill character (default is a space).
       10283                 :            : [clinic start generated code]*/
       10284                 :            :
       10285                 :            : static PyObject *
       10286                 :          0 : unicode_center_impl(PyObject *self, Py_ssize_t width, Py_UCS4 fillchar)
       10287                 :            : /*[clinic end generated code: output=420c8859effc7c0c input=b42b247eb26e6519]*/
       10288                 :            : {
       10289                 :            :     Py_ssize_t marg, left;
       10290                 :            :
       10291         [ #  # ]:          0 :     if (PyUnicode_GET_LENGTH(self) >= width)
       10292                 :          0 :         return unicode_result_unchanged(self);
       10293                 :            :
       10294                 :          0 :     marg = width - PyUnicode_GET_LENGTH(self);
       10295                 :          0 :     left = marg / 2 + (marg & width & 1);
       10296                 :            :
       10297                 :          0 :     return pad(self, left, marg - left, fillchar);
       10298                 :            : }
       10299                 :            :
       10300                 :            : /* This function assumes that str1 and str2 are readied by the caller. */
       10301                 :            :
       10302                 :            : static int
       10303                 :     122324 : unicode_compare(PyObject *str1, PyObject *str2)
       10304                 :            : {
       10305                 :            : #define COMPARE(TYPE1, TYPE2) \
       10306                 :            :     do { \
       10307                 :            :         TYPE1* p1 = (TYPE1 *)data1; \
       10308                 :            :         TYPE2* p2 = (TYPE2 *)data2; \
       10309                 :            :         TYPE1* end = p1 + len; \
       10310                 :            :         Py_UCS4 c1, c2; \
       10311                 :            :         for (; p1 != end; p1++, p2++) { \
       10312                 :            :             c1 = *p1; \
       10313                 :            :             c2 = *p2; \
       10314                 :            :             if (c1 != c2) \
       10315                 :            :                 return (c1 < c2) ? -1 : 1; \
       10316                 :            :         } \
       10317                 :            :     } \
       10318                 :            :     while (0)
       10319                 :            :
       10320                 :            :     int kind1, kind2;
       10321                 :            :     const void *data1, *data2;
       10322                 :            :     Py_ssize_t len1, len2, len;
       10323                 :            :
       10324                 :     122324 :     kind1 = PyUnicode_KIND(str1);
       10325                 :     122324 :     kind2 = PyUnicode_KIND(str2);
       10326                 :     122324 :     data1 = PyUnicode_DATA(str1);
       10327                 :     122324 :     data2 = PyUnicode_DATA(str2);
       10328                 :     122324 :     len1 = PyUnicode_GET_LENGTH(str1);
       10329                 :     122324 :     len2 = PyUnicode_GET_LENGTH(str2);
       10330                 :     122324 :     len = Py_MIN(len1, len2);
       10331                 :            :
       10332   [ +  +  +  - ]:     122324 :     switch(kind1) {
       10333   [ +  +  -  - ]:     122235 :     case PyUnicode_1BYTE_KIND:
       10334                 :            :     {
       10335                 :            :         switch(kind2) {
       10336                 :     121369 :         case PyUnicode_1BYTE_KIND:
       10337                 :            :         {
       10338                 :     121369 :             int cmp = memcmp(data1, data2, len);
       10339                 :            :             /* normalize result of memcmp() into the range [-1; 1] */
       10340         [ +  + ]:     121369 :             if (cmp < 0)
       10341                 :     106569 :                 return -1;
       10342         [ +  + ]:      14800 :             if (cmp > 0)
       10343                 :      14205 :                 return 1;
       10344                 :        595 :             break;
       10345                 :            :         }
       10346                 :        866 :         case PyUnicode_2BYTE_KIND:
       10347   [ +  -  +  -  :        866 :             COMPARE(Py_UCS1, Py_UCS2);
                       +  - ]
       10348                 :          0 :             break;
       10349                 :          0 :         case PyUnicode_4BYTE_KIND:
       10350   [ #  #  #  #  :          0 :             COMPARE(Py_UCS1, Py_UCS4);
                       #  # ]
       10351                 :          0 :             break;
       10352                 :          0 :         default:
       10353                 :          0 :             Py_UNREACHABLE();
       10354                 :            :         }
       10355                 :        595 :         break;
       10356                 :            :     }
       10357   [ +  +  -  - ]:         86 :     case PyUnicode_2BYTE_KIND:
       10358                 :            :     {
       10359                 :            :         switch(kind2) {
       10360                 :          8 :         case PyUnicode_1BYTE_KIND:
       10361   [ +  -  -  +  :          8 :             COMPARE(Py_UCS2, Py_UCS1);
                       +  - ]
       10362                 :          0 :             break;
       10363                 :         78 :         case PyUnicode_2BYTE_KIND:
       10364                 :            :         {
       10365   [ +  -  +  +  :         78 :             COMPARE(Py_UCS2, Py_UCS2);
                       +  - ]
       10366                 :          0 :             break;
       10367                 :            :         }
       10368                 :          0 :         case PyUnicode_4BYTE_KIND:
       10369   [ #  #  #  #  :          0 :             COMPARE(Py_UCS2, Py_UCS4);
                       #  # ]
       10370                 :          0 :             break;
       10371                 :          0 :         default:
       10372                 :          0 :             Py_UNREACHABLE();
       10373                 :            :         }
       10374                 :          0 :         break;
       10375                 :            :     }
       10376   [ +  +  -  - ]:          3 :     case PyUnicode_4BYTE_KIND:
       10377                 :            :     {
       10378                 :            :         switch(kind2) {
       10379                 :          2 :         case PyUnicode_1BYTE_KIND:
       10380   [ +  -  -  +  :          2 :             COMPARE(Py_UCS4, Py_UCS1);
                       +  - ]
       10381                 :          0 :             break;
       10382                 :          1 :         case PyUnicode_2BYTE_KIND:
       10383   [ +  -  -  +  :          1 :             COMPARE(Py_UCS4, Py_UCS2);
                       +  - ]
       10384                 :          0 :             break;
       10385                 :          0 :         case PyUnicode_4BYTE_KIND:
       10386                 :            :         {
       10387                 :            : #if defined(HAVE_WMEMCMP) && SIZEOF_WCHAR_T == 4
       10388                 :          0 :             int cmp = wmemcmp((wchar_t *)data1, (wchar_t *)data2, len);
       10389                 :            :             /* normalize result of wmemcmp() into the range [-1; 1] */
       10390         [ #  # ]:          0 :             if (cmp < 0)
       10391                 :          0 :                 return -1;
       10392         [ #  # ]:          0 :             if (cmp > 0)
       10393                 :          0 :                 return 1;
       10394                 :            : #else
       10395                 :            :             COMPARE(Py_UCS4, Py_UCS4);
       10396                 :            : #endif
       10397                 :          0 :             break;
       10398                 :            :         }
       10399                 :          0 :         default:
       10400                 :          0 :             Py_UNREACHABLE();
       10401                 :            :         }
       10402                 :          0 :         break;
       10403                 :            :     }
       10404                 :          0 :     default:
       10405                 :          0 :         Py_UNREACHABLE();
       10406                 :            :     }
       10407                 :            :
       10408         [ +  + ]:        595 :     if (len1 == len2)
       10409                 :        386 :         return 0;
       10410         [ +  + ]:        209 :     if (len1 < len2)
       10411                 :         50 :         return -1;
       10412                 :            :     else
       10413                 :        159 :         return 1;
       10414                 :            :
       10415                 :            : #undef COMPARE
       10416                 :            : }
       10417                 :            :
       10418                 :            : static int
       10419                 :     134272 : unicode_compare_eq(PyObject *str1, PyObject *str2)
       10420                 :            : {
       10421                 :            :     int kind;
       10422                 :            :     const void *data1, *data2;
       10423                 :            :     Py_ssize_t len;
       10424                 :            :     int cmp;
       10425                 :            :
       10426                 :     134272 :     len = PyUnicode_GET_LENGTH(str1);
       10427         [ +  + ]:     134272 :     if (PyUnicode_GET_LENGTH(str2) != len)
       10428                 :      65734 :         return 0;
       10429                 :      68538 :     kind = PyUnicode_KIND(str1);
       10430         [ -  + ]:      68538 :     if (PyUnicode_KIND(str2) != kind)
       10431                 :          0 :         return 0;
       10432                 :      68538 :     data1 = PyUnicode_DATA(str1);
       10433                 :      68538 :     data2 = PyUnicode_DATA(str2);
       10434                 :            :
       10435                 :      68538 :     cmp = memcmp(data1, data2, len * kind);
       10436                 :      68538 :     return (cmp == 0);
       10437                 :            : }
       10438                 :            :
       10439                 :            : int
       10440                 :      55193 : _PyUnicode_Equal(PyObject *str1, PyObject *str2)
       10441                 :            : {
       10442                 :            :     assert(PyUnicode_Check(str1));
       10443                 :            :     assert(PyUnicode_Check(str2));
       10444         [ +  + ]:      55193 :     if (str1 == str2) {
       10445                 :      24134 :         return 1;
       10446                 :            :     }
       10447                 :      31059 :     return unicode_compare_eq(str1, str2);
       10448                 :            : }
       10449                 :            :
       10450                 :            :
       10451                 :            : int
       10452                 :       2807 : PyUnicode_Compare(PyObject *left, PyObject *right)
       10453                 :            : {
       10454   [ +  -  +  - ]:       2807 :     if (PyUnicode_Check(left) && PyUnicode_Check(right)) {
       10455                 :            :         /* a string is equal to itself */
       10456         [ -  + ]:       2807 :         if (left == right)
       10457                 :          0 :             return 0;
       10458                 :            :
       10459                 :       2807 :         return unicode_compare(left, right);
       10460                 :            :     }
       10461                 :          0 :     PyErr_Format(PyExc_TypeError,
       10462                 :            :                  "Can't compare %.100s and %.100s",
       10463                 :          0 :                  Py_TYPE(left)->tp_name,
       10464                 :          0 :                  Py_TYPE(right)->tp_name);
       10465                 :          0 :     return -1;
       10466                 :            : }
       10467                 :            :
       10468                 :            : int
       10469                 :        560 : PyUnicode_CompareWithASCIIString(PyObject* uni, const char* str)
       10470                 :            : {
       10471                 :            :     Py_ssize_t i;
       10472                 :            :     int kind;
       10473                 :            :     Py_UCS4 chr;
       10474                 :            :
       10475                 :            :     assert(_PyUnicode_CHECK(uni));
       10476                 :        560 :     kind = PyUnicode_KIND(uni);
       10477         [ +  - ]:        560 :     if (kind == PyUnicode_1BYTE_KIND) {
       10478                 :        560 :         const void *data = PyUnicode_1BYTE_DATA(uni);
       10479                 :        560 :         size_t len1 = (size_t)PyUnicode_GET_LENGTH(uni);
       10480                 :        560 :         size_t len, len2 = strlen(str);
       10481                 :            :         int cmp;
       10482                 :            :
       10483                 :        560 :         len = Py_MIN(len1, len2);
       10484                 :        560 :         cmp = memcmp(data, str, len);
       10485         [ +  + ]:        560 :         if (cmp != 0) {
       10486         [ +  + ]:        474 :             if (cmp < 0)
       10487                 :         82 :                 return -1;
       10488                 :            :             else
       10489                 :        392 :                 return 1;
       10490                 :            :         }
       10491         [ -  + ]:         86 :         if (len1 > len2)
       10492                 :          0 :             return 1; /* uni is longer */
       10493         [ -  + ]:         86 :         if (len1 < len2)
       10494                 :          0 :             return -1; /* str is longer */
       10495                 :         86 :         return 0;
       10496                 :            :     }
       10497                 :            :     else {
       10498                 :          0 :         const void *data = PyUnicode_DATA(uni);
       10499                 :            :         /* Compare Unicode string and source character set string */
       10500   [ #  #  #  # ]:          0 :         for (i = 0; (chr = PyUnicode_READ(kind, data, i)) && str[i]; i++)
       10501         [ #  # ]:          0 :             if (chr != (unsigned char)str[i])
       10502         [ #  # ]:          0 :                 return (chr < (unsigned char)(str[i])) ? -1 : 1;
       10503                 :            :         /* This check keeps Python strings that end in '\0' from comparing equal
       10504                 :            :          to C strings identical up to that point. */
       10505   [ #  #  #  # ]:          0 :         if (PyUnicode_GET_LENGTH(uni) != i || chr)
       10506                 :          0 :             return 1; /* uni is longer */
       10507         [ #  # ]:          0 :         if (str[i])
       10508                 :          0 :             return -1; /* str is longer */
       10509                 :          0 :         return 0;
       10510                 :            :     }
       10511                 :            : }
       10512                 :            :
       10513                 :            : int
       10514                 :     243403 : _PyUnicode_EqualToASCIIString(PyObject *unicode, const char *str)
       10515                 :            : {
       10516                 :            :     size_t len;
       10517                 :            :     assert(_PyUnicode_CHECK(unicode));
       10518                 :            :     assert(str);
       10519                 :            : #ifndef NDEBUG
       10520                 :            :     for (const char *p = str; *p; p++) {
       10521                 :            :         assert((unsigned char)*p < 128);
       10522                 :            :     }
       10523                 :            : #endif
       10524         [ -  + ]:     243403 :     if (!PyUnicode_IS_ASCII(unicode))
       10525                 :          0 :         return 0;
       10526                 :     243403 :     len = (size_t)PyUnicode_GET_LENGTH(unicode);
       10527         [ +  + ]:     259797 :     return strlen(str) == len &&
       10528         [ +  + ]:      16394 :            memcmp(PyUnicode_1BYTE_DATA(unicode), str, len) == 0;
       10529                 :            : }
       10530                 :            :
       10531                 :            : int
       10532                 :          0 : _PyUnicode_EqualToASCIIId(PyObject *left, _Py_Identifier *right)
       10533                 :            : {
       10534                 :            :     PyObject *right_uni;
       10535                 :            :
       10536                 :            :     assert(_PyUnicode_CHECK(left));
       10537                 :            :     assert(right->string);
       10538                 :            : #ifndef NDEBUG
       10539                 :            :     for (const char *p = right->string; *p; p++) {
       10540                 :            :         assert((unsigned char)*p < 128);
       10541                 :            :     }
       10542                 :            : #endif
       10543                 :            :
       10544         [ #  # ]:          0 :     if (!PyUnicode_IS_ASCII(left))
       10545                 :          0 :         return 0;
       10546                 :            :
       10547                 :          0 :     right_uni = _PyUnicode_FromId(right);       /* borrowed */
       10548         [ #  # ]:          0 :     if (right_uni == NULL) {
       10549                 :            :         /* memory error or bad data */
       10550                 :          0 :         PyErr_Clear();
       10551                 :          0 :         return _PyUnicode_EqualToASCIIString(left, right->string);
       10552                 :            :     }
       10553                 :            :
       10554         [ #  # ]:          0 :     if (left == right_uni)
       10555                 :          0 :         return 1;
       10556                 :            :
       10557         [ #  # ]:          0 :     if (PyUnicode_CHECK_INTERNED(left))
       10558                 :          0 :         return 0;
       10559                 :            :
       10560                 :            :     assert(_PyUnicode_HASH(right_uni) != -1);
       10561                 :          0 :     Py_hash_t hash = _PyUnicode_HASH(left);
       10562   [ #  #  #  # ]:          0 :     if (hash != -1 && hash != _PyUnicode_HASH(right_uni)) {
       10563                 :          0 :         return 0;
       10564                 :            :     }
       10565                 :            :
       10566                 :          0 :     return unicode_compare_eq(left, right_uni);
       10567                 :            : }
       10568                 :            :
       10569                 :            : PyObject *
       10570                 :     226968 : PyUnicode_RichCompare(PyObject *left, PyObject *right, int op)
       10571                 :            : {
       10572                 :            :     int result;
       10573                 :            :
       10574   [ +  -  +  + ]:     226968 :     if (!PyUnicode_Check(left) || !PyUnicode_Check(right))
       10575                 :       1300 :         Py_RETURN_NOTIMPLEMENTED;
       10576                 :            :
       10577         [ +  + ]:     225668 :     if (left == right) {
       10578      [ +  +  - ]:       2938 :         switch (op) {
       10579                 :        881 :         case Py_EQ:
       10580                 :            :         case Py_LE:
       10581                 :            :         case Py_GE:
       10582                 :            :             /* a string is equal to itself */
       10583                 :        881 :             Py_RETURN_TRUE;
       10584                 :       2057 :         case Py_NE:
       10585                 :            :         case Py_LT:
       10586                 :            :         case Py_GT:
       10587                 :       2057 :             Py_RETURN_FALSE;
       10588                 :          0 :         default:
       10589                 :          0 :             PyErr_BadArgument();
       10590                 :          0 :             return NULL;
       10591                 :            :         }
       10592                 :            :     }
       10593   [ +  +  +  + ]:     222730 :     else if (op == Py_EQ || op == Py_NE) {
       10594                 :     103213 :         result = unicode_compare_eq(left, right);
       10595                 :     103213 :         result ^= (op == Py_NE);
       10596                 :     103213 :         return PyBool_FromLong(result);
       10597                 :            :     }
       10598                 :            :     else {
       10599                 :     119517 :         result = unicode_compare(left, right);
       10600   [ -  -  +  +  :     119517 :         Py_RETURN_RICHCOMPARE(result, 0, op);
              +  -  -  -  -
              -  -  +  +  +
                 +  +  +  -
                          - ]
       10601                 :            :     }
       10602                 :            : }
       10603                 :            :
       10604                 :            : int
       10605                 :       4056 : _PyUnicode_EQ(PyObject *aa, PyObject *bb)
       10606                 :            : {
       10607                 :       4056 :     return unicode_eq(aa, bb);
       10608                 :            : }
       10609                 :            :
       10610                 :            : int
       10611                 :       7317 : PyUnicode_Contains(PyObject *str, PyObject *substr)
       10612                 :            : {
       10613                 :            :     int kind1, kind2;
       10614                 :            :     const void *buf1, *buf2;
       10615                 :            :     Py_ssize_t len1, len2;
       10616                 :            :     int result;
       10617                 :            :
       10618         [ -  + ]:       7317 :     if (!PyUnicode_Check(substr)) {
       10619                 :          0 :         PyErr_Format(PyExc_TypeError,
       10620                 :            :                      "'in <string>' requires string as left operand, not %.100s",
       10621                 :          0 :                      Py_TYPE(substr)->tp_name);
       10622                 :          0 :         return -1;
       10623                 :            :     }
       10624         [ -  + ]:       7317 :     if (ensure_unicode(str) < 0)
       10625                 :          0 :         return -1;
       10626                 :            :
       10627                 :       7317 :     kind1 = PyUnicode_KIND(str);
       10628                 :       7317 :     kind2 = PyUnicode_KIND(substr);
       10629         [ -  + ]:       7317 :     if (kind1 < kind2)
       10630                 :          0 :         return 0;
       10631                 :       7317 :     len1 = PyUnicode_GET_LENGTH(str);
       10632                 :       7317 :     len2 = PyUnicode_GET_LENGTH(substr);
       10633         [ +  + ]:       7317 :     if (len1 < len2)
       10634                 :        190 :         return 0;
       10635                 :       7127 :     buf1 = PyUnicode_DATA(str);
       10636                 :       7127 :     buf2 = PyUnicode_DATA(substr);
       10637         [ +  + ]:       7127 :     if (len2 == 1) {
       10638                 :       6374 :         Py_UCS4 ch = PyUnicode_READ(kind2, buf2, 0);
       10639                 :       6374 :         result = findchar((const char *)buf1, kind1, len1, ch, 1) != -1;
       10640                 :       6374 :         return result;
       10641                 :            :     }
       10642         [ -  + ]:        753 :     if (kind2 != kind1) {
       10643                 :          0 :         buf2 = unicode_askind(kind2, buf2, len2, kind1);
       10644         [ #  # ]:          0 :         if (!buf2)
       10645                 :          0 :             return -1;
       10646                 :            :     }
       10647                 :            :
       10648   [ +  -  -  - ]:        753 :     switch (kind1) {
       10649                 :        753 :     case PyUnicode_1BYTE_KIND:
       10650                 :        753 :         result = ucs1lib_find(buf1, len1, buf2, len2, 0) != -1;
       10651                 :        753 :         break;
       10652                 :          0 :     case PyUnicode_2BYTE_KIND:
       10653                 :          0 :         result = ucs2lib_find(buf1, len1, buf2, len2, 0) != -1;
       10654                 :          0 :         break;
       10655                 :          0 :     case PyUnicode_4BYTE_KIND:
       10656                 :          0 :         result = ucs4lib_find(buf1, len1, buf2, len2, 0) != -1;
       10657                 :          0 :         break;
       10658                 :          0 :     default:
       10659                 :          0 :         Py_UNREACHABLE();
       10660                 :            :     }
       10661                 :            :
       10662                 :            :     assert((kind2 == kind1) == (buf2 == PyUnicode_DATA(substr)));
       10663         [ -  + ]:        753 :     if (kind2 != kind1)
       10664                 :          0 :         PyMem_Free((void *)buf2);
       10665                 :            :
       10666                 :        753 :     return result;
       10667                 :            : }
       10668                 :            :
       10669                 :            : /* Concat to string or Unicode object giving a new Unicode object. */
       10670                 :            :
       10671                 :            : PyObject *
       10672                 :      98679 : PyUnicode_Concat(PyObject *left, PyObject *right)
       10673                 :            : {
       10674                 :            :     PyObject *result;
       10675                 :            :     Py_UCS4 maxchar, maxchar2;
       10676                 :            :     Py_ssize_t left_len, right_len, new_len;
       10677                 :            :
       10678         [ -  + ]:      98679 :     if (ensure_unicode(left) < 0)
       10679                 :          0 :         return NULL;
       10680                 :            :
       10681         [ -  + ]:      98679 :     if (!PyUnicode_Check(right)) {
       10682                 :          0 :         PyErr_Format(PyExc_TypeError,
       10683                 :            :                      "can only concatenate str (not \"%.200s\") to str",
       10684                 :          0 :                      Py_TYPE(right)->tp_name);
       10685                 :          0 :         return NULL;
       10686                 :            :     }
       10687                 :            :
       10688                 :            :     /* Shortcuts */
       10689                 :      98679 :     PyObject *empty = unicode_get_empty();  // Borrowed reference
       10690         [ +  + ]:      98679 :     if (left == empty) {
       10691                 :        525 :         return PyUnicode_FromObject(right);
       10692                 :            :     }
       10693         [ +  + ]:      98154 :     if (right == empty) {
       10694                 :       6046 :         return PyUnicode_FromObject(left);
       10695                 :            :     }
       10696                 :            :
       10697                 :      92108 :     left_len = PyUnicode_GET_LENGTH(left);
       10698                 :      92108 :     right_len = PyUnicode_GET_LENGTH(right);
       10699         [ -  + ]:      92108 :     if (left_len > PY_SSIZE_T_MAX - right_len) {
       10700                 :          0 :         PyErr_SetString(PyExc_OverflowError,
       10701                 :            :                         "strings are too large to concat");
       10702                 :          0 :         return NULL;
       10703                 :            :     }
       10704                 :      92108 :     new_len = left_len + right_len;
       10705                 :            :
       10706                 :      92108 :     maxchar = PyUnicode_MAX_CHAR_VALUE(left);
       10707                 :      92108 :     maxchar2 = PyUnicode_MAX_CHAR_VALUE(right);
       10708                 :      92108 :     maxchar = Py_MAX(maxchar, maxchar2);
       10709                 :            :
       10710                 :            :     /* Concat the two Unicode strings */
       10711                 :      92108 :     result = PyUnicode_New(new_len, maxchar);
       10712         [ -  + ]:      92108 :     if (result == NULL)
       10713                 :          0 :         return NULL;
       10714                 :      92108 :     _PyUnicode_FastCopyCharacters(result, 0, left, 0, left_len);
       10715                 :      92108 :     _PyUnicode_FastCopyCharacters(result, left_len, right, 0, right_len);
       10716                 :            :     assert(_PyUnicode_CheckConsistency(result, 1));
       10717                 :      92108 :     return result;
       10718                 :            : }
       10719                 :            :
       10720                 :            : void
       10721                 :       7963 : PyUnicode_Append(PyObject **p_left, PyObject *right)
       10722                 :            : {
       10723                 :            :     PyObject *left, *res;
       10724                 :            :     Py_UCS4 maxchar, maxchar2;
       10725                 :            :     Py_ssize_t left_len, right_len, new_len;
       10726                 :            :
       10727         [ -  + ]:       7963 :     if (p_left == NULL) {
       10728         [ #  # ]:          0 :         if (!PyErr_Occurred())
       10729                 :          0 :             PyErr_BadInternalCall();
       10730                 :          0 :         return;
       10731                 :            :     }
       10732                 :       7963 :     left = *p_left;
       10733   [ +  -  +  - ]:       7963 :     if (right == NULL || left == NULL
       10734   [ +  -  -  + ]:       7963 :         || !PyUnicode_Check(left) || !PyUnicode_Check(right)) {
       10735         [ #  # ]:          0 :         if (!PyErr_Occurred())
       10736                 :          0 :             PyErr_BadInternalCall();
       10737                 :          0 :         goto error;
       10738                 :            :     }
       10739                 :            :
       10740                 :            :     /* Shortcuts */
       10741                 :       7963 :     PyObject *empty = unicode_get_empty();  // Borrowed reference
       10742         [ +  + ]:       7963 :     if (left == empty) {
       10743                 :         92 :         Py_DECREF(left);
       10744                 :         92 :         *p_left = Py_NewRef(right);
       10745                 :         92 :         return;
       10746                 :            :     }
       10747         [ -  + ]:       7871 :     if (right == empty) {
       10748                 :          0 :         return;
       10749                 :            :     }
       10750                 :            :
       10751                 :       7871 :     left_len = PyUnicode_GET_LENGTH(left);
       10752                 :       7871 :     right_len = PyUnicode_GET_LENGTH(right);
       10753         [ -  + ]:       7871 :     if (left_len > PY_SSIZE_T_MAX - right_len) {
       10754                 :          0 :         PyErr_SetString(PyExc_OverflowError,
       10755                 :            :                         "strings are too large to concat");
       10756                 :          0 :         goto error;
       10757                 :            :     }
       10758                 :       7871 :     new_len = left_len + right_len;
       10759                 :            :
       10760         [ +  + ]:       7871 :     if (unicode_modifiable(left)
       10761         [ +  - ]:       6118 :         && PyUnicode_CheckExact(right)
       10762         [ +  + ]:       6118 :         && PyUnicode_KIND(right) <= PyUnicode_KIND(left)
       10763                 :            :         /* Don't resize for ascii += latin1. Convert ascii to latin1 requires
       10764                 :            :            to change the structure size, but characters are stored just after
       10765                 :            :            the structure, and so it requires to move all characters which is
       10766                 :            :            not so different than duplicating the string. */
       10767   [ +  +  +  + ]:       6117 :         && !(PyUnicode_IS_ASCII(left) && !PyUnicode_IS_ASCII(right)))
       10768                 :            :     {
       10769                 :            :         /* append inplace */
       10770         [ -  + ]:       6116 :         if (unicode_resize(p_left, new_len) != 0)
       10771                 :          0 :             goto error;
       10772                 :            :
       10773                 :            :         /* copy 'right' into the newly allocated area of 'left' */
       10774                 :       6116 :         _PyUnicode_FastCopyCharacters(*p_left, left_len, right, 0, right_len);
       10775                 :            :     }
       10776                 :            :     else {
       10777                 :       1755 :         maxchar = PyUnicode_MAX_CHAR_VALUE(left);
       10778                 :       1755 :         maxchar2 = PyUnicode_MAX_CHAR_VALUE(right);
       10779                 :       1755 :         maxchar = Py_MAX(maxchar, maxchar2);
       10780                 :            :
       10781                 :            :         /* Concat the two Unicode strings */
       10782                 :       1755 :         res = PyUnicode_New(new_len, maxchar);
       10783         [ -  + ]:       1755 :         if (res == NULL)
       10784                 :          0 :             goto error;
       10785                 :       1755 :         _PyUnicode_FastCopyCharacters(res, 0, left, 0, left_len);
       10786                 :       1755 :         _PyUnicode_FastCopyCharacters(res, left_len, right, 0, right_len);
       10787                 :       1755 :         Py_DECREF(left);
       10788                 :       1755 :         *p_left = res;
       10789                 :            :     }
       10790                 :            :     assert(_PyUnicode_CheckConsistency(*p_left, 1));
       10791                 :       7871 :     return;
       10792                 :            :
       10793                 :          0 : error:
       10794         [ #  # ]:          0 :     Py_CLEAR(*p_left);
       10795                 :            : }
       10796                 :            :
       10797                 :            : void
       10798                 :        795 : PyUnicode_AppendAndDel(PyObject **pleft, PyObject *right)
       10799                 :            : {
       10800                 :        795 :     PyUnicode_Append(pleft, right);
       10801                 :        795 :     Py_XDECREF(right);
       10802                 :        795 : }
       10803                 :            :
       10804                 :            : /*
       10805                 :            : Wraps asciilib_parse_args_finds() and additionally ensures that the
       10806                 :            : first argument is a unicode object.
       10807                 :            : */
       10808                 :            :
       10809                 :            : static inline int
       10810                 :       3075 : parse_args_finds_unicode(const char * function_name, PyObject *args,
       10811                 :            :                          PyObject **substring,
       10812                 :            :                          Py_ssize_t *start, Py_ssize_t *end)
       10813                 :            : {
       10814         [ +  - ]:       3075 :     if (asciilib_parse_args_finds(function_name, args, substring, start, end)) {
       10815         [ -  + ]:       3075 :         if (ensure_unicode(*substring) < 0)
       10816                 :          0 :             return 0;
       10817                 :       3075 :         return 1;
       10818                 :            :     }
       10819                 :          0 :     return 0;
       10820                 :            : }
       10821                 :            :
       10822                 :            : PyDoc_STRVAR(count__doc__,
       10823                 :            :              "S.count(sub[, start[, end]]) -> int\n\
       10824                 :            : \n\
       10825                 :            : Return the number of non-overlapping occurrences of substring sub in\n\
       10826                 :            : string S[start:end].  Optional arguments start and end are\n\
       10827                 :            : interpreted as in slice notation.");
       10828                 :            :
       10829                 :            : static PyObject *
       10830                 :        112 : unicode_count(PyObject *self, PyObject *args)
       10831                 :            : {
       10832                 :        112 :     PyObject *substring = NULL;   /* initialize to fix a compiler warning */
       10833                 :        112 :     Py_ssize_t start = 0;
       10834                 :        112 :     Py_ssize_t end = PY_SSIZE_T_MAX;
       10835                 :            :     Py_ssize_t result;
       10836                 :            :
       10837         [ -  + ]:        112 :     if (!parse_args_finds_unicode("count", args, &substring, &start, &end))
       10838                 :          0 :         return NULL;
       10839                 :            :
       10840                 :        112 :     result = unicode_count_impl(self, substring, start, end);
       10841         [ -  + ]:        112 :     if (result == -1)
       10842                 :          0 :         return NULL;
       10843                 :            :
       10844                 :        112 :     return PyLong_FromSsize_t(result);
       10845                 :            : }
       10846                 :            :
       10847                 :            : /*[clinic input]
       10848                 :            : str.encode as unicode_encode
       10849                 :            :
       10850                 :            :     encoding: str(c_default="NULL") = 'utf-8'
       10851                 :            :         The encoding in which to encode the string.
       10852                 :            :     errors: str(c_default="NULL") = 'strict'
       10853                 :            :         The error handling scheme to use for encoding errors.
       10854                 :            :         The default is 'strict' meaning that encoding errors raise a
       10855                 :            :         UnicodeEncodeError.  Other possible values are 'ignore', 'replace' and
       10856                 :            :         'xmlcharrefreplace' as well as any other name registered with
       10857                 :            :         codecs.register_error that can handle UnicodeEncodeErrors.
       10858                 :            :
       10859                 :            : Encode the string using the codec registered for encoding.
       10860                 :            : [clinic start generated code]*/
       10861                 :            :
       10862                 :            : static PyObject *
       10863                 :       3123 : unicode_encode_impl(PyObject *self, const char *encoding, const char *errors)
       10864                 :            : /*[clinic end generated code: output=bf78b6e2a9470e3c input=f0a9eb293d08fe02]*/
       10865                 :            : {
       10866                 :       3123 :     return PyUnicode_AsEncodedString(self, encoding, errors);
       10867                 :            : }
       10868                 :            :
       10869                 :            : /*[clinic input]
       10870                 :            : str.expandtabs as unicode_expandtabs
       10871                 :            :
       10872                 :            :     tabsize: int = 8
       10873                 :            :
       10874                 :            : Return a copy where all tab characters are expanded using spaces.
       10875                 :            :
       10876                 :            : If tabsize is not given, a tab size of 8 characters is assumed.
       10877                 :            : [clinic start generated code]*/
       10878                 :            :
       10879                 :            : static PyObject *
       10880                 :          1 : unicode_expandtabs_impl(PyObject *self, int tabsize)
       10881                 :            : /*[clinic end generated code: output=3457c5dcee26928f input=8a01914034af4c85]*/
       10882                 :            : {
       10883                 :            :     Py_ssize_t i, j, line_pos, src_len, incr;
       10884                 :            :     Py_UCS4 ch;
       10885                 :            :     PyObject *u;
       10886                 :            :     const void *src_data;
       10887                 :            :     void *dest_data;
       10888                 :            :     int kind;
       10889                 :            :     int found;
       10890                 :            :
       10891                 :            :     /* First pass: determine size of output string */
       10892                 :          1 :     src_len = PyUnicode_GET_LENGTH(self);
       10893                 :          1 :     i = j = line_pos = 0;
       10894                 :          1 :     kind = PyUnicode_KIND(self);
       10895                 :          1 :     src_data = PyUnicode_DATA(self);
       10896                 :          1 :     found = 0;
       10897         [ +  + ]:       3226 :     for (; i < src_len; i++) {
       10898                 :       3225 :         ch = PyUnicode_READ(kind, src_data, i);
       10899         [ -  + ]:       3225 :         if (ch == '\t') {
       10900                 :          0 :             found = 1;
       10901         [ #  # ]:          0 :             if (tabsize > 0) {
       10902                 :          0 :                 incr = tabsize - (line_pos % tabsize); /* cannot overflow */
       10903         [ #  # ]:          0 :                 if (j > PY_SSIZE_T_MAX - incr)
       10904                 :          0 :                     goto overflow;
       10905                 :          0 :                 line_pos += incr;
       10906                 :          0 :                 j += incr;
       10907                 :            :             }
       10908                 :            :         }
       10909                 :            :         else {
       10910         [ -  + ]:       3225 :             if (j > PY_SSIZE_T_MAX - 1)
       10911                 :          0 :                 goto overflow;
       10912                 :       3225 :             line_pos++;
       10913                 :       3225 :             j++;
       10914   [ +  +  -  + ]:       3225 :             if (ch == '\n' || ch == '\r')
       10915                 :        183 :                 line_pos = 0;
       10916                 :            :         }
       10917                 :            :     }
       10918         [ +  - ]:          1 :     if (!found)
       10919                 :          1 :         return unicode_result_unchanged(self);
       10920                 :            :
       10921                 :            :     /* Second pass: create output string and fill it */
       10922                 :          0 :     u = PyUnicode_New(j, PyUnicode_MAX_CHAR_VALUE(self));
       10923         [ #  # ]:          0 :     if (!u)
       10924                 :          0 :         return NULL;
       10925                 :          0 :     dest_data = PyUnicode_DATA(u);
       10926                 :            :
       10927                 :          0 :     i = j = line_pos = 0;
       10928                 :            :
       10929         [ #  # ]:          0 :     for (; i < src_len; i++) {
       10930                 :          0 :         ch = PyUnicode_READ(kind, src_data, i);
       10931         [ #  # ]:          0 :         if (ch == '\t') {
       10932         [ #  # ]:          0 :             if (tabsize > 0) {
       10933                 :          0 :                 incr = tabsize - (line_pos % tabsize);
       10934                 :          0 :                 line_pos += incr;
       10935                 :          0 :                 unicode_fill(kind, dest_data, ' ', j, incr);
       10936                 :          0 :                 j += incr;
       10937                 :            :             }
       10938                 :            :         }
       10939                 :            :         else {
       10940                 :          0 :             line_pos++;
       10941                 :          0 :             PyUnicode_WRITE(kind, dest_data, j, ch);
       10942                 :          0 :             j++;
       10943   [ #  #  #  # ]:          0 :             if (ch == '\n' || ch == '\r')
       10944                 :          0 :                 line_pos = 0;
       10945                 :            :         }
       10946                 :            :     }
       10947                 :            :     assert (j == PyUnicode_GET_LENGTH(u));
       10948                 :          0 :     return unicode_result(u);
       10949                 :            :
       10950                 :          0 :   overflow:
       10951                 :          0 :     PyErr_SetString(PyExc_OverflowError, "new string is too long");
       10952                 :          0 :     return NULL;
       10953                 :            : }
       10954                 :            :
       10955                 :            : PyDoc_STRVAR(find__doc__,
       10956                 :            :              "S.find(sub[, start[, end]]) -> int\n\
       10957                 :            : \n\
       10958                 :            : Return the lowest index in S where substring sub is found,\n\
       10959                 :            : such that sub is contained within S[start:end].  Optional\n\
       10960                 :            : arguments start and end are interpreted as in slice notation.\n\
       10961                 :            : \n\
       10962                 :            : Return -1 on failure.");
       10963                 :            :
       10964                 :            : static PyObject *
       10965                 :        103 : unicode_find(PyObject *self, PyObject *args)
       10966                 :            : {
       10967                 :            :     /* initialize variables to prevent gcc warning */
       10968                 :        103 :     PyObject *substring = NULL;
       10969                 :        103 :     Py_ssize_t start = 0;
       10970                 :        103 :     Py_ssize_t end = 0;
       10971                 :            :     Py_ssize_t result;
       10972                 :            :
       10973         [ -  + ]:        103 :     if (!parse_args_finds_unicode("find", args, &substring, &start, &end))
       10974                 :          0 :         return NULL;
       10975                 :            :
       10976                 :        103 :     result = any_find_slice(self, substring, start, end, 1);
       10977                 :            :
       10978         [ -  + ]:        103 :     if (result == -2)
       10979                 :          0 :         return NULL;
       10980                 :            :
       10981                 :        103 :     return PyLong_FromSsize_t(result);
       10982                 :            : }
       10983                 :            :
       10984                 :            : static PyObject *
       10985                 :      20640 : unicode_getitem(PyObject *self, Py_ssize_t index)
       10986                 :            : {
       10987                 :            :     const void *data;
       10988                 :            :     int kind;
       10989                 :            :     Py_UCS4 ch;
       10990                 :            :
       10991         [ -  + ]:      20640 :     if (!PyUnicode_Check(self)) {
       10992                 :          0 :         PyErr_BadArgument();
       10993                 :          0 :         return NULL;
       10994                 :            :     }
       10995   [ +  -  +  + ]:      20640 :     if (index < 0 || index >= PyUnicode_GET_LENGTH(self)) {
       10996                 :         80 :         PyErr_SetString(PyExc_IndexError, "string index out of range");
       10997                 :         80 :         return NULL;
       10998                 :            :     }
       10999                 :      20560 :     kind = PyUnicode_KIND(self);
       11000                 :      20560 :     data = PyUnicode_DATA(self);
       11001                 :      20560 :     ch = PyUnicode_READ(kind, data, index);
       11002                 :      20560 :     return unicode_char(ch);
       11003                 :            : }
       11004                 :            :
       11005                 :            : /* Believe it or not, this produces the same value for ASCII strings
       11006                 :            :    as bytes_hash(). */
       11007                 :            : static Py_hash_t
       11008                 :    3294058 : unicode_hash(PyObject *self)
       11009                 :            : {
       11010                 :            :     Py_uhash_t x;  /* Unsigned for defined overflow behavior. */
       11011                 :            :
       11012                 :            : #ifdef Py_DEBUG
       11013                 :            :     assert(_Py_HashSecret_Initialized);
       11014                 :            : #endif
       11015         [ +  + ]:    3294058 :     if (_PyUnicode_HASH(self) != -1)
       11016                 :    1031684 :         return _PyUnicode_HASH(self);
       11017                 :            :
       11018                 :    2262374 :     x = _Py_HashBytes(PyUnicode_DATA(self),
       11019                 :    2262374 :                       PyUnicode_GET_LENGTH(self) * PyUnicode_KIND(self));
       11020                 :    2262374 :     _PyUnicode_HASH(self) = x;
       11021                 :    2262374 :     return x;
       11022                 :            : }
       11023                 :            :
       11024                 :            : PyDoc_STRVAR(index__doc__,
       11025                 :            :              "S.index(sub[, start[, end]]) -> int\n\
       11026                 :            : \n\
       11027                 :            : Return the lowest index in S where substring sub is found,\n\
       11028                 :            : such that sub is contained within S[start:end].  Optional\n\
       11029                 :            : arguments start and end are interpreted as in slice notation.\n\
       11030                 :            : \n\
       11031                 :            : Raises ValueError when the substring is not found.");
       11032                 :            :
       11033                 :            : static PyObject *
       11034                 :        127 : unicode_index(PyObject *self, PyObject *args)
       11035                 :            : {
       11036                 :            :     /* initialize variables to prevent gcc warning */
       11037                 :            :     Py_ssize_t result;
       11038                 :        127 :     PyObject *substring = NULL;
       11039                 :        127 :     Py_ssize_t start = 0;
       11040                 :        127 :     Py_ssize_t end = 0;
       11041                 :            :
       11042         [ -  + ]:        127 :     if (!parse_args_finds_unicode("index", args, &substring, &start, &end))
       11043                 :          0 :         return NULL;
       11044                 :            :
       11045                 :        127 :     result = any_find_slice(self, substring, start, end, 1);
       11046                 :            :
       11047         [ -  + ]:        127 :     if (result == -2)
       11048                 :          0 :         return NULL;
       11049                 :            :
       11050         [ -  + ]:        127 :     if (result < 0) {
       11051                 :          0 :         PyErr_SetString(PyExc_ValueError, "substring not found");
       11052                 :          0 :         return NULL;
       11053                 :            :     }
       11054                 :            :
       11055                 :        127 :     return PyLong_FromSsize_t(result);
       11056                 :            : }
       11057                 :            :
       11058                 :            : /*[clinic input]
       11059                 :            : str.isascii as unicode_isascii
       11060                 :            :
       11061                 :            : Return True if all characters in the string are ASCII, False otherwise.
       11062                 :            :
       11063                 :            : ASCII characters have code points in the range U+0000-U+007F.
       11064                 :            : Empty string is ASCII too.
       11065                 :            : [clinic start generated code]*/
       11066                 :            :
       11067                 :            : static PyObject *
       11068                 :        385 : unicode_isascii_impl(PyObject *self)
       11069                 :            : /*[clinic end generated code: output=c5910d64b5a8003f input=5a43cbc6399621d5]*/
       11070                 :            : {
       11071                 :        385 :     return PyBool_FromLong(PyUnicode_IS_ASCII(self));
       11072                 :            : }
       11073                 :            :
       11074                 :            : /*[clinic input]
       11075                 :            : str.islower as unicode_islower
       11076                 :            :
       11077                 :            : Return True if the string is a lowercase string, False otherwise.
       11078                 :            :
       11079                 :            : A string is lowercase if all cased characters in the string are lowercase and
       11080                 :            : there is at least one cased character in the string.
       11081                 :            : [clinic start generated code]*/
       11082                 :            :
       11083                 :            : static PyObject *
       11084                 :          0 : unicode_islower_impl(PyObject *self)
       11085                 :            : /*[clinic end generated code: output=dbd41995bd005b81 input=acec65ac6821ae47]*/
       11086                 :            : {
       11087                 :            :     Py_ssize_t i, length;
       11088                 :            :     int kind;
       11089                 :            :     const void *data;
       11090                 :            :     int cased;
       11091                 :            :
       11092                 :          0 :     length = PyUnicode_GET_LENGTH(self);
       11093                 :          0 :     kind = PyUnicode_KIND(self);
       11094                 :          0 :     data = PyUnicode_DATA(self);
       11095                 :            :
       11096                 :            :     /* Shortcut for single character strings */
       11097         [ #  # ]:          0 :     if (length == 1)
       11098                 :          0 :         return PyBool_FromLong(
       11099                 :          0 :             Py_UNICODE_ISLOWER(PyUnicode_READ(kind, data, 0)));
       11100                 :            :
       11101                 :            :     /* Special case for empty strings */
       11102         [ #  # ]:          0 :     if (length == 0)
       11103                 :          0 :         Py_RETURN_FALSE;
       11104                 :            :
       11105                 :          0 :     cased = 0;
       11106         [ #  # ]:          0 :     for (i = 0; i < length; i++) {
       11107                 :          0 :         const Py_UCS4 ch = PyUnicode_READ(kind, data, i);
       11108                 :            :
       11109   [ #  #  #  # ]:          0 :         if (Py_UNICODE_ISUPPER(ch) || Py_UNICODE_ISTITLE(ch))
       11110                 :          0 :             Py_RETURN_FALSE;
       11111   [ #  #  #  # ]:          0 :         else if (!cased && Py_UNICODE_ISLOWER(ch))
       11112                 :          0 :             cased = 1;
       11113                 :            :     }
       11114                 :          0 :     return PyBool_FromLong(cased);
       11115                 :            : }
       11116                 :            :
       11117                 :            : /*[clinic input]
       11118                 :            : str.isupper as unicode_isupper
       11119                 :            :
       11120                 :            : Return True if the string is an uppercase string, False otherwise.
       11121                 :            :
       11122                 :            : A string is uppercase if all cased characters in the string are uppercase and
       11123                 :            : there is at least one cased character in the string.
       11124                 :            : [clinic start generated code]*/
       11125                 :            :
       11126                 :            : static PyObject *
       11127                 :       1844 : unicode_isupper_impl(PyObject *self)
       11128                 :            : /*[clinic end generated code: output=049209c8e7f15f59 input=e9b1feda5d17f2d3]*/
       11129                 :            : {
       11130                 :            :     Py_ssize_t i, length;
       11131                 :            :     int kind;
       11132                 :            :     const void *data;
       11133                 :            :     int cased;
       11134                 :            :
       11135                 :       1844 :     length = PyUnicode_GET_LENGTH(self);
       11136                 :       1844 :     kind = PyUnicode_KIND(self);
       11137                 :       1844 :     data = PyUnicode_DATA(self);
       11138                 :            :
       11139                 :            :     /* Shortcut for single character strings */
       11140         [ -  + ]:       1844 :     if (length == 1)
       11141                 :          0 :         return PyBool_FromLong(
       11142                 :          0 :             Py_UNICODE_ISUPPER(PyUnicode_READ(kind, data, 0)) != 0);
       11143                 :            :
       11144                 :            :     /* Special case for empty strings */
       11145         [ -  + ]:       1844 :     if (length == 0)
       11146                 :          0 :         Py_RETURN_FALSE;
       11147                 :            :
       11148                 :       1844 :     cased = 0;
       11149         [ +  + ]:      22240 :     for (i = 0; i < length; i++) {
       11150                 :      20670 :         const Py_UCS4 ch = PyUnicode_READ(kind, data, i);
       11151                 :            :
       11152   [ +  +  -  + ]:      20670 :         if (Py_UNICODE_ISLOWER(ch) || Py_UNICODE_ISTITLE(ch))
       11153                 :        274 :             Py_RETURN_FALSE;
       11154   [ +  +  +  + ]:      20396 :         else if (!cased && Py_UNICODE_ISUPPER(ch))
       11155                 :       1596 :             cased = 1;
       11156                 :            :     }
       11157                 :       1570 :     return PyBool_FromLong(cased);
       11158                 :            : }
       11159                 :            :
       11160                 :            : /*[clinic input]
       11161                 :            : str.istitle as unicode_istitle
       11162                 :            :
       11163                 :            : Return True if the string is a title-cased string, False otherwise.
       11164                 :            :
       11165                 :            : In a title-cased string, upper- and title-case characters may only
       11166                 :            : follow uncased characters and lowercase characters only cased ones.
       11167                 :            : [clinic start generated code]*/
       11168                 :            :
       11169                 :            : static PyObject *
       11170                 :          0 : unicode_istitle_impl(PyObject *self)
       11171                 :            : /*[clinic end generated code: output=e9bf6eb91f5d3f0e input=98d32bd2e1f06f8c]*/
       11172                 :            : {
       11173                 :            :     Py_ssize_t i, length;
       11174                 :            :     int kind;
       11175                 :            :     const void *data;
       11176                 :            :     int cased, previous_is_cased;
       11177                 :            :
       11178                 :          0 :     length = PyUnicode_GET_LENGTH(self);
       11179                 :          0 :     kind = PyUnicode_KIND(self);
       11180                 :          0 :     data = PyUnicode_DATA(self);
       11181                 :            :
       11182                 :            :     /* Shortcut for single character strings */
       11183         [ #  # ]:          0 :     if (length == 1) {
       11184                 :          0 :         Py_UCS4 ch = PyUnicode_READ(kind, data, 0);
       11185   [ #  #  #  # ]:          0 :         return PyBool_FromLong((Py_UNICODE_ISTITLE(ch) != 0) ||
       11186                 :          0 :                                (Py_UNICODE_ISUPPER(ch) != 0));
       11187                 :            :     }
       11188                 :            :
       11189                 :            :     /* Special case for empty strings */
       11190         [ #  # ]:          0 :     if (length == 0)
       11191                 :          0 :         Py_RETURN_FALSE;
       11192                 :            :
       11193                 :          0 :     cased = 0;
       11194                 :          0 :     previous_is_cased = 0;
       11195         [ #  # ]:          0 :     for (i = 0; i < length; i++) {
       11196                 :          0 :         const Py_UCS4 ch = PyUnicode_READ(kind, data, i);
       11197                 :            :
       11198   [ #  #  #  # ]:          0 :         if (Py_UNICODE_ISUPPER(ch) || Py_UNICODE_ISTITLE(ch)) {
       11199         [ #  # ]:          0 :             if (previous_is_cased)
       11200                 :          0 :                 Py_RETURN_FALSE;
       11201                 :          0 :             previous_is_cased = 1;
       11202                 :          0 :             cased = 1;
       11203                 :            :         }
       11204         [ #  # ]:          0 :         else if (Py_UNICODE_ISLOWER(ch)) {
       11205         [ #  # ]:          0 :             if (!previous_is_cased)
       11206                 :          0 :                 Py_RETURN_FALSE;
       11207                 :          0 :             previous_is_cased = 1;
       11208                 :          0 :             cased = 1;
       11209                 :            :         }
       11210                 :            :         else
       11211                 :          0 :             previous_is_cased = 0;
       11212                 :            :     }
       11213                 :          0 :     return PyBool_FromLong(cased);
       11214                 :            : }
       11215                 :            :
       11216                 :            : /*[clinic input]
       11217                 :            : str.isspace as unicode_isspace
       11218                 :            :
       11219                 :            : Return True if the string is a whitespace string, False otherwise.
       11220                 :            :
       11221                 :            : A string is whitespace if all characters in the string are whitespace and there
       11222                 :            : is at least one character in the string.
       11223                 :            : [clinic start generated code]*/
       11224                 :            :
       11225                 :            : static PyObject *
       11226                 :          1 : unicode_isspace_impl(PyObject *self)
       11227                 :            : /*[clinic end generated code: output=163a63bfa08ac2b9 input=fe462cb74f8437d8]*/
       11228                 :            : {
       11229                 :            :     Py_ssize_t i, length;
       11230                 :            :     int kind;
       11231                 :            :     const void *data;
       11232                 :            :
       11233                 :          1 :     length = PyUnicode_GET_LENGTH(self);
       11234                 :          1 :     kind = PyUnicode_KIND(self);
       11235                 :          1 :     data = PyUnicode_DATA(self);
       11236                 :            :
       11237                 :            :     /* Shortcut for single character strings */
       11238         [ +  - ]:          1 :     if (length == 1)
       11239                 :          1 :         return PyBool_FromLong(
       11240                 :          1 :             Py_UNICODE_ISSPACE(PyUnicode_READ(kind, data, 0)));
       11241                 :            :
       11242                 :            :     /* Special case for empty strings */
       11243         [ #  # ]:          0 :     if (length == 0)
       11244                 :          0 :         Py_RETURN_FALSE;
       11245                 :            :
       11246         [ #  # ]:          0 :     for (i = 0; i < length; i++) {
       11247                 :          0 :         const Py_UCS4 ch = PyUnicode_READ(kind, data, i);
       11248         [ #  # ]:          0 :         if (!Py_UNICODE_ISSPACE(ch))
       11249                 :          0 :             Py_RETURN_FALSE;
       11250                 :            :     }
       11251                 :          0 :     Py_RETURN_TRUE;
       11252                 :            : }
       11253                 :            :
       11254                 :            : /*[clinic input]
       11255                 :            : str.isalpha as unicode_isalpha
       11256                 :            :
       11257                 :            : Return True if the string is an alphabetic string, False otherwise.
       11258                 :            :
       11259                 :            : A string is alphabetic if all characters in the string are alphabetic and there
       11260                 :            : is at least one character in the string.
       11261                 :            : [clinic start generated code]*/
       11262                 :            :
       11263                 :            : static PyObject *
       11264                 :          0 : unicode_isalpha_impl(PyObject *self)
       11265                 :            : /*[clinic end generated code: output=cc81b9ac3883ec4f input=d0fd18a96cbca5eb]*/
       11266                 :            : {
       11267                 :            :     Py_ssize_t i, length;
       11268                 :            :     int kind;
       11269                 :            :     const void *data;
       11270                 :            :
       11271                 :          0 :     length = PyUnicode_GET_LENGTH(self);
       11272                 :          0 :     kind = PyUnicode_KIND(self);
       11273                 :          0 :     data = PyUnicode_DATA(self);
       11274                 :            :
       11275                 :            :     /* Shortcut for single character strings */
       11276         [ #  # ]:          0 :     if (length == 1)
       11277                 :          0 :         return PyBool_FromLong(
       11278                 :          0 :             Py_UNICODE_ISALPHA(PyUnicode_READ(kind, data, 0)));
       11279                 :            :
       11280                 :            :     /* Special case for empty strings */
       11281         [ #  # ]:          0 :     if (length == 0)
       11282                 :          0 :         Py_RETURN_FALSE;
       11283                 :            :
       11284         [ #  # ]:          0 :     for (i = 0; i < length; i++) {
       11285         [ #  # ]:          0 :         if (!Py_UNICODE_ISALPHA(PyUnicode_READ(kind, data, i)))
       11286                 :          0 :             Py_RETURN_FALSE;
       11287                 :            :     }
       11288                 :          0 :     Py_RETURN_TRUE;
       11289                 :            : }
       11290                 :            :
       11291                 :            : /*[clinic input]
       11292                 :            : str.isalnum as unicode_isalnum
       11293                 :            :
       11294                 :            : Return True if the string is an alpha-numeric string, False otherwise.
       11295                 :            :
       11296                 :            : A string is alpha-numeric if all characters in the string are alpha-numeric and
       11297                 :            : there is at least one character in the string.
       11298                 :            : [clinic start generated code]*/
       11299                 :            :
       11300                 :            : static PyObject *
       11301                 :        432 : unicode_isalnum_impl(PyObject *self)
       11302                 :            : /*[clinic end generated code: output=a5a23490ffc3660c input=5c6579bf2e04758c]*/
       11303                 :            : {
       11304                 :            :     int kind;
       11305                 :            :     const void *data;
       11306                 :            :     Py_ssize_t len, i;
       11307                 :            :
       11308                 :        432 :     kind = PyUnicode_KIND(self);
       11309                 :        432 :     data = PyUnicode_DATA(self);
       11310                 :        432 :     len = PyUnicode_GET_LENGTH(self);
       11311                 :            :
       11312                 :            :     /* Shortcut for single character strings */
       11313         [ +  - ]:        432 :     if (len == 1) {
       11314                 :        432 :         const Py_UCS4 ch = PyUnicode_READ(kind, data, 0);
       11315                 :        432 :         return PyBool_FromLong(Py_UNICODE_ISALNUM(ch));
       11316                 :            :     }
       11317                 :            :
       11318                 :            :     /* Special case for empty strings */
       11319         [ #  # ]:          0 :     if (len == 0)
       11320                 :          0 :         Py_RETURN_FALSE;
       11321                 :            :
       11322         [ #  # ]:          0 :     for (i = 0; i < len; i++) {
       11323                 :          0 :         const Py_UCS4 ch = PyUnicode_READ(kind, data, i);
       11324         [ #  # ]:          0 :         if (!Py_UNICODE_ISALNUM(ch))
       11325                 :          0 :             Py_RETURN_FALSE;
       11326                 :            :     }
       11327                 :          0 :     Py_RETURN_TRUE;
       11328                 :            : }
       11329                 :            :
       11330                 :            : /*[clinic input]
       11331                 :            : str.isdecimal as unicode_isdecimal
       11332                 :            :
       11333                 :            : Return True if the string is a decimal string, False otherwise.
       11334                 :            :
       11335                 :            : A string is a decimal string if all characters in the string are decimal and
       11336                 :            : there is at least one character in the string.
       11337                 :            : [clinic start generated code]*/
       11338                 :            :
       11339                 :            : static PyObject *
       11340                 :          0 : unicode_isdecimal_impl(PyObject *self)
       11341                 :            : /*[clinic end generated code: output=fb2dcdb62d3fc548 input=336bc97ab4c8268f]*/
       11342                 :            : {
       11343                 :            :     Py_ssize_t i, length;
       11344                 :            :     int kind;
       11345                 :            :     const void *data;
       11346                 :            :
       11347                 :          0 :     length = PyUnicode_GET_LENGTH(self);
       11348                 :          0 :     kind = PyUnicode_KIND(self);
       11349                 :          0 :     data = PyUnicode_DATA(self);
       11350                 :            :
       11351                 :            :     /* Shortcut for single character strings */
       11352         [ #  # ]:          0 :     if (length == 1)
       11353                 :          0 :         return PyBool_FromLong(
       11354                 :          0 :             Py_UNICODE_ISDECIMAL(PyUnicode_READ(kind, data, 0)));
       11355                 :            :
       11356                 :            :     /* Special case for empty strings */
       11357         [ #  # ]:          0 :     if (length == 0)
       11358                 :          0 :         Py_RETURN_FALSE;
       11359                 :            :
       11360         [ #  # ]:          0 :     for (i = 0; i < length; i++) {
       11361         [ #  # ]:          0 :         if (!Py_UNICODE_ISDECIMAL(PyUnicode_READ(kind, data, i)))
       11362                 :          0 :             Py_RETURN_FALSE;
       11363                 :            :     }
       11364                 :          0 :     Py_RETURN_TRUE;
       11365                 :            : }
       11366                 :            :
       11367                 :            : /*[clinic input]
       11368                 :            : str.isdigit as unicode_isdigit
       11369                 :            :
       11370                 :            : Return True if the string is a digit string, False otherwise.
       11371                 :            :
       11372                 :            : A string is a digit string if all characters in the string are digits and there
       11373                 :            : is at least one character in the string.
       11374                 :            : [clinic start generated code]*/
       11375                 :            :
       11376                 :            : static PyObject *
       11377                 :          0 : unicode_isdigit_impl(PyObject *self)
       11378                 :            : /*[clinic end generated code: output=10a6985311da6858 input=901116c31deeea4c]*/
       11379                 :            : {
       11380                 :            :     Py_ssize_t i, length;
       11381                 :            :     int kind;
       11382                 :            :     const void *data;
       11383                 :            :
       11384                 :          0 :     length = PyUnicode_GET_LENGTH(self);
       11385                 :          0 :     kind = PyUnicode_KIND(self);
       11386                 :          0 :     data = PyUnicode_DATA(self);
       11387                 :            :
       11388                 :            :     /* Shortcut for single character strings */
       11389         [ #  # ]:          0 :     if (length == 1) {
       11390                 :          0 :         const Py_UCS4 ch = PyUnicode_READ(kind, data, 0);
       11391                 :          0 :         return PyBool_FromLong(Py_UNICODE_ISDIGIT(ch));
       11392                 :            :     }
       11393                 :            :
       11394                 :            :     /* Special case for empty strings */
       11395         [ #  # ]:          0 :     if (length == 0)
       11396                 :          0 :         Py_RETURN_FALSE;
       11397                 :            :
       11398         [ #  # ]:          0 :     for (i = 0; i < length; i++) {
       11399         [ #  # ]:          0 :         if (!Py_UNICODE_ISDIGIT(PyUnicode_READ(kind, data, i)))
       11400                 :          0 :             Py_RETURN_FALSE;
       11401                 :            :     }
       11402                 :          0 :     Py_RETURN_TRUE;
       11403                 :            : }
       11404                 :            :
       11405                 :            : /*[clinic input]
       11406                 :            : str.isnumeric as unicode_isnumeric
       11407                 :            :
       11408                 :            : Return True if the string is a numeric string, False otherwise.
       11409                 :            :
       11410                 :            : A string is numeric if all characters in the string are numeric and there is at
       11411                 :            : least one character in the string.
       11412                 :            : [clinic start generated code]*/
       11413                 :            :
       11414                 :            : static PyObject *
       11415                 :          0 : unicode_isnumeric_impl(PyObject *self)
       11416                 :            : /*[clinic end generated code: output=9172a32d9013051a input=722507db976f826c]*/
       11417                 :            : {
       11418                 :            :     Py_ssize_t i, length;
       11419                 :            :     int kind;
       11420                 :            :     const void *data;
       11421                 :            :
       11422                 :          0 :     length = PyUnicode_GET_LENGTH(self);
       11423                 :          0 :     kind = PyUnicode_KIND(self);
       11424                 :          0 :     data = PyUnicode_DATA(self);
       11425                 :            :
       11426                 :            :     /* Shortcut for single character strings */
       11427         [ #  # ]:          0 :     if (length == 1)
       11428                 :          0 :         return PyBool_FromLong(
       11429                 :          0 :             Py_UNICODE_ISNUMERIC(PyUnicode_READ(kind, data, 0)));
       11430                 :            :
       11431                 :            :     /* Special case for empty strings */
       11432         [ #  # ]:          0 :     if (length == 0)
       11433                 :          0 :         Py_RETURN_FALSE;
       11434                 :            :
       11435         [ #  # ]:          0 :     for (i = 0; i < length; i++) {
       11436         [ #  # ]:          0 :         if (!Py_UNICODE_ISNUMERIC(PyUnicode_READ(kind, data, i)))
       11437                 :          0 :             Py_RETURN_FALSE;
       11438                 :            :     }
       11439                 :          0 :     Py_RETURN_TRUE;
       11440                 :            : }
       11441                 :            :
       11442                 :            : Py_ssize_t
       11443                 :        703 : _PyUnicode_ScanIdentifier(PyObject *self)
       11444                 :            : {
       11445                 :            :     Py_ssize_t i;
       11446                 :        703 :     Py_ssize_t len = PyUnicode_GET_LENGTH(self);
       11447         [ -  + ]:        703 :     if (len == 0) {
       11448                 :            :         /* an empty string is not a valid identifier */
       11449                 :          0 :         return 0;
       11450                 :            :     }
       11451                 :            :
       11452                 :        703 :     int kind = PyUnicode_KIND(self);
       11453                 :        703 :     const void *data = PyUnicode_DATA(self);
       11454                 :        703 :     Py_UCS4 ch = PyUnicode_READ(kind, data, 0);
       11455                 :            :     /* PEP 3131 says that the first character must be in
       11456                 :            :        XID_Start and subsequent characters in XID_Continue,
       11457                 :            :        and for the ASCII range, the 2.x rules apply (i.e
       11458                 :            :        start with letters and underscore, continue with
       11459                 :            :        letters, digits, underscore). However, given the current
       11460                 :            :        definition of XID_Start and XID_Continue, it is sufficient
       11461                 :            :        to check just for these, except that _ must be allowed
       11462                 :            :        as starting an identifier.  */
       11463   [ +  +  -  + ]:        703 :     if (!_PyUnicode_IsXidStart(ch) && ch != 0x5F /* LOW LINE */) {
       11464                 :          0 :         return 0;
       11465                 :            :     }
       11466                 :            :
       11467         [ +  + ]:       5385 :     for (i = 1; i < len; i++) {
       11468                 :       4682 :         ch = PyUnicode_READ(kind, data, i);
       11469         [ -  + ]:       4682 :         if (!_PyUnicode_IsXidContinue(ch)) {
       11470                 :          0 :             return i;
       11471                 :            :         }
       11472                 :            :     }
       11473                 :        703 :     return i;
       11474                 :            : }
       11475                 :            :
       11476                 :            : int
       11477                 :        703 : PyUnicode_IsIdentifier(PyObject *self)
       11478                 :            : {
       11479                 :        703 :     Py_ssize_t i = _PyUnicode_ScanIdentifier(self);
       11480                 :        703 :     Py_ssize_t len = PyUnicode_GET_LENGTH(self);
       11481                 :            :     /* an empty string is not a valid identifier */
       11482   [ +  -  +  - ]:        703 :     return len && i == len;
       11483                 :            : }
       11484                 :            :
       11485                 :            : /*[clinic input]
       11486                 :            : str.isidentifier as unicode_isidentifier
       11487                 :            :
       11488                 :            : Return True if the string is a valid Python identifier, False otherwise.
       11489                 :            :
       11490                 :            : Call keyword.iskeyword(s) to test whether string s is a reserved identifier,
       11491                 :            : such as "def" or "class".
       11492                 :            : [clinic start generated code]*/
       11493                 :            :
       11494                 :            : static PyObject *
       11495                 :        371 : unicode_isidentifier_impl(PyObject *self)
       11496                 :            : /*[clinic end generated code: output=fe585a9666572905 input=2d807a104f21c0c5]*/
       11497                 :            : {
       11498                 :        371 :     return PyBool_FromLong(PyUnicode_IsIdentifier(self));
       11499                 :            : }
       11500                 :            :
       11501                 :            : /*[clinic input]
       11502                 :            : str.isprintable as unicode_isprintable
       11503                 :            :
       11504                 :            : Return True if the string is printable, False otherwise.
       11505                 :            :
       11506                 :            : A string is printable if all of its characters are considered printable in
       11507                 :            : repr() or if it is empty.
       11508                 :            : [clinic start generated code]*/
       11509                 :            :
       11510                 :            : static PyObject *
       11511                 :          0 : unicode_isprintable_impl(PyObject *self)
       11512                 :            : /*[clinic end generated code: output=3ab9626cd32dd1a0 input=98a0e1c2c1813209]*/
       11513                 :            : {
       11514                 :            :     Py_ssize_t i, length;
       11515                 :            :     int kind;
       11516                 :            :     const void *data;
       11517                 :            :
       11518                 :          0 :     length = PyUnicode_GET_LENGTH(self);
       11519                 :          0 :     kind = PyUnicode_KIND(self);
       11520                 :          0 :     data = PyUnicode_DATA(self);
       11521                 :            :
       11522                 :            :     /* Shortcut for single character strings */
       11523         [ #  # ]:          0 :     if (length == 1)
       11524                 :          0 :         return PyBool_FromLong(
       11525                 :          0 :             Py_UNICODE_ISPRINTABLE(PyUnicode_READ(kind, data, 0)));
       11526                 :            :
       11527         [ #  # ]:          0 :     for (i = 0; i < length; i++) {
       11528         [ #  # ]:          0 :         if (!Py_UNICODE_ISPRINTABLE(PyUnicode_READ(kind, data, i))) {
       11529                 :          0 :             Py_RETURN_FALSE;
       11530                 :            :         }
       11531                 :            :     }
       11532                 :          0 :     Py_RETURN_TRUE;
       11533                 :            : }
       11534                 :            :
       11535                 :            : /*[clinic input]
       11536                 :            : str.join as unicode_join
       11537                 :            :
       11538                 :            :     iterable: object
       11539                 :            :     /
       11540                 :            :
       11541                 :            : Concatenate any number of strings.
       11542                 :            :
       11543                 :            : The string whose method is called is inserted in between each given string.
       11544                 :            : The result is returned as a new string.
       11545                 :            :
       11546                 :            : Example: '.'.join(['ab', 'pq', 'rs']) -> 'ab.pq.rs'
       11547                 :            : [clinic start generated code]*/
       11548                 :            :
       11549                 :            : static PyObject *
       11550                 :      27557 : unicode_join(PyObject *self, PyObject *iterable)
       11551                 :            : /*[clinic end generated code: output=6857e7cecfe7bf98 input=2f70422bfb8fa189]*/
       11552                 :            : {
       11553                 :      27557 :     return PyUnicode_Join(self, iterable);
       11554                 :            : }
       11555                 :            :
       11556                 :            : static Py_ssize_t
       11557                 :      42224 : unicode_length(PyObject *self)
       11558                 :            : {
       11559                 :      42224 :     return PyUnicode_GET_LENGTH(self);
       11560                 :            : }
       11561                 :            :
       11562                 :            : /*[clinic input]
       11563                 :            : str.ljust as unicode_ljust
       11564                 :            :
       11565                 :            :     width: Py_ssize_t
       11566                 :            :     fillchar: Py_UCS4 = ' '
       11567                 :            :     /
       11568                 :            :
       11569                 :            : Return a left-justified string of length width.
       11570                 :            :
       11571                 :            : Padding is done using the specified fill character (default is a space).
       11572                 :            : [clinic start generated code]*/
       11573                 :            :
       11574                 :            : static PyObject *
       11575                 :          0 : unicode_ljust_impl(PyObject *self, Py_ssize_t width, Py_UCS4 fillchar)
       11576                 :            : /*[clinic end generated code: output=1cce0e0e0a0b84b3 input=3ab599e335e60a32]*/
       11577                 :            : {
       11578         [ #  # ]:          0 :     if (PyUnicode_GET_LENGTH(self) >= width)
       11579                 :          0 :         return unicode_result_unchanged(self);
       11580                 :            :
       11581                 :          0 :     return pad(self, 0, width - PyUnicode_GET_LENGTH(self), fillchar);
       11582                 :            : }
       11583                 :            :
       11584                 :            : /*[clinic input]
       11585                 :            : str.lower as unicode_lower
       11586                 :            :
       11587                 :            : Return a copy of the string converted to lowercase.
       11588                 :            : [clinic start generated code]*/
       11589                 :            :
       11590                 :            : static PyObject *
       11591                 :        127 : unicode_lower_impl(PyObject *self)
       11592                 :            : /*[clinic end generated code: output=84ef9ed42efad663 input=60a2984b8beff23a]*/
       11593                 :            : {
       11594         [ +  - ]:        127 :     if (PyUnicode_IS_ASCII(self))
       11595                 :        127 :         return ascii_upper_or_lower(self, 1);
       11596                 :          0 :     return case_operation(self, do_lower);
       11597                 :            : }
       11598                 :            :
       11599                 :            : #define LEFTSTRIP 0
       11600                 :            : #define RIGHTSTRIP 1
       11601                 :            : #define BOTHSTRIP 2
       11602                 :            :
       11603                 :            : /* Arrays indexed by above */
       11604                 :            : static const char *stripfuncnames[] = {"lstrip", "rstrip", "strip"};
       11605                 :            :
       11606                 :            : #define STRIPNAME(i) (stripfuncnames[i])
       11607                 :            :
       11608                 :            : /* externally visible for str.strip(unicode) */
       11609                 :            : PyObject *
       11610                 :      11403 : _PyUnicode_XStrip(PyObject *self, int striptype, PyObject *sepobj)
       11611                 :            : {
       11612                 :            :     const void *data;
       11613                 :            :     int kind;
       11614                 :            :     Py_ssize_t i, j, len;
       11615                 :            :     BLOOM_MASK sepmask;
       11616                 :            :     Py_ssize_t seplen;
       11617                 :            :
       11618                 :      11403 :     kind = PyUnicode_KIND(self);
       11619                 :      11403 :     data = PyUnicode_DATA(self);
       11620                 :      11403 :     len = PyUnicode_GET_LENGTH(self);
       11621                 :      11403 :     seplen = PyUnicode_GET_LENGTH(sepobj);
       11622                 :      11403 :     sepmask = make_bloom_mask(PyUnicode_KIND(sepobj),
       11623                 :      11403 :                               PyUnicode_DATA(sepobj),
       11624                 :            :                               seplen);
       11625                 :            :
       11626                 :      11403 :     i = 0;
       11627         [ +  + ]:      11403 :     if (striptype != RIGHTSTRIP) {
       11628         [ +  - ]:        143 :         while (i < len) {
       11629                 :        143 :             Py_UCS4 ch = PyUnicode_READ(kind, data, i);
       11630         [ +  + ]:        143 :             if (!BLOOM(sepmask, ch))
       11631                 :         62 :                 break;
       11632         [ +  + ]:         81 :             if (PyUnicode_FindChar(sepobj, ch, 0, seplen, 1) < 0)
       11633                 :          1 :                 break;
       11634                 :         80 :             i++;
       11635                 :            :         }
       11636                 :            :     }
       11637                 :            :
       11638                 :      11403 :     j = len;
       11639         [ +  + ]:      11403 :     if (striptype != LEFTSTRIP) {
       11640                 :      11340 :         j--;
       11641         [ +  - ]:      11407 :         while (j >= i) {
       11642                 :      11407 :             Py_UCS4 ch = PyUnicode_READ(kind, data, j);
       11643         [ +  + ]:      11407 :             if (!BLOOM(sepmask, ch))
       11644                 :       8422 :                 break;
       11645         [ +  + ]:       2985 :             if (PyUnicode_FindChar(sepobj, ch, 0, seplen, 1) < 0)
       11646                 :       2918 :                 break;
       11647                 :         67 :             j--;
       11648                 :            :         }
       11649                 :            :
       11650                 :      11340 :         j++;
       11651                 :            :     }
       11652                 :            :
       11653                 :      11403 :     return PyUnicode_Substring(self, i, j);
       11654                 :            : }
       11655                 :            :
       11656                 :            : PyObject*
       11657                 :     769389 : PyUnicode_Substring(PyObject *self, Py_ssize_t start, Py_ssize_t end)
       11658                 :            : {
       11659                 :            :     const unsigned char *data;
       11660                 :            :     int kind;
       11661                 :            :     Py_ssize_t length;
       11662                 :            :
       11663                 :     769389 :     length = PyUnicode_GET_LENGTH(self);
       11664                 :     769389 :     end = Py_MIN(end, length);
       11665                 :            :
       11666   [ +  +  +  + ]:     769389 :     if (start == 0 && end == length)
       11667                 :      12591 :         return unicode_result_unchanged(self);
       11668                 :            :
       11669   [ +  -  -  + ]:     756798 :     if (start < 0 || end < 0) {
       11670                 :          0 :         PyErr_SetString(PyExc_IndexError, "string index out of range");
       11671                 :          0 :         return NULL;
       11672                 :            :     }
       11673   [ +  +  -  + ]:     756798 :     if (start >= length || end < start)
       11674                 :        731 :         _Py_RETURN_UNICODE_EMPTY();
       11675                 :            :
       11676                 :     756067 :     length = end - start;
       11677         [ +  + ]:     756067 :     if (PyUnicode_IS_ASCII(self)) {
       11678                 :     747401 :         data = PyUnicode_1BYTE_DATA(self);
       11679                 :     747401 :         return _PyUnicode_FromASCII((const char*)(data + start), length);
       11680                 :            :     }
       11681                 :            :     else {
       11682                 :       8666 :         kind = PyUnicode_KIND(self);
       11683                 :       8666 :         data = PyUnicode_1BYTE_DATA(self);
       11684                 :       8666 :         return PyUnicode_FromKindAndData(kind,
       11685                 :       8666 :                                          data + kind * start,
       11686                 :            :                                          length);
       11687                 :            :     }
       11688                 :            : }
       11689                 :            :
       11690                 :            : static PyObject *
       11691                 :       7298 : do_strip(PyObject *self, int striptype)
       11692                 :            : {
       11693                 :            :     Py_ssize_t len, i, j;
       11694                 :            :
       11695                 :       7298 :     len = PyUnicode_GET_LENGTH(self);
       11696                 :            :
       11697         [ +  - ]:       7298 :     if (PyUnicode_IS_ASCII(self)) {
       11698                 :       7298 :         const Py_UCS1 *data = PyUnicode_1BYTE_DATA(self);
       11699                 :            :
       11700                 :       7298 :         i = 0;
       11701         [ +  - ]:       7298 :         if (striptype != RIGHTSTRIP) {
       11702         [ +  + ]:      12179 :             while (i < len) {
       11703                 :      11268 :                 Py_UCS1 ch = data[i];
       11704         [ +  + ]:      11268 :                 if (!_Py_ascii_whitespace[ch])
       11705                 :       6387 :                     break;
       11706                 :       4881 :                 i++;
       11707                 :            :             }
       11708                 :            :         }
       11709                 :            :
       11710                 :       7298 :         j = len;
       11711         [ +  + ]:       7298 :         if (striptype != LEFTSTRIP) {
       11712                 :       7279 :             j--;
       11713         [ +  + ]:      13219 :             while (j >= i) {
       11714                 :      12308 :                 Py_UCS1 ch = data[j];
       11715         [ +  + ]:      12308 :                 if (!_Py_ascii_whitespace[ch])
       11716                 :       6368 :                     break;
       11717                 :       5940 :                 j--;
       11718                 :            :             }
       11719                 :       7279 :             j++;
       11720                 :            :         }
       11721                 :            :     }
       11722                 :            :     else {
       11723                 :          0 :         int kind = PyUnicode_KIND(self);
       11724                 :          0 :         const void *data = PyUnicode_DATA(self);
       11725                 :            :
       11726                 :          0 :         i = 0;
       11727         [ #  # ]:          0 :         if (striptype != RIGHTSTRIP) {
       11728         [ #  # ]:          0 :             while (i < len) {
       11729                 :          0 :                 Py_UCS4 ch = PyUnicode_READ(kind, data, i);
       11730         [ #  # ]:          0 :                 if (!Py_UNICODE_ISSPACE(ch))
       11731                 :          0 :                     break;
       11732                 :          0 :                 i++;
       11733                 :            :             }
       11734                 :            :         }
       11735                 :            :
       11736                 :          0 :         j = len;
       11737         [ #  # ]:          0 :         if (striptype != LEFTSTRIP) {
       11738                 :          0 :             j--;
       11739         [ #  # ]:          0 :             while (j >= i) {
       11740                 :          0 :                 Py_UCS4 ch = PyUnicode_READ(kind, data, j);
       11741         [ #  # ]:          0 :                 if (!Py_UNICODE_ISSPACE(ch))
       11742                 :          0 :                     break;
       11743                 :          0 :                 j--;
       11744                 :            :             }
       11745                 :          0 :             j++;
       11746                 :            :         }
       11747                 :            :     }
       11748                 :            :
       11749                 :       7298 :     return PyUnicode_Substring(self, i, j);
       11750                 :            : }
       11751                 :            :
       11752                 :            :
       11753                 :            : static PyObject *
       11754                 :      18701 : do_argstrip(PyObject *self, int striptype, PyObject *sep)
       11755                 :            : {
       11756         [ +  + ]:      18701 :     if (sep != Py_None) {
       11757         [ +  - ]:      11403 :         if (PyUnicode_Check(sep))
       11758                 :      11403 :             return _PyUnicode_XStrip(self, striptype, sep);
       11759                 :            :         else {
       11760                 :          0 :             PyErr_Format(PyExc_TypeError,
       11761                 :            :                          "%s arg must be None or str",
       11762                 :            :                          STRIPNAME(striptype));
       11763                 :          0 :             return NULL;
       11764                 :            :         }
       11765                 :            :     }
       11766                 :            :
       11767                 :       7298 :     return do_strip(self, striptype);
       11768                 :            : }
       11769                 :            :
       11770                 :            :
       11771                 :            : /*[clinic input]
       11772                 :            : str.strip as unicode_strip
       11773                 :            :
       11774                 :            :     chars: object = None
       11775                 :            :     /
       11776                 :            :
       11777                 :            : Return a copy of the string with leading and trailing whitespace removed.
       11778                 :            :
       11779                 :            : If chars is given and not None, remove characters in chars instead.
       11780                 :            : [clinic start generated code]*/
       11781                 :            :
       11782                 :            : static PyObject *
       11783                 :       7279 : unicode_strip_impl(PyObject *self, PyObject *chars)
       11784                 :            : /*[clinic end generated code: output=ca19018454345d57 input=385289c6f423b954]*/
       11785                 :            : {
       11786                 :       7279 :     return do_argstrip(self, BOTHSTRIP, chars);
       11787                 :            : }
       11788                 :            :
       11789                 :            :
       11790                 :            : /*[clinic input]
       11791                 :            : str.lstrip as unicode_lstrip
       11792                 :            :
       11793                 :            :     chars: object = None
       11794                 :            :     /
       11795                 :            :
       11796                 :            : Return a copy of the string with leading whitespace removed.
       11797                 :            :
       11798                 :            : If chars is given and not None, remove characters in chars instead.
       11799                 :            : [clinic start generated code]*/
       11800                 :            :
       11801                 :            : static PyObject *
       11802                 :         82 : unicode_lstrip_impl(PyObject *self, PyObject *chars)
       11803                 :            : /*[clinic end generated code: output=3b43683251f79ca7 input=529f9f3834448671]*/
       11804                 :            : {
       11805                 :         82 :     return do_argstrip(self, LEFTSTRIP, chars);
       11806                 :            : }
       11807                 :            :
       11808                 :            :
       11809                 :            : /*[clinic input]
       11810                 :            : str.rstrip as unicode_rstrip
       11811                 :            :
       11812                 :            :     chars: object = None
       11813                 :            :     /
       11814                 :            :
       11815                 :            : Return a copy of the string with trailing whitespace removed.
       11816                 :            :
       11817                 :            : If chars is given and not None, remove characters in chars instead.
       11818                 :            : [clinic start generated code]*/
       11819                 :            :
       11820                 :            : static PyObject *
       11821                 :      11340 : unicode_rstrip_impl(PyObject *self, PyObject *chars)
       11822                 :            : /*[clinic end generated code: output=4a59230017cc3b7a input=62566c627916557f]*/
       11823                 :            : {
       11824                 :      11340 :     return do_argstrip(self, RIGHTSTRIP, chars);
       11825                 :            : }
       11826                 :            :
       11827                 :            :
       11828                 :            : static PyObject*
       11829                 :     146935 : unicode_repeat(PyObject *str, Py_ssize_t len)
       11830                 :            : {
       11831                 :            :     PyObject *u;
       11832                 :            :     Py_ssize_t nchars, n;
       11833                 :            :
       11834         [ +  + ]:     146935 :     if (len < 1)
       11835                 :      18096 :         _Py_RETURN_UNICODE_EMPTY();
       11836                 :            :
       11837                 :            :     /* no repeat, return original string */
       11838         [ +  + ]:     128839 :     if (len == 1)
       11839                 :      49770 :         return unicode_result_unchanged(str);
       11840                 :            :
       11841         [ -  + ]:      79069 :     if (PyUnicode_GET_LENGTH(str) > PY_SSIZE_T_MAX / len) {
       11842                 :          0 :         PyErr_SetString(PyExc_OverflowError,
       11843                 :            :                         "repeated string is too long");
       11844                 :          0 :         return NULL;
       11845                 :            :     }
       11846                 :      79069 :     nchars = len * PyUnicode_GET_LENGTH(str);
       11847                 :            :
       11848                 :      79069 :     u = PyUnicode_New(nchars, PyUnicode_MAX_CHAR_VALUE(str));
       11849         [ -  + ]:      79069 :     if (!u)
       11850                 :          0 :         return NULL;
       11851                 :            :     assert(PyUnicode_KIND(u) == PyUnicode_KIND(str));
       11852                 :            :
       11853         [ +  + ]:      79069 :     if (PyUnicode_GET_LENGTH(str) == 1) {
       11854                 :        295 :         int kind = PyUnicode_KIND(str);
       11855                 :        295 :         Py_UCS4 fill_char = PyUnicode_READ(kind, PyUnicode_DATA(str), 0);
       11856         [ +  - ]:        295 :         if (kind == PyUnicode_1BYTE_KIND) {
       11857                 :        295 :             void *to = PyUnicode_DATA(u);
       11858                 :        295 :             memset(to, (unsigned char)fill_char, len);
       11859                 :            :         }
       11860         [ #  # ]:          0 :         else if (kind == PyUnicode_2BYTE_KIND) {
       11861                 :          0 :             Py_UCS2 *ucs2 = PyUnicode_2BYTE_DATA(u);
       11862         [ #  # ]:          0 :             for (n = 0; n < len; ++n)
       11863                 :          0 :                 ucs2[n] = fill_char;
       11864                 :            :         } else {
       11865                 :          0 :             Py_UCS4 *ucs4 = PyUnicode_4BYTE_DATA(u);
       11866                 :            :             assert(kind == PyUnicode_4BYTE_KIND);
       11867         [ #  # ]:          0 :             for (n = 0; n < len; ++n)
       11868                 :          0 :                 ucs4[n] = fill_char;
       11869                 :            :         }
       11870                 :            :     }
       11871                 :            :     else {
       11872                 :      78774 :         Py_ssize_t char_size = PyUnicode_KIND(str);
       11873                 :      78774 :         char *to = (char *) PyUnicode_DATA(u);
       11874                 :      78774 :         _PyBytes_Repeat(to, nchars * char_size, PyUnicode_DATA(str),
       11875                 :      78774 :             PyUnicode_GET_LENGTH(str) * char_size);
       11876                 :            :     }
       11877                 :            :
       11878                 :            :     assert(_PyUnicode_CheckConsistency(u, 1));
       11879                 :      79069 :     return u;
       11880                 :            : }
       11881                 :            :
       11882                 :            : PyObject *
       11883                 :          1 : PyUnicode_Replace(PyObject *str,
       11884                 :            :                   PyObject *substr,
       11885                 :            :                   PyObject *replstr,
       11886                 :            :                   Py_ssize_t maxcount)
       11887                 :            : {
       11888   [ +  -  +  -  :          2 :     if (ensure_unicode(str) < 0 || ensure_unicode(substr) < 0 ||
                       -  + ]
       11889                 :          1 :             ensure_unicode(replstr) < 0)
       11890                 :          0 :         return NULL;
       11891                 :          1 :     return replace(str, substr, replstr, maxcount);
       11892                 :            : }
       11893                 :            :
       11894                 :            : /*[clinic input]
       11895                 :            : str.replace as unicode_replace
       11896                 :            :
       11897                 :            :     old: unicode
       11898                 :            :     new: unicode
       11899                 :            :     count: Py_ssize_t = -1
       11900                 :            :         Maximum number of occurrences to replace.
       11901                 :            :         -1 (the default value) means replace all occurrences.
       11902                 :            :     /
       11903                 :            :
       11904                 :            : Return a copy with all occurrences of substring old replaced by new.
       11905                 :            :
       11906                 :            : If the optional argument count is given, only the first count occurrences are
       11907                 :            : replaced.
       11908                 :            : [clinic start generated code]*/
       11909                 :            :
       11910                 :            : static PyObject *
       11911                 :       5727 : unicode_replace_impl(PyObject *self, PyObject *old, PyObject *new,
       11912                 :            :                      Py_ssize_t count)
       11913                 :            : /*[clinic end generated code: output=b63f1a8b5eebf448 input=147d12206276ebeb]*/
       11914                 :            : {
       11915                 :       5727 :     return replace(self, old, new, count);
       11916                 :            : }
       11917                 :            :
       11918                 :            : /*[clinic input]
       11919                 :            : str.removeprefix as unicode_removeprefix
       11920                 :            :
       11921                 :            :     prefix: unicode
       11922                 :            :     /
       11923                 :            :
       11924                 :            : Return a str with the given prefix string removed if present.
       11925                 :            :
       11926                 :            : If the string starts with the prefix string, return string[len(prefix):].
       11927                 :            : Otherwise, return a copy of the original string.
       11928                 :            : [clinic start generated code]*/
       11929                 :            :
       11930                 :            : static PyObject *
       11931                 :         80 : unicode_removeprefix_impl(PyObject *self, PyObject *prefix)
       11932                 :            : /*[clinic end generated code: output=f1e5945e9763bcb9 input=27ec40b99a37eb88]*/
       11933                 :            : {
       11934                 :         80 :     int match = tailmatch(self, prefix, 0, PY_SSIZE_T_MAX, -1);
       11935         [ -  + ]:         80 :     if (match == -1) {
       11936                 :          0 :         return NULL;
       11937                 :            :     }
       11938         [ -  + ]:         80 :     if (match) {
       11939                 :          0 :         return PyUnicode_Substring(self, PyUnicode_GET_LENGTH(prefix),
       11940                 :            :                                    PyUnicode_GET_LENGTH(self));
       11941                 :            :     }
       11942                 :         80 :     return unicode_result_unchanged(self);
       11943                 :            : }
       11944                 :            :
       11945                 :            : /*[clinic input]
       11946                 :            : str.removesuffix as unicode_removesuffix
       11947                 :            :
       11948                 :            :     suffix: unicode
       11949                 :            :     /
       11950                 :            :
       11951                 :            : Return a str with the given suffix string removed if present.
       11952                 :            :
       11953                 :            : If the string ends with the suffix string and that suffix is not empty,
       11954                 :            : return string[:-len(suffix)]. Otherwise, return a copy of the original
       11955                 :            : string.
       11956                 :            : [clinic start generated code]*/
       11957                 :            :
       11958                 :            : static PyObject *
       11959                 :          0 : unicode_removesuffix_impl(PyObject *self, PyObject *suffix)
       11960                 :            : /*[clinic end generated code: output=d36629e227636822 input=12cc32561e769be4]*/
       11961                 :            : {
       11962                 :          0 :     int match = tailmatch(self, suffix, 0, PY_SSIZE_T_MAX, +1);
       11963         [ #  # ]:          0 :     if (match == -1) {
       11964                 :          0 :         return NULL;
       11965                 :            :     }
       11966         [ #  # ]:          0 :     if (match) {
       11967                 :          0 :         return PyUnicode_Substring(self, 0, PyUnicode_GET_LENGTH(self)
       11968                 :          0 :                                             - PyUnicode_GET_LENGTH(suffix));
       11969                 :            :     }
       11970                 :          0 :     return unicode_result_unchanged(self);
       11971                 :            : }
       11972                 :            :
       11973                 :            : static PyObject *
       11974                 :     112359 : unicode_repr(PyObject *unicode)
       11975                 :            : {
       11976                 :            :     PyObject *repr;
       11977                 :            :     Py_ssize_t isize;
       11978                 :            :     Py_ssize_t osize, squote, dquote, i, o;
       11979                 :            :     Py_UCS4 max, quote;
       11980                 :            :     int ikind, okind, unchanged;
       11981                 :            :     const void *idata;
       11982                 :            :     void *odata;
       11983                 :            :
       11984                 :     112359 :     isize = PyUnicode_GET_LENGTH(unicode);
       11985                 :     112359 :     idata = PyUnicode_DATA(unicode);
       11986                 :            :
       11987                 :            :     /* Compute length of output, quote characters, and
       11988                 :            :        maximum character */
       11989                 :     112359 :     osize = 0;
       11990                 :     112359 :     max = 127;
       11991                 :     112359 :     squote = dquote = 0;
       11992                 :     112359 :     ikind = PyUnicode_KIND(unicode);
       11993         [ +  + ]:    1857945 :     for (i = 0; i < isize; i++) {
       11994                 :    1745586 :         Py_UCS4 ch = PyUnicode_READ(ikind, idata, i);
       11995                 :    1745586 :         Py_ssize_t incr = 1;
       11996   [ +  +  +  + ]:    1745586 :         switch (ch) {
       11997                 :       2022 :         case '\'': squote++; break;
       11998                 :        327 :         case '"':  dquote++; break;
       11999                 :       8718 :         case '\\': case '\t': case '\r': case '\n':
       12000                 :       8718 :             incr = 2;
       12001                 :       8718 :             break;
       12002                 :    1734519 :         default:
       12003                 :            :             /* Fast-path ASCII */
       12004   [ +  +  +  + ]:    1734519 :             if (ch < ' ' || ch == 0x7f)
       12005                 :         90 :                 incr = 4; /* \xHH */
       12006         [ +  + ]:    1734429 :             else if (ch < 0x7f)
       12007                 :            :                 ;
       12008         [ +  + ]:        409 :             else if (Py_UNICODE_ISPRINTABLE(ch))
       12009                 :        406 :                 max = ch > max ? ch : max;
       12010         [ +  - ]:          3 :             else if (ch < 0x100)
       12011                 :          3 :                 incr = 4; /* \xHH */
       12012         [ #  # ]:          0 :             else if (ch < 0x10000)
       12013                 :          0 :                 incr = 6; /* \uHHHH */
       12014                 :            :             else
       12015                 :          0 :                 incr = 10; /* \uHHHHHHHH */
       12016                 :            :         }
       12017         [ -  + ]:    1745586 :         if (osize > PY_SSIZE_T_MAX - incr) {
       12018                 :          0 :             PyErr_SetString(PyExc_OverflowError,
       12019                 :            :                             "string is too long to generate repr");
       12020                 :          0 :             return NULL;
       12021                 :            :         }
       12022                 :    1745586 :         osize += incr;
       12023                 :            :     }
       12024                 :            :
       12025                 :     112359 :     quote = '\'';
       12026                 :     112359 :     unchanged = (osize == isize);
       12027         [ +  + ]:     112359 :     if (squote) {
       12028                 :        596 :         unchanged = 0;
       12029         [ +  + ]:        596 :         if (dquote)
       12030                 :            :             /* Both squote and dquote present. Use squote,
       12031                 :            :                and escape them */
       12032                 :         21 :             osize += squote;
       12033                 :            :         else
       12034                 :        575 :             quote = '"';
       12035                 :            :     }
       12036                 :     112359 :     osize += 2;   /* quotes */
       12037                 :            :
       12038                 :     112359 :     repr = PyUnicode_New(osize, max);
       12039         [ -  + ]:     112359 :     if (repr == NULL)
       12040                 :          0 :         return NULL;
       12041                 :     112359 :     okind = PyUnicode_KIND(repr);
       12042                 :     112359 :     odata = PyUnicode_DATA(repr);
       12043                 :            :
       12044                 :     112359 :     PyUnicode_WRITE(okind, odata, 0, quote);
       12045                 :     112359 :     PyUnicode_WRITE(okind, odata, osize-1, quote);
       12046         [ +  + ]:     112359 :     if (unchanged) {
       12047                 :     110490 :         _PyUnicode_FastCopyCharacters(repr, 1,
       12048                 :            :                                       unicode, 0,
       12049                 :            :                                       isize);
       12050                 :            :     }
       12051                 :            :     else {
       12052         [ +  + ]:     377907 :         for (i = 0, o = 1; i < isize; i++) {
       12053                 :     376038 :             Py_UCS4 ch = PyUnicode_READ(ikind, idata, i);
       12054                 :            :
       12055                 :            :             /* Escape quotes and backslashes */
       12056   [ +  +  +  + ]:     376038 :             if ((ch == quote) || (ch == '\\')) {
       12057                 :        667 :                 PyUnicode_WRITE(okind, odata, o++, '\\');
       12058                 :        667 :                 PyUnicode_WRITE(okind, odata, o++, ch);
       12059                 :        667 :                 continue;
       12060                 :            :             }
       12061                 :            :
       12062                 :            :             /* Map special whitespace to '\t', \n', '\r' */
       12063         [ +  + ]:     375371 :             if (ch == '\t') {
       12064                 :          9 :                 PyUnicode_WRITE(okind, odata, o++, '\\');
       12065                 :          9 :                 PyUnicode_WRITE(okind, odata, o++, 't');
       12066                 :            :             }
       12067         [ +  + ]:     375362 :             else if (ch == '\n') {
       12068                 :       8220 :                 PyUnicode_WRITE(okind, odata, o++, '\\');
       12069                 :       8220 :                 PyUnicode_WRITE(okind, odata, o++, 'n');
       12070                 :            :             }
       12071         [ +  + ]:     367142 :             else if (ch == '\r') {
       12072                 :         13 :                 PyUnicode_WRITE(okind, odata, o++, '\\');
       12073                 :         13 :                 PyUnicode_WRITE(okind, odata, o++, 'r');
       12074                 :            :             }
       12075                 :            :
       12076                 :            :             /* Map non-printable US ASCII to '\xhh' */
       12077   [ +  +  +  + ]:     367129 :             else if (ch < ' ' || ch == 0x7F) {
       12078                 :         90 :                 PyUnicode_WRITE(okind, odata, o++, '\\');
       12079                 :         90 :                 PyUnicode_WRITE(okind, odata, o++, 'x');
       12080                 :         90 :                 PyUnicode_WRITE(okind, odata, o++, Py_hexdigits[(ch >> 4) & 0x000F]);
       12081                 :         90 :                 PyUnicode_WRITE(okind, odata, o++, Py_hexdigits[ch & 0x000F]);
       12082                 :            :             }
       12083                 :            :
       12084                 :            :             /* Copy ASCII characters as-is */
       12085         [ +  + ]:     367039 :             else if (ch < 0x7F) {
       12086                 :     366645 :                 PyUnicode_WRITE(okind, odata, o++, ch);
       12087                 :            :             }
       12088                 :            :
       12089                 :            :             /* Non-ASCII characters */
       12090                 :            :             else {
       12091                 :            :                 /* Map Unicode whitespace and control characters
       12092                 :            :                    (categories Z* and C* except ASCII space)
       12093                 :            :                 */
       12094         [ +  + ]:        394 :                 if (!Py_UNICODE_ISPRINTABLE(ch)) {
       12095                 :          3 :                     PyUnicode_WRITE(okind, odata, o++, '\\');
       12096                 :            :                     /* Map 8-bit characters to '\xhh' */
       12097         [ +  - ]:          3 :                     if (ch <= 0xff) {
       12098                 :          3 :                         PyUnicode_WRITE(okind, odata, o++, 'x');
       12099                 :          3 :                         PyUnicode_WRITE(okind, odata, o++, Py_hexdigits[(ch >> 4) & 0x000F]);
       12100                 :          3 :                         PyUnicode_WRITE(okind, odata, o++, Py_hexdigits[ch & 0x000F]);
       12101                 :            :                     }
       12102                 :            :                     /* Map 16-bit characters to '\uxxxx' */
       12103         [ #  # ]:          0 :                     else if (ch <= 0xffff) {
       12104                 :          0 :                         PyUnicode_WRITE(okind, odata, o++, 'u');
       12105                 :          0 :                         PyUnicode_WRITE(okind, odata, o++, Py_hexdigits[(ch >> 12) & 0xF]);
       12106                 :          0 :                         PyUnicode_WRITE(okind, odata, o++, Py_hexdigits[(ch >> 8) & 0xF]);
       12107                 :          0 :                         PyUnicode_WRITE(okind, odata, o++, Py_hexdigits[(ch >> 4) & 0xF]);
       12108                 :          0 :                         PyUnicode_WRITE(okind, odata, o++, Py_hexdigits[ch & 0xF]);
       12109                 :            :                     }
       12110                 :            :                     /* Map 21-bit characters to '\U00xxxxxx' */
       12111                 :            :                     else {
       12112                 :          0 :                         PyUnicode_WRITE(okind, odata, o++, 'U');
       12113                 :          0 :                         PyUnicode_WRITE(okind, odata, o++, Py_hexdigits[(ch >> 28) & 0xF]);
       12114                 :          0 :                         PyUnicode_WRITE(okind, odata, o++, Py_hexdigits[(ch >> 24) & 0xF]);
       12115                 :          0 :                         PyUnicode_WRITE(okind, odata, o++, Py_hexdigits[(ch >> 20) & 0xF]);
       12116                 :          0 :                         PyUnicode_WRITE(okind, odata, o++, Py_hexdigits[(ch >> 16) & 0xF]);
       12117                 :          0 :                         PyUnicode_WRITE(okind, odata, o++, Py_hexdigits[(ch >> 12) & 0xF]);
       12118                 :          0 :                         PyUnicode_WRITE(okind, odata, o++, Py_hexdigits[(ch >> 8) & 0xF]);
       12119                 :          0 :                         PyUnicode_WRITE(okind, odata, o++, Py_hexdigits[(ch >> 4) & 0xF]);
       12120                 :          0 :                         PyUnicode_WRITE(okind, odata, o++, Py_hexdigits[ch & 0xF]);
       12121                 :            :                     }
       12122                 :            :                 }
       12123                 :            :                 /* Copy characters as-is */
       12124                 :            :                 else {
       12125                 :        391 :                     PyUnicode_WRITE(okind, odata, o++, ch);
       12126                 :            :                 }
       12127                 :            :             }
       12128                 :            :         }
       12129                 :            :     }
       12130                 :            :     /* Closing quote already added at the beginning */
       12131                 :            :     assert(_PyUnicode_CheckConsistency(repr, 1));
       12132                 :     112359 :     return repr;
       12133                 :            : }
       12134                 :            :
       12135                 :            : PyDoc_STRVAR(rfind__doc__,
       12136                 :            :              "S.rfind(sub[, start[, end]]) -> int\n\
       12137                 :            : \n\
       12138                 :            : Return the highest index in S where substring sub is found,\n\
       12139                 :            : such that sub is contained within S[start:end].  Optional\n\
       12140                 :            : arguments start and end are interpreted as in slice notation.\n\
       12141                 :            : \n\
       12142                 :            : Return -1 on failure.");
       12143                 :            :
       12144                 :            : static PyObject *
       12145                 :       2733 : unicode_rfind(PyObject *self, PyObject *args)
       12146                 :            : {
       12147                 :            :     /* initialize variables to prevent gcc warning */
       12148                 :       2733 :     PyObject *substring = NULL;
       12149                 :       2733 :     Py_ssize_t start = 0;
       12150                 :       2733 :     Py_ssize_t end = 0;
       12151                 :            :     Py_ssize_t result;
       12152                 :            :
       12153         [ -  + ]:       2733 :     if (!parse_args_finds_unicode("rfind", args, &substring, &start, &end))
       12154                 :          0 :         return NULL;
       12155                 :            :
       12156                 :       2733 :     result = any_find_slice(self, substring, start, end, -1);
       12157                 :            :
       12158         [ -  + ]:       2733 :     if (result == -2)
       12159                 :          0 :         return NULL;
       12160                 :            :
       12161                 :       2733 :     return PyLong_FromSsize_t(result);
       12162                 :            : }
       12163                 :            :
       12164                 :            : PyDoc_STRVAR(rindex__doc__,
       12165                 :            :              "S.rindex(sub[, start[, end]]) -> int\n\
       12166                 :            : \n\
       12167                 :            : Return the highest index in S where substring sub is found,\n\
       12168                 :            : such that sub is contained within S[start:end].  Optional\n\
       12169                 :            : arguments start and end are interpreted as in slice notation.\n\
       12170                 :            : \n\
       12171                 :            : Raises ValueError when the substring is not found.");
       12172                 :            :
       12173                 :            : static PyObject *
       12174                 :          0 : unicode_rindex(PyObject *self, PyObject *args)
       12175                 :            : {
       12176                 :            :     /* initialize variables to prevent gcc warning */
       12177                 :          0 :     PyObject *substring = NULL;
       12178                 :          0 :     Py_ssize_t start = 0;
       12179                 :          0 :     Py_ssize_t end = 0;
       12180                 :            :     Py_ssize_t result;
       12181                 :            :
       12182         [ #  # ]:          0 :     if (!parse_args_finds_unicode("rindex", args, &substring, &start, &end))
       12183                 :          0 :         return NULL;
       12184                 :            :
       12185                 :          0 :     result = any_find_slice(self, substring, start, end, -1);
       12186                 :            :
       12187         [ #  # ]:          0 :     if (result == -2)
       12188                 :          0 :         return NULL;
       12189                 :            :
       12190         [ #  # ]:          0 :     if (result < 0) {
       12191                 :          0 :         PyErr_SetString(PyExc_ValueError, "substring not found");
       12192                 :          0 :         return NULL;
       12193                 :            :     }
       12194                 :            :
       12195                 :          0 :     return PyLong_FromSsize_t(result);
       12196                 :            : }
       12197                 :            :
       12198                 :            : /*[clinic input]
       12199                 :            : str.rjust as unicode_rjust
       12200                 :            :
       12201                 :            :     width: Py_ssize_t
       12202                 :            :     fillchar: Py_UCS4 = ' '
       12203                 :            :     /
       12204                 :            :
       12205                 :            : Return a right-justified string of length width.
       12206                 :            :
       12207                 :            : Padding is done using the specified fill character (default is a space).
       12208                 :            : [clinic start generated code]*/
       12209                 :            :
       12210                 :            : static PyObject *
       12211                 :          0 : unicode_rjust_impl(PyObject *self, Py_ssize_t width, Py_UCS4 fillchar)
       12212                 :            : /*[clinic end generated code: output=804a1a57fbe8d5cf input=d05f550b5beb1f72]*/
       12213                 :            : {
       12214         [ #  # ]:          0 :     if (PyUnicode_GET_LENGTH(self) >= width)
       12215                 :          0 :         return unicode_result_unchanged(self);
       12216                 :            :
       12217                 :          0 :     return pad(self, width - PyUnicode_GET_LENGTH(self), 0, fillchar);
       12218                 :            : }
       12219                 :            :
       12220                 :            : PyObject *
       12221                 :          0 : PyUnicode_Split(PyObject *s, PyObject *sep, Py_ssize_t maxsplit)
       12222                 :            : {
       12223   [ #  #  #  #  :          0 :     if (ensure_unicode(s) < 0 || (sep != NULL && ensure_unicode(sep) < 0))
                       #  # ]
       12224                 :          0 :         return NULL;
       12225                 :            :
       12226                 :          0 :     return split(s, sep, maxsplit);
       12227                 :            : }
       12228                 :            :
       12229                 :            : /*[clinic input]
       12230                 :            : str.split as unicode_split
       12231                 :            :
       12232                 :            :     sep: object = None
       12233                 :            :         The separator used to split the string.
       12234                 :            :
       12235                 :            :         When set to None (the default value), will split on any whitespace
       12236                 :            :         character (including \\n \\r \\t \\f and spaces) and will discard
       12237                 :            :         empty strings from the result.
       12238                 :            :     maxsplit: Py_ssize_t = -1
       12239                 :            :         Maximum number of splits (starting from the left).
       12240                 :            :         -1 (the default value) means no limit.
       12241                 :            :
       12242                 :            : Return a list of the substrings in the string, using sep as the separator string.
       12243                 :            :
       12244                 :            : Note, str.split() is mainly useful for data that has been intentionally
       12245                 :            : delimited.  With natural text that includes punctuation, consider using
       12246                 :            : the regular expression module.
       12247                 :            :
       12248                 :            : [clinic start generated code]*/
       12249                 :            :
       12250                 :            : static PyObject *
       12251                 :       8074 : unicode_split_impl(PyObject *self, PyObject *sep, Py_ssize_t maxsplit)
       12252                 :            : /*[clinic end generated code: output=3a65b1db356948dc input=906d953b44efc43b]*/
       12253                 :            : {
       12254         [ +  + ]:       8074 :     if (sep == Py_None)
       12255                 :       5258 :         return split(self, NULL, maxsplit);
       12256         [ +  - ]:       2816 :     if (PyUnicode_Check(sep))
       12257                 :       2816 :         return split(self, sep, maxsplit);
       12258                 :            :
       12259                 :          0 :     PyErr_Format(PyExc_TypeError,
       12260                 :            :                  "must be str or None, not %.100s",
       12261                 :          0 :                  Py_TYPE(sep)->tp_name);
       12262                 :          0 :     return NULL;
       12263                 :            : }
       12264                 :            :
       12265                 :            : PyObject *
       12266                 :         36 : PyUnicode_Partition(PyObject *str_obj, PyObject *sep_obj)
       12267                 :            : {
       12268                 :            :     PyObject* out;
       12269                 :            :     int kind1, kind2;
       12270                 :            :     const void *buf1, *buf2;
       12271                 :            :     Py_ssize_t len1, len2;
       12272                 :            :
       12273   [ +  -  -  + ]:         36 :     if (ensure_unicode(str_obj) < 0 || ensure_unicode(sep_obj) < 0)
       12274                 :          0 :         return NULL;
       12275                 :            :
       12276                 :         36 :     kind1 = PyUnicode_KIND(str_obj);
       12277                 :         36 :     kind2 = PyUnicode_KIND(sep_obj);
       12278                 :         36 :     len1 = PyUnicode_GET_LENGTH(str_obj);
       12279                 :         36 :     len2 = PyUnicode_GET_LENGTH(sep_obj);
       12280   [ +  -  -  + ]:         36 :     if (kind1 < kind2 || len1 < len2) {
       12281                 :          0 :         PyObject *empty = unicode_get_empty();  // Borrowed reference
       12282                 :          0 :         return PyTuple_Pack(3, str_obj, empty, empty);
       12283                 :            :     }
       12284                 :         36 :     buf1 = PyUnicode_DATA(str_obj);
       12285                 :         36 :     buf2 = PyUnicode_DATA(sep_obj);
       12286         [ -  + ]:         36 :     if (kind2 != kind1) {
       12287                 :          0 :         buf2 = unicode_askind(kind2, buf2, len2, kind1);
       12288         [ #  # ]:          0 :         if (!buf2)
       12289                 :          0 :             return NULL;
       12290                 :            :     }
       12291                 :            :
       12292   [ +  -  -  - ]:         36 :     switch (kind1) {
       12293                 :         36 :     case PyUnicode_1BYTE_KIND:
       12294   [ +  +  +  - ]:         36 :         if (PyUnicode_IS_ASCII(str_obj) && PyUnicode_IS_ASCII(sep_obj))
       12295                 :         30 :             out = asciilib_partition(str_obj, buf1, len1, sep_obj, buf2, len2);
       12296                 :            :         else
       12297                 :          6 :             out = ucs1lib_partition(str_obj, buf1, len1, sep_obj, buf2, len2);
       12298                 :         36 :         break;
       12299                 :          0 :     case PyUnicode_2BYTE_KIND:
       12300                 :          0 :         out = ucs2lib_partition(str_obj, buf1, len1, sep_obj, buf2, len2);
       12301                 :          0 :         break;
       12302                 :          0 :     case PyUnicode_4BYTE_KIND:
       12303                 :          0 :         out = ucs4lib_partition(str_obj, buf1, len1, sep_obj, buf2, len2);
       12304                 :          0 :         break;
       12305                 :          0 :     default:
       12306                 :          0 :         Py_UNREACHABLE();
       12307                 :            :     }
       12308                 :            :
       12309                 :            :     assert((kind2 == kind1) == (buf2 == PyUnicode_DATA(sep_obj)));
       12310         [ -  + ]:         36 :     if (kind2 != kind1)
       12311                 :          0 :         PyMem_Free((void *)buf2);
       12312                 :            :
       12313                 :         36 :     return out;
       12314                 :            : }
       12315                 :            :
       12316                 :            :
       12317                 :            : PyObject *
       12318                 :       4387 : PyUnicode_RPartition(PyObject *str_obj, PyObject *sep_obj)
       12319                 :            : {
       12320                 :            :     PyObject* out;
       12321                 :            :     int kind1, kind2;
       12322                 :            :     const void *buf1, *buf2;
       12323                 :            :     Py_ssize_t len1, len2;
       12324                 :            :
       12325   [ +  -  -  + ]:       4387 :     if (ensure_unicode(str_obj) < 0 || ensure_unicode(sep_obj) < 0)
       12326                 :          0 :         return NULL;
       12327                 :            :
       12328                 :       4387 :     kind1 = PyUnicode_KIND(str_obj);
       12329                 :       4387 :     kind2 = PyUnicode_KIND(sep_obj);
       12330                 :       4387 :     len1 = PyUnicode_GET_LENGTH(str_obj);
       12331                 :       4387 :     len2 = PyUnicode_GET_LENGTH(sep_obj);
       12332   [ +  -  -  + ]:       4387 :     if (kind1 < kind2 || len1 < len2) {
       12333                 :          0 :         PyObject *empty = unicode_get_empty();  // Borrowed reference
       12334                 :          0 :         return PyTuple_Pack(3, empty, empty, str_obj);
       12335                 :            :     }
       12336                 :       4387 :     buf1 = PyUnicode_DATA(str_obj);
       12337                 :       4387 :     buf2 = PyUnicode_DATA(sep_obj);
       12338         [ -  + ]:       4387 :     if (kind2 != kind1) {
       12339                 :          0 :         buf2 = unicode_askind(kind2, buf2, len2, kind1);
       12340         [ #  # ]:          0 :         if (!buf2)
       12341                 :          0 :             return NULL;
       12342                 :            :     }
       12343                 :            :
       12344   [ +  -  -  - ]:       4387 :     switch (kind1) {
       12345                 :       4387 :     case PyUnicode_1BYTE_KIND:
       12346   [ +  -  +  - ]:       4387 :         if (PyUnicode_IS_ASCII(str_obj) && PyUnicode_IS_ASCII(sep_obj))
       12347                 :       4387 :             out = asciilib_rpartition(str_obj, buf1, len1, sep_obj, buf2, len2);
       12348                 :            :         else
       12349                 :          0 :             out = ucs1lib_rpartition(str_obj, buf1, len1, sep_obj, buf2, len2);
       12350                 :       4387 :         break;
       12351                 :          0 :     case PyUnicode_2BYTE_KIND:
       12352                 :          0 :         out = ucs2lib_rpartition(str_obj, buf1, len1, sep_obj, buf2, len2);
       12353                 :          0 :         break;
       12354                 :          0 :     case PyUnicode_4BYTE_KIND:
       12355                 :          0 :         out = ucs4lib_rpartition(str_obj, buf1, len1, sep_obj, buf2, len2);
       12356                 :          0 :         break;
       12357                 :          0 :     default:
       12358                 :          0 :         Py_UNREACHABLE();
       12359                 :            :     }
       12360                 :            :
       12361                 :            :     assert((kind2 == kind1) == (buf2 == PyUnicode_DATA(sep_obj)));
       12362         [ -  + ]:       4387 :     if (kind2 != kind1)
       12363                 :          0 :         PyMem_Free((void *)buf2);
       12364                 :            :
       12365                 :       4387 :     return out;
       12366                 :            : }
       12367                 :            :
       12368                 :            : /*[clinic input]
       12369                 :            : str.partition as unicode_partition
       12370                 :            :
       12371                 :            :     sep: object
       12372                 :            :     /
       12373                 :            :
       12374                 :            : Partition the string into three parts using the given separator.
       12375                 :            :
       12376                 :            : This will search for the separator in the string.  If the separator is found,
       12377                 :            : returns a 3-tuple containing the part before the separator, the separator
       12378                 :            : itself, and the part after it.
       12379                 :            :
       12380                 :            : If the separator is not found, returns a 3-tuple containing the original string
       12381                 :            : and two empty strings.
       12382                 :            : [clinic start generated code]*/
       12383                 :            :
       12384                 :            : static PyObject *
       12385                 :         36 : unicode_partition(PyObject *self, PyObject *sep)
       12386                 :            : /*[clinic end generated code: output=e4ced7bd253ca3c4 input=f29b8d06c63e50be]*/
       12387                 :            : {
       12388                 :         36 :     return PyUnicode_Partition(self, sep);
       12389                 :            : }
       12390                 :            :
       12391                 :            : /*[clinic input]
       12392                 :            : str.rpartition as unicode_rpartition = str.partition
       12393                 :            :
       12394                 :            : Partition the string into three parts using the given separator.
       12395                 :            :
       12396                 :            : This will search for the separator in the string, starting at the end. If
       12397                 :            : the separator is found, returns a 3-tuple containing the part before the
       12398                 :            : separator, the separator itself, and the part after it.
       12399                 :            :
       12400                 :            : If the separator is not found, returns a 3-tuple containing two empty strings
       12401                 :            : and the original string.
       12402                 :            : [clinic start generated code]*/
       12403                 :            :
       12404                 :            : static PyObject *
       12405                 :       4387 : unicode_rpartition(PyObject *self, PyObject *sep)
       12406                 :            : /*[clinic end generated code: output=1aa13cf1156572aa input=c4b7db3ef5cf336a]*/
       12407                 :            : {
       12408                 :       4387 :     return PyUnicode_RPartition(self, sep);
       12409                 :            : }
       12410                 :            :
       12411                 :            : PyObject *
       12412                 :          0 : PyUnicode_RSplit(PyObject *s, PyObject *sep, Py_ssize_t maxsplit)
       12413                 :            : {
       12414   [ #  #  #  #  :          0 :     if (ensure_unicode(s) < 0 || (sep != NULL && ensure_unicode(sep) < 0))
                       #  # ]
       12415                 :          0 :         return NULL;
       12416                 :            :
       12417                 :          0 :     return rsplit(s, sep, maxsplit);
       12418                 :            : }
       12419                 :            :
       12420                 :            : /*[clinic input]
       12421                 :            : str.rsplit as unicode_rsplit = str.split
       12422                 :            :
       12423                 :            : Return a list of the substrings in the string, using sep as the separator string.
       12424                 :            :
       12425                 :            : Splitting starts at the end of the string and works to the front.
       12426                 :            : [clinic start generated code]*/
       12427                 :            :
       12428                 :            : static PyObject *
       12429                 :         23 : unicode_rsplit_impl(PyObject *self, PyObject *sep, Py_ssize_t maxsplit)
       12430                 :            : /*[clinic end generated code: output=c2b815c63bcabffc input=ea78406060fce33c]*/
       12431                 :            : {
       12432         [ -  + ]:         23 :     if (sep == Py_None)
       12433                 :          0 :         return rsplit(self, NULL, maxsplit);
       12434         [ +  - ]:         23 :     if (PyUnicode_Check(sep))
       12435                 :         23 :         return rsplit(self, sep, maxsplit);
       12436                 :            :
       12437                 :          0 :     PyErr_Format(PyExc_TypeError,
       12438                 :            :                  "must be str or None, not %.100s",
       12439                 :          0 :                  Py_TYPE(sep)->tp_name);
       12440                 :          0 :     return NULL;
       12441                 :            : }
       12442                 :            :
       12443                 :            : /*[clinic input]
       12444                 :            : str.splitlines as unicode_splitlines
       12445                 :            :
       12446                 :            :     keepends: bool = False
       12447                 :            :
       12448                 :            : Return a list of the lines in the string, breaking at line boundaries.
       12449                 :            :
       12450                 :            : Line breaks are not included in the resulting list unless keepends is given and
       12451                 :            : true.
       12452                 :            : [clinic start generated code]*/
       12453                 :            :
       12454                 :            : static PyObject *
       12455                 :        108 : unicode_splitlines_impl(PyObject *self, int keepends)
       12456                 :            : /*[clinic end generated code: output=f664dcdad153ec40 input=ba6ad05ee85d2b55]*/
       12457                 :            : {
       12458                 :        108 :     return PyUnicode_Splitlines(self, keepends);
       12459                 :            : }
       12460                 :            :
       12461                 :            : static
       12462                 :          0 : PyObject *unicode_str(PyObject *self)
       12463                 :            : {
       12464                 :          0 :     return unicode_result_unchanged(self);
       12465                 :            : }
       12466                 :            :
       12467                 :            : /*[clinic input]
       12468                 :            : str.swapcase as unicode_swapcase
       12469                 :            :
       12470                 :            : Convert uppercase characters to lowercase and lowercase characters to uppercase.
       12471                 :            : [clinic start generated code]*/
       12472                 :            :
       12473                 :            : static PyObject *
       12474                 :          0 : unicode_swapcase_impl(PyObject *self)
       12475                 :            : /*[clinic end generated code: output=5d28966bf6d7b2af input=3f3ef96d5798a7bb]*/
       12476                 :            : {
       12477                 :          0 :     return case_operation(self, do_swapcase);
       12478                 :            : }
       12479                 :            :
       12480                 :            : /*[clinic input]
       12481                 :            :
       12482                 :            : @staticmethod
       12483                 :            : str.maketrans as unicode_maketrans
       12484                 :            :
       12485                 :            :   x: object
       12486                 :            :
       12487                 :            :   y: unicode=NULL
       12488                 :            :
       12489                 :            :   z: unicode=NULL
       12490                 :            :
       12491                 :            :   /
       12492                 :            :
       12493                 :            : Return a translation table usable for str.translate().
       12494                 :            :
       12495                 :            : If there is only one argument, it must be a dictionary mapping Unicode
       12496                 :            : ordinals (integers) or characters to Unicode ordinals, strings or None.
       12497                 :            : Character keys will be then converted to ordinals.
       12498                 :            : If there are two arguments, they must be strings of equal length, and
       12499                 :            : in the resulting dictionary, each character in x will be mapped to the
       12500                 :            : character at the same position in y. If there is a third argument, it
       12501                 :            : must be a string, whose characters will be mapped to None in the result.
       12502                 :            : [clinic start generated code]*/
       12503                 :            :
       12504                 :            : static PyObject *
       12505                 :          0 : unicode_maketrans_impl(PyObject *x, PyObject *y, PyObject *z)
       12506                 :            : /*[clinic end generated code: output=a925c89452bd5881 input=7bfbf529a293c6c5]*/
       12507                 :            : {
       12508                 :          0 :     PyObject *new = NULL, *key, *value;
       12509                 :          0 :     Py_ssize_t i = 0;
       12510                 :            :     int res;
       12511                 :            :
       12512                 :          0 :     new = PyDict_New();
       12513         [ #  # ]:          0 :     if (!new)
       12514                 :          0 :         return NULL;
       12515         [ #  # ]:          0 :     if (y != NULL) {
       12516                 :            :         int x_kind, y_kind, z_kind;
       12517                 :            :         const void *x_data, *y_data, *z_data;
       12518                 :            :
       12519                 :            :         /* x must be a string too, of equal length */
       12520         [ #  # ]:          0 :         if (!PyUnicode_Check(x)) {
       12521                 :          0 :             PyErr_SetString(PyExc_TypeError, "first maketrans argument must "
       12522                 :            :                             "be a string if there is a second argument");
       12523                 :          0 :             goto err;
       12524                 :            :         }
       12525         [ #  # ]:          0 :         if (PyUnicode_GET_LENGTH(x) != PyUnicode_GET_LENGTH(y)) {
       12526                 :          0 :             PyErr_SetString(PyExc_ValueError, "the first two maketrans "
       12527                 :            :                             "arguments must have equal length");
       12528                 :          0 :             goto err;
       12529                 :            :         }
       12530                 :            :         /* create entries for translating chars in x to those in y */
       12531                 :          0 :         x_kind = PyUnicode_KIND(x);
       12532                 :          0 :         y_kind = PyUnicode_KIND(y);
       12533                 :          0 :         x_data = PyUnicode_DATA(x);
       12534                 :          0 :         y_data = PyUnicode_DATA(y);
       12535         [ #  # ]:          0 :         for (i = 0; i < PyUnicode_GET_LENGTH(x); i++) {
       12536                 :          0 :             key = PyLong_FromLong(PyUnicode_READ(x_kind, x_data, i));
       12537         [ #  # ]:          0 :             if (!key)
       12538                 :          0 :                 goto err;
       12539                 :          0 :             value = PyLong_FromLong(PyUnicode_READ(y_kind, y_data, i));
       12540         [ #  # ]:          0 :             if (!value) {
       12541                 :          0 :                 Py_DECREF(key);
       12542                 :          0 :                 goto err;
       12543                 :            :             }
       12544                 :          0 :             res = PyDict_SetItem(new, key, value);
       12545                 :          0 :             Py_DECREF(key);
       12546                 :          0 :             Py_DECREF(value);
       12547         [ #  # ]:          0 :             if (res < 0)
       12548                 :          0 :                 goto err;
       12549                 :            :         }
       12550                 :            :         /* create entries for deleting chars in z */
       12551         [ #  # ]:          0 :         if (z != NULL) {
       12552                 :          0 :             z_kind = PyUnicode_KIND(z);
       12553                 :          0 :             z_data = PyUnicode_DATA(z);
       12554         [ #  # ]:          0 :             for (i = 0; i < PyUnicode_GET_LENGTH(z); i++) {
       12555                 :          0 :                 key = PyLong_FromLong(PyUnicode_READ(z_kind, z_data, i));
       12556         [ #  # ]:          0 :                 if (!key)
       12557                 :          0 :                     goto err;
       12558                 :          0 :                 res = PyDict_SetItem(new, key, Py_None);
       12559                 :          0 :                 Py_DECREF(key);
       12560         [ #  # ]:          0 :                 if (res < 0)
       12561                 :          0 :                     goto err;
       12562                 :            :             }
       12563                 :            :         }
       12564                 :            :     } else {
       12565                 :            :         int kind;
       12566                 :            :         const void *data;
       12567                 :            :
       12568                 :            :         /* x must be a dict */
       12569         [ #  # ]:          0 :         if (!PyDict_CheckExact(x)) {
       12570                 :          0 :             PyErr_SetString(PyExc_TypeError, "if you give only one argument "
       12571                 :            :                             "to maketrans it must be a dict");
       12572                 :          0 :             goto err;
       12573                 :            :         }
       12574                 :            :         /* copy entries into the new dict, converting string keys to int keys */
       12575         [ #  # ]:          0 :         while (PyDict_Next(x, &i, &key, &value)) {
       12576         [ #  # ]:          0 :             if (PyUnicode_Check(key)) {
       12577                 :            :                 /* convert string keys to integer keys */
       12578                 :            :                 PyObject *newkey;
       12579         [ #  # ]:          0 :                 if (PyUnicode_GET_LENGTH(key) != 1) {
       12580                 :          0 :                     PyErr_SetString(PyExc_ValueError, "string keys in translate "
       12581                 :            :                                     "table must be of length 1");
       12582                 :          0 :                     goto err;
       12583                 :            :                 }
       12584                 :          0 :                 kind = PyUnicode_KIND(key);
       12585                 :          0 :                 data = PyUnicode_DATA(key);
       12586                 :          0 :                 newkey = PyLong_FromLong(PyUnicode_READ(kind, data, 0));
       12587         [ #  # ]:          0 :                 if (!newkey)
       12588                 :          0 :                     goto err;
       12589                 :          0 :                 res = PyDict_SetItem(new, newkey, value);
       12590                 :          0 :                 Py_DECREF(newkey);
       12591         [ #  # ]:          0 :                 if (res < 0)
       12592                 :          0 :                     goto err;
       12593         [ #  # ]:          0 :             } else if (PyLong_Check(key)) {
       12594                 :            :                 /* just keep integer keys */
       12595         [ #  # ]:          0 :                 if (PyDict_SetItem(new, key, value) < 0)
       12596                 :          0 :                     goto err;
       12597                 :            :             } else {
       12598                 :          0 :                 PyErr_SetString(PyExc_TypeError, "keys in translate table must "
       12599                 :            :                                 "be strings or integers");
       12600                 :          0 :                 goto err;
       12601                 :            :             }
       12602                 :            :         }
       12603                 :            :     }
       12604                 :          0 :     return new;
       12605                 :          0 :   err:
       12606                 :          0 :     Py_DECREF(new);
       12607                 :          0 :     return NULL;
       12608                 :            : }
       12609                 :            :
       12610                 :            : /*[clinic input]
       12611                 :            : str.translate as unicode_translate
       12612                 :            :
       12613                 :            :     table: object
       12614                 :            :         Translation table, which must be a mapping of Unicode ordinals to
       12615                 :            :         Unicode ordinals, strings, or None.
       12616                 :            :     /
       12617                 :            :
       12618                 :            : Replace each character in the string using the given translation table.
       12619                 :            :
       12620                 :            : The table must implement lookup/indexing via __getitem__, for instance a
       12621                 :            : dictionary or list.  If this operation raises LookupError, the character is
       12622                 :            : left untouched.  Characters mapped to None are deleted.
       12623                 :            : [clinic start generated code]*/
       12624                 :            :
       12625                 :            : static PyObject *
       12626                 :        145 : unicode_translate(PyObject *self, PyObject *table)
       12627                 :            : /*[clinic end generated code: output=3cb448ff2fd96bf3 input=6d38343db63d8eb0]*/
       12628                 :            : {
       12629                 :        145 :     return _PyUnicode_TranslateCharmap(self, table, "ignore");
       12630                 :            : }
       12631                 :            :
       12632                 :            : /*[clinic input]
       12633                 :            : str.upper as unicode_upper
       12634                 :            :
       12635                 :            : Return a copy of the string converted to uppercase.
       12636                 :            : [clinic start generated code]*/
       12637                 :            :
       12638                 :            : static PyObject *
       12639                 :        108 : unicode_upper_impl(PyObject *self)
       12640                 :            : /*[clinic end generated code: output=1b7ddd16bbcdc092 input=db3d55682dfe2e6c]*/
       12641                 :            : {
       12642         [ +  - ]:        108 :     if (PyUnicode_IS_ASCII(self))
       12643                 :        108 :         return ascii_upper_or_lower(self, 0);
       12644                 :          0 :     return case_operation(self, do_upper);
       12645                 :            : }
       12646                 :            :
       12647                 :            : /*[clinic input]
       12648                 :            : str.zfill as unicode_zfill
       12649                 :            :
       12650                 :            :     width: Py_ssize_t
       12651                 :            :     /
       12652                 :            :
       12653                 :            : Pad a numeric string with zeros on the left, to fill a field of the given width.
       12654                 :            :
       12655                 :            : The string is never truncated.
       12656                 :            : [clinic start generated code]*/
       12657                 :            :
       12658                 :            : static PyObject *
       12659                 :          0 : unicode_zfill_impl(PyObject *self, Py_ssize_t width)
       12660                 :            : /*[clinic end generated code: output=e13fb6bdf8e3b9df input=c6b2f772c6f27799]*/
       12661                 :            : {
       12662                 :            :     Py_ssize_t fill;
       12663                 :            :     PyObject *u;
       12664                 :            :     int kind;
       12665                 :            :     const void *data;
       12666                 :            :     Py_UCS4 chr;
       12667                 :            :
       12668         [ #  # ]:          0 :     if (PyUnicode_GET_LENGTH(self) >= width)
       12669                 :          0 :         return unicode_result_unchanged(self);
       12670                 :            :
       12671                 :          0 :     fill = width - PyUnicode_GET_LENGTH(self);
       12672                 :            :
       12673                 :          0 :     u = pad(self, fill, 0, '0');
       12674                 :            :
       12675         [ #  # ]:          0 :     if (u == NULL)
       12676                 :          0 :         return NULL;
       12677                 :            :
       12678                 :          0 :     kind = PyUnicode_KIND(u);
       12679                 :          0 :     data = PyUnicode_DATA(u);
       12680                 :          0 :     chr = PyUnicode_READ(kind, data, fill);
       12681                 :            :
       12682   [ #  #  #  # ]:          0 :     if (chr == '+' || chr == '-') {
       12683                 :            :         /* move sign to beginning of string */
       12684                 :          0 :         PyUnicode_WRITE(kind, data, 0, chr);
       12685                 :          0 :         PyUnicode_WRITE(kind, data, fill, '0');
       12686                 :            :     }
       12687                 :            :
       12688                 :            :     assert(_PyUnicode_CheckConsistency(u, 1));
       12689                 :          0 :     return u;
       12690                 :            : }
       12691                 :            :
       12692                 :            : PyDoc_STRVAR(startswith__doc__,
       12693                 :            :              "S.startswith(prefix[, start[, end]]) -> bool\n\
       12694                 :            : \n\
       12695                 :            : Return True if S starts with the specified prefix, False otherwise.\n\
       12696                 :            : With optional start, test S beginning at that position.\n\
       12697                 :            : With optional end, stop comparing S at that position.\n\
       12698                 :            : prefix can also be a tuple of strings to try.");
       12699                 :            :
       12700                 :            : static PyObject *
       12701                 :      15342 : unicode_startswith(PyObject *self,
       12702                 :            :                    PyObject *args)
       12703                 :            : {
       12704                 :            :     PyObject *subobj;
       12705                 :            :     PyObject *substring;
       12706                 :      15342 :     Py_ssize_t start = 0;
       12707                 :      15342 :     Py_ssize_t end = PY_SSIZE_T_MAX;
       12708                 :            :     int result;
       12709                 :            :
       12710         [ -  + ]:      15342 :     if (!asciilib_parse_args_finds("startswith", args, &subobj, &start, &end))
       12711                 :          0 :         return NULL;
       12712         [ +  + ]:      15342 :     if (PyTuple_Check(subobj)) {
       12713                 :            :         Py_ssize_t i;
       12714         [ +  + ]:        479 :         for (i = 0; i < PyTuple_GET_SIZE(subobj); i++) {
       12715                 :        370 :             substring = PyTuple_GET_ITEM(subobj, i);
       12716         [ -  + ]:        370 :             if (!PyUnicode_Check(substring)) {
       12717                 :          0 :                 PyErr_Format(PyExc_TypeError,
       12718                 :            :                              "tuple for startswith must only contain str, "
       12719                 :            :                              "not %.100s",
       12720                 :          0 :                              Py_TYPE(substring)->tp_name);
       12721                 :          0 :                 return NULL;
       12722                 :            :             }
       12723                 :        370 :             result = tailmatch(self, substring, start, end, -1);
       12724         [ -  + ]:        370 :             if (result == -1)
       12725                 :          0 :                 return NULL;
       12726         [ +  + ]:        370 :             if (result) {
       12727                 :         23 :                 Py_RETURN_TRUE;
       12728                 :            :             }
       12729                 :            :         }
       12730                 :            :         /* nothing matched */
       12731                 :        109 :         Py_RETURN_FALSE;
       12732                 :            :     }
       12733         [ -  + ]:      15210 :     if (!PyUnicode_Check(subobj)) {
       12734                 :          0 :         PyErr_Format(PyExc_TypeError,
       12735                 :            :                      "startswith first arg must be str or "
       12736                 :          0 :                      "a tuple of str, not %.100s", Py_TYPE(subobj)->tp_name);
       12737                 :          0 :         return NULL;
       12738                 :            :     }
       12739                 :      15210 :     result = tailmatch(self, subobj, start, end, -1);
       12740         [ -  + ]:      15210 :     if (result == -1)
       12741                 :          0 :         return NULL;
       12742                 :      15210 :     return PyBool_FromLong(result);
       12743                 :            : }
       12744                 :            :
       12745                 :            :
       12746                 :            : PyDoc_STRVAR(endswith__doc__,
       12747                 :            :              "S.endswith(suffix[, start[, end]]) -> bool\n\
       12748                 :            : \n\
       12749                 :            : Return True if S ends with the specified suffix, False otherwise.\n\
       12750                 :            : With optional start, test S beginning at that position.\n\
       12751                 :            : With optional end, stop comparing S at that position.\n\
       12752                 :            : suffix can also be a tuple of strings to try.");
       12753                 :            :
       12754                 :            : static PyObject *
       12755                 :       4381 : unicode_endswith(PyObject *self,
       12756                 :            :                  PyObject *args)
       12757                 :            : {
       12758                 :            :     PyObject *subobj;
       12759                 :            :     PyObject *substring;
       12760                 :       4381 :     Py_ssize_t start = 0;
       12761                 :       4381 :     Py_ssize_t end = PY_SSIZE_T_MAX;
       12762                 :            :     int result;
       12763                 :            :
       12764         [ -  + ]:       4381 :     if (!asciilib_parse_args_finds("endswith", args, &subobj, &start, &end))
       12765                 :          0 :         return NULL;
       12766         [ +  + ]:       4381 :     if (PyTuple_Check(subobj)) {
       12767                 :            :         Py_ssize_t i;
       12768         [ +  + ]:       4528 :         for (i = 0; i < PyTuple_GET_SIZE(subobj); i++) {
       12769                 :       3426 :             substring = PyTuple_GET_ITEM(subobj, i);
       12770         [ -  + ]:       3426 :             if (!PyUnicode_Check(substring)) {
       12771                 :          0 :                 PyErr_Format(PyExc_TypeError,
       12772                 :            :                              "tuple for endswith must only contain str, "
       12773                 :            :                              "not %.100s",
       12774                 :          0 :                              Py_TYPE(substring)->tp_name);
       12775                 :          0 :                 return NULL;
       12776                 :            :             }
       12777                 :       3426 :             result = tailmatch(self, substring, start, end, +1);
       12778         [ -  + ]:       3426 :             if (result == -1)
       12779                 :          0 :                 return NULL;
       12780         [ +  + ]:       3426 :             if (result) {
       12781                 :       1165 :                 Py_RETURN_TRUE;
       12782                 :            :             }
       12783                 :            :         }
       12784                 :       1102 :         Py_RETURN_FALSE;
       12785                 :            :     }
       12786         [ -  + ]:       2114 :     if (!PyUnicode_Check(subobj)) {
       12787                 :          0 :         PyErr_Format(PyExc_TypeError,
       12788                 :            :                      "endswith first arg must be str or "
       12789                 :          0 :                      "a tuple of str, not %.100s", Py_TYPE(subobj)->tp_name);
       12790                 :          0 :         return NULL;
       12791                 :            :     }
       12792                 :       2114 :     result = tailmatch(self, subobj, start, end, +1);
       12793         [ -  + ]:       2114 :     if (result == -1)
       12794                 :          0 :         return NULL;
       12795                 :       2114 :     return PyBool_FromLong(result);
       12796                 :            : }
       12797                 :            :
       12798                 :            : static inline void
       12799                 :     347693 : _PyUnicodeWriter_Update(_PyUnicodeWriter *writer)
       12800                 :            : {
       12801                 :     347693 :     writer->maxchar = PyUnicode_MAX_CHAR_VALUE(writer->buffer);
       12802                 :     347693 :     writer->data = PyUnicode_DATA(writer->buffer);
       12803                 :            :
       12804         [ +  + ]:     347693 :     if (!writer->readonly) {
       12805                 :     347688 :         writer->kind = PyUnicode_KIND(writer->buffer);
       12806                 :     347688 :         writer->size = PyUnicode_GET_LENGTH(writer->buffer);
       12807                 :            :     }
       12808                 :            :     else {
       12809                 :            :         /* use a value smaller than PyUnicode_1BYTE_KIND() so
       12810                 :            :            _PyUnicodeWriter_PrepareKind() will copy the buffer. */
       12811                 :          5 :         writer->kind = 0;
       12812                 :            :         assert(writer->kind <= PyUnicode_1BYTE_KIND);
       12813                 :            :
       12814                 :            :         /* Copy-on-write mode: set buffer size to 0 so
       12815                 :            :          * _PyUnicodeWriter_Prepare() will copy (and enlarge) the buffer on
       12816                 :            :          * next write. */
       12817                 :          5 :         writer->size = 0;
       12818                 :            :     }
       12819                 :     347693 : }
       12820                 :            :
       12821                 :            : void
       12822                 :     302629 : _PyUnicodeWriter_Init(_PyUnicodeWriter *writer)
       12823                 :            : {
       12824                 :     302629 :     memset(writer, 0, sizeof(*writer));
       12825                 :            :
       12826                 :            :     /* ASCII is the bare minimum */
       12827                 :     302629 :     writer->min_char = 127;
       12828                 :            :
       12829                 :            :     /* use a value smaller than PyUnicode_1BYTE_KIND() so
       12830                 :            :        _PyUnicodeWriter_PrepareKind() will copy the buffer. */
       12831                 :     302629 :     writer->kind = 0;
       12832                 :            :     assert(writer->kind <= PyUnicode_1BYTE_KIND);
       12833                 :     302629 : }
       12834                 :            :
       12835                 :            : // Initialize _PyUnicodeWriter with initial buffer
       12836                 :            : static inline void
       12837                 :         93 : _PyUnicodeWriter_InitWithBuffer(_PyUnicodeWriter *writer, PyObject *buffer)
       12838                 :            : {
       12839                 :         93 :     memset(writer, 0, sizeof(*writer));
       12840                 :         93 :     writer->buffer = buffer;
       12841                 :         93 :     _PyUnicodeWriter_Update(writer);
       12842                 :         93 :     writer->min_length = writer->size;
       12843                 :         93 : }
       12844                 :            :
       12845                 :            : int
       12846                 :     347595 : _PyUnicodeWriter_PrepareInternal(_PyUnicodeWriter *writer,
       12847                 :            :                                  Py_ssize_t length, Py_UCS4 maxchar)
       12848                 :            : {
       12849                 :            :     Py_ssize_t newlen;
       12850                 :            :     PyObject *newbuffer;
       12851                 :            :
       12852                 :            :     assert(maxchar <= MAX_UNICODE);
       12853                 :            :
       12854                 :            :     /* ensure that the _PyUnicodeWriter_Prepare macro was used */
       12855                 :            :     assert((maxchar > writer->maxchar && length >= 0)
       12856                 :            :            || length > 0);
       12857                 :            :
       12858         [ -  + ]:     347595 :     if (length > PY_SSIZE_T_MAX - writer->pos) {
       12859                 :          0 :         PyErr_NoMemory();
       12860                 :          0 :         return -1;
       12861                 :            :     }
       12862                 :     347595 :     newlen = writer->pos + length;
       12863                 :            :
       12864                 :     347595 :     maxchar = Py_MAX(maxchar, writer->min_char);
       12865                 :            :
       12866         [ +  + ]:     347595 :     if (writer->buffer == NULL) {
       12867                 :            :         assert(!writer->readonly);
       12868         [ +  + ]:     302606 :         if (writer->overallocate
       12869         [ +  - ]:      32000 :             && newlen <= (PY_SSIZE_T_MAX - newlen / OVERALLOCATE_FACTOR)) {
       12870                 :            :             /* overallocate to limit the number of realloc() */
       12871                 :      32000 :             newlen += newlen / OVERALLOCATE_FACTOR;
       12872                 :            :         }
       12873         [ +  + ]:     302606 :         if (newlen < writer->min_length)
       12874                 :      31980 :             newlen = writer->min_length;
       12875                 :            :
       12876                 :     302606 :         writer->buffer = PyUnicode_New(newlen, maxchar);
       12877         [ -  + ]:     302606 :         if (writer->buffer == NULL)
       12878                 :          0 :             return -1;
       12879                 :            :     }
       12880         [ +  + ]:      44989 :     else if (newlen > writer->size) {
       12881         [ +  + ]:      44829 :         if (writer->overallocate
       12882         [ +  - ]:      42390 :             && newlen <= (PY_SSIZE_T_MAX - newlen / OVERALLOCATE_FACTOR)) {
       12883                 :            :             /* overallocate to limit the number of realloc() */
       12884                 :      42390 :             newlen += newlen / OVERALLOCATE_FACTOR;
       12885                 :            :         }
       12886         [ -  + ]:      44829 :         if (newlen < writer->min_length)
       12887                 :          0 :             newlen = writer->min_length;
       12888                 :            :
       12889   [ +  +  -  + ]:      44829 :         if (maxchar > writer->maxchar || writer->readonly) {
       12890                 :            :             /* resize + widen */
       12891                 :         43 :             maxchar = Py_MAX(maxchar, writer->maxchar);
       12892                 :         43 :             newbuffer = PyUnicode_New(newlen, maxchar);
       12893         [ -  + ]:         43 :             if (newbuffer == NULL)
       12894                 :          0 :                 return -1;
       12895                 :         43 :             _PyUnicode_FastCopyCharacters(newbuffer, 0,
       12896                 :            :                                           writer->buffer, 0, writer->pos);
       12897                 :         43 :             Py_DECREF(writer->buffer);
       12898                 :         43 :             writer->readonly = 0;
       12899                 :            :         }
       12900                 :            :         else {
       12901                 :      44786 :             newbuffer = resize_compact(writer->buffer, newlen);
       12902         [ -  + ]:      44786 :             if (newbuffer == NULL)
       12903                 :          0 :                 return -1;
       12904                 :            :         }
       12905                 :      44829 :         writer->buffer = newbuffer;
       12906                 :            :     }
       12907         [ +  - ]:        160 :     else if (maxchar > writer->maxchar) {
       12908                 :            :         assert(!writer->readonly);
       12909                 :        160 :         newbuffer = PyUnicode_New(writer->size, maxchar);
       12910         [ -  + ]:        160 :         if (newbuffer == NULL)
       12911                 :          0 :             return -1;
       12912                 :        160 :         _PyUnicode_FastCopyCharacters(newbuffer, 0,
       12913                 :            :                                       writer->buffer, 0, writer->pos);
       12914                 :        160 :         Py_SETREF(writer->buffer, newbuffer);
       12915                 :            :     }
       12916                 :     347595 :     _PyUnicodeWriter_Update(writer);
       12917                 :     347595 :     return 0;
       12918                 :            :
       12919                 :            : #undef OVERALLOCATE_FACTOR
       12920                 :            : }
       12921                 :            :
       12922                 :            : int
       12923                 :          6 : _PyUnicodeWriter_PrepareKindInternal(_PyUnicodeWriter *writer,
       12924                 :            :                                      int kind)
       12925                 :            : {
       12926                 :            :     Py_UCS4 maxchar;
       12927                 :            :
       12928                 :            :     /* ensure that the _PyUnicodeWriter_PrepareKind macro was used */
       12929                 :            :     assert(writer->kind < kind);
       12930                 :            :
       12931   [ -  +  -  - ]:          6 :     switch (kind)
       12932                 :            :     {
       12933                 :          0 :     case PyUnicode_1BYTE_KIND: maxchar = 0xff; break;
       12934                 :          6 :     case PyUnicode_2BYTE_KIND: maxchar = 0xffff; break;
       12935                 :          0 :     case PyUnicode_4BYTE_KIND: maxchar = MAX_UNICODE; break;
       12936                 :          0 :     default:
       12937                 :          0 :         Py_UNREACHABLE();
       12938                 :            :     }
       12939                 :            :
       12940                 :          6 :     return _PyUnicodeWriter_PrepareInternal(writer, 0, maxchar);
       12941                 :            : }
       12942                 :            :
       12943                 :            : static inline int
       12944                 :      26792 : _PyUnicodeWriter_WriteCharInline(_PyUnicodeWriter *writer, Py_UCS4 ch)
       12945                 :            : {
       12946                 :            :     assert(ch <= MAX_UNICODE);
       12947   [ +  +  +  +  :      26792 :     if (_PyUnicodeWriter_Prepare(writer, 1, ch) < 0)
                       -  + ]
       12948                 :          0 :         return -1;
       12949                 :      26792 :     PyUnicode_WRITE(writer->kind, writer->data, writer->pos, ch);
       12950                 :      26792 :     writer->pos++;
       12951                 :      26792 :     return 0;
       12952                 :            : }
       12953                 :            :
       12954                 :            : int
       12955                 :      26549 : _PyUnicodeWriter_WriteChar(_PyUnicodeWriter *writer, Py_UCS4 ch)
       12956                 :            : {
       12957                 :      26549 :     return _PyUnicodeWriter_WriteCharInline(writer, ch);
       12958                 :            : }
       12959                 :            :
       12960                 :            : int
       12961                 :     177700 : _PyUnicodeWriter_WriteStr(_PyUnicodeWriter *writer, PyObject *str)
       12962                 :            : {
       12963                 :            :     Py_UCS4 maxchar;
       12964                 :            :     Py_ssize_t len;
       12965                 :            :
       12966                 :     177700 :     len = PyUnicode_GET_LENGTH(str);
       12967         [ +  + ]:     177700 :     if (len == 0)
       12968                 :         27 :         return 0;
       12969                 :     177673 :     maxchar = PyUnicode_MAX_CHAR_VALUE(str);
       12970   [ +  +  +  + ]:     177673 :     if (maxchar > writer->maxchar || len > writer->size - writer->pos) {
       12971   [ +  +  +  + ]:      38964 :         if (writer->buffer == NULL && !writer->overallocate) {
       12972                 :            :             assert(_PyUnicode_CheckConsistency(str, 1));
       12973                 :          1 :             writer->readonly = 1;
       12974                 :          1 :             writer->buffer = Py_NewRef(str);
       12975                 :          1 :             _PyUnicodeWriter_Update(writer);
       12976                 :          1 :             writer->pos += len;
       12977                 :          1 :             return 0;
       12978                 :            :         }
       12979         [ -  + ]:      38963 :         if (_PyUnicodeWriter_PrepareInternal(writer, len, maxchar) == -1)
       12980                 :          0 :             return -1;
       12981                 :            :     }
       12982                 :     177672 :     _PyUnicode_FastCopyCharacters(writer->buffer, writer->pos,
       12983                 :            :                                   str, 0, len);
       12984                 :     177672 :     writer->pos += len;
       12985                 :     177672 :     return 0;
       12986                 :            : }
       12987                 :            :
       12988                 :            : int
       12989                 :        705 : _PyUnicodeWriter_WriteSubstring(_PyUnicodeWriter *writer, PyObject *str,
       12990                 :            :                                 Py_ssize_t start, Py_ssize_t end)
       12991                 :            : {
       12992                 :            :     Py_UCS4 maxchar;
       12993                 :            :     Py_ssize_t len;
       12994                 :            :
       12995                 :            :     assert(0 <= start);
       12996                 :            :     assert(end <= PyUnicode_GET_LENGTH(str));
       12997                 :            :     assert(start <= end);
       12998                 :            :
       12999         [ -  + ]:        705 :     if (end == 0)
       13000                 :          0 :         return 0;
       13001                 :            :
       13002   [ +  +  -  + ]:        705 :     if (start == 0 && end == PyUnicode_GET_LENGTH(str))
       13003                 :          0 :         return _PyUnicodeWriter_WriteStr(writer, str);
       13004                 :            :
       13005         [ +  + ]:        705 :     if (PyUnicode_MAX_CHAR_VALUE(str) > writer->maxchar)
       13006                 :        170 :         maxchar = _PyUnicode_FindMaxChar(str, start, end);
       13007                 :            :     else
       13008                 :        535 :         maxchar = writer->maxchar;
       13009                 :        705 :     len = end - start;
       13010                 :            :
       13011   [ +  +  +  +  :        705 :     if (_PyUnicodeWriter_Prepare(writer, len, maxchar) < 0)
                 +  -  -  + ]
       13012                 :          0 :         return -1;
       13013                 :            :
       13014                 :        705 :     _PyUnicode_FastCopyCharacters(writer->buffer, writer->pos,
       13015                 :            :                                   str, start, len);
       13016                 :        705 :     writer->pos += len;
       13017                 :        705 :     return 0;
       13018                 :            : }
       13019                 :            :
       13020                 :            : int
       13021                 :     183185 : _PyUnicodeWriter_WriteASCIIString(_PyUnicodeWriter *writer,
       13022                 :            :                                   const char *ascii, Py_ssize_t len)
       13023                 :            : {
       13024         [ -  + ]:     183185 :     if (len == -1)
       13025                 :          0 :         len = strlen(ascii);
       13026                 :            :
       13027                 :            :     assert(ucs1lib_find_max_char((const Py_UCS1*)ascii, (const Py_UCS1*)ascii + len) < 128);
       13028                 :            :
       13029   [ +  +  +  + ]:     183185 :     if (writer->buffer == NULL && !writer->overallocate) {
       13030                 :            :         PyObject *str;
       13031                 :            :
       13032                 :          4 :         str = _PyUnicode_FromASCII(ascii, len);
       13033         [ -  + ]:          4 :         if (str == NULL)
       13034                 :          0 :             return -1;
       13035                 :            :
       13036                 :          4 :         writer->readonly = 1;
       13037                 :          4 :         writer->buffer = str;
       13038                 :          4 :         _PyUnicodeWriter_Update(writer);
       13039                 :          4 :         writer->pos += len;
       13040                 :          4 :         return 0;
       13041                 :            :     }
       13042                 :            :
       13043   [ +  +  +  +  :     183181 :     if (_PyUnicodeWriter_Prepare(writer, len, 127) == -1)
                 +  -  -  + ]
       13044                 :          0 :         return -1;
       13045                 :            :
       13046   [ +  +  +  - ]:     183181 :     switch (writer->kind)
       13047                 :            :     {
       13048                 :     182805 :     case PyUnicode_1BYTE_KIND:
       13049                 :            :     {
       13050                 :     182805 :         const Py_UCS1 *str = (const Py_UCS1 *)ascii;
       13051                 :     182805 :         Py_UCS1 *data = writer->data;
       13052                 :            :
       13053                 :     182805 :         memcpy(data + writer->pos, str, len);
       13054                 :     182805 :         break;
       13055                 :            :     }
       13056                 :        292 :     case PyUnicode_2BYTE_KIND:
       13057                 :            :     {
       13058   [ -  +  +  + ]:        876 :         _PyUnicode_CONVERT_BYTES(
       13059                 :            :             Py_UCS1, Py_UCS2,
       13060                 :            :             ascii, ascii + len,
       13061                 :            :             (Py_UCS2 *)writer->data + writer->pos);
       13062                 :        292 :         break;
       13063                 :            :     }
       13064                 :         84 :     case PyUnicode_4BYTE_KIND:
       13065                 :            :     {
       13066   [ -  +  +  + ]:        252 :         _PyUnicode_CONVERT_BYTES(
       13067                 :            :             Py_UCS1, Py_UCS4,
       13068                 :            :             ascii, ascii + len,
       13069                 :            :             (Py_UCS4 *)writer->data + writer->pos);
       13070                 :         84 :         break;
       13071                 :            :     }
       13072                 :          0 :     default:
       13073                 :          0 :         Py_UNREACHABLE();
       13074                 :            :     }
       13075                 :            :
       13076                 :     183181 :     writer->pos += len;
       13077                 :     183181 :     return 0;
       13078                 :            : }
       13079                 :            :
       13080                 :            : int
       13081                 :          0 : _PyUnicodeWriter_WriteLatin1String(_PyUnicodeWriter *writer,
       13082                 :            :                                    const char *str, Py_ssize_t len)
       13083                 :            : {
       13084                 :            :     Py_UCS4 maxchar;
       13085                 :            :
       13086                 :          0 :     maxchar = ucs1lib_find_max_char((const Py_UCS1*)str, (const Py_UCS1*)str + len);
       13087   [ #  #  #  #  :          0 :     if (_PyUnicodeWriter_Prepare(writer, len, maxchar) == -1)
                 #  #  #  # ]
       13088                 :          0 :         return -1;
       13089                 :          0 :     unicode_write_cstr(writer->buffer, writer->pos, str, len);
       13090                 :          0 :     writer->pos += len;
       13091                 :          0 :     return 0;
       13092                 :            : }
       13093                 :            :
       13094                 :            : PyObject *
       13095                 :     302710 : _PyUnicodeWriter_Finish(_PyUnicodeWriter *writer)
       13096                 :            : {
       13097                 :            :     PyObject *str;
       13098                 :            :
       13099         [ +  + ]:     302710 :     if (writer->pos == 0) {
       13100         [ -  + ]:         17 :         Py_CLEAR(writer->buffer);
       13101                 :         17 :         _Py_RETURN_UNICODE_EMPTY();
       13102                 :            :     }
       13103                 :            :
       13104                 :     302693 :     str = writer->buffer;
       13105                 :     302693 :     writer->buffer = NULL;
       13106                 :            :
       13107         [ +  + ]:     302693 :     if (writer->readonly) {
       13108                 :            :         assert(PyUnicode_GET_LENGTH(str) == writer->pos);
       13109                 :          5 :         return str;
       13110                 :            :     }
       13111                 :            :
       13112         [ +  + ]:     302688 :     if (PyUnicode_GET_LENGTH(str) != writer->pos) {
       13113                 :            :         PyObject *str2;
       13114                 :      29558 :         str2 = resize_compact(str, writer->pos);
       13115         [ -  + ]:      29558 :         if (str2 == NULL) {
       13116                 :          0 :             Py_DECREF(str);
       13117                 :          0 :             return NULL;
       13118                 :            :         }
       13119                 :      29558 :         str = str2;
       13120                 :            :     }
       13121                 :            :
       13122                 :            :     assert(_PyUnicode_CheckConsistency(str, 1));
       13123                 :     302688 :     return unicode_result(str);
       13124                 :            : }
       13125                 :            :
       13126                 :            : void
       13127                 :         25 : _PyUnicodeWriter_Dealloc(_PyUnicodeWriter *writer)
       13128                 :            : {
       13129         [ +  + ]:         25 :     Py_CLEAR(writer->buffer);
       13130                 :         25 : }
       13131                 :            :
       13132                 :            : #include "stringlib/unicode_format.h"
       13133                 :            :
       13134                 :            : PyDoc_STRVAR(format__doc__,
       13135                 :            :              "S.format(*args, **kwargs) -> str\n\
       13136                 :            : \n\
       13137                 :            : Return a formatted version of S, using substitutions from args and kwargs.\n\
       13138                 :            : The substitutions are identified by braces ('{' and '}').");
       13139                 :            :
       13140                 :            : PyDoc_STRVAR(format_map__doc__,
       13141                 :            :              "S.format_map(mapping) -> str\n\
       13142                 :            : \n\
       13143                 :            : Return a formatted version of S, using substitutions from mapping.\n\
       13144                 :            : The substitutions are identified by braces ('{' and '}').");
       13145                 :            :
       13146                 :            : /*[clinic input]
       13147                 :            : str.__format__ as unicode___format__
       13148                 :            :
       13149                 :            :     format_spec: unicode
       13150                 :            :     /
       13151                 :            :
       13152                 :            : Return a formatted version of the string as described by format_spec.
       13153                 :            : [clinic start generated code]*/
       13154                 :            :
       13155                 :            : static PyObject *
       13156                 :          0 : unicode___format___impl(PyObject *self, PyObject *format_spec)
       13157                 :            : /*[clinic end generated code: output=45fceaca6d2ba4c8 input=5e135645d167a214]*/
       13158                 :            : {
       13159                 :            :     _PyUnicodeWriter writer;
       13160                 :            :     int ret;
       13161                 :            :
       13162                 :          0 :     _PyUnicodeWriter_Init(&writer);
       13163                 :          0 :     ret = _PyUnicode_FormatAdvancedWriter(&writer,
       13164                 :            :                                           self, format_spec, 0,
       13165                 :            :                                           PyUnicode_GET_LENGTH(format_spec));
       13166         [ #  # ]:          0 :     if (ret == -1) {
       13167                 :          0 :         _PyUnicodeWriter_Dealloc(&writer);
       13168                 :          0 :         return NULL;
       13169                 :            :     }
       13170                 :          0 :     return _PyUnicodeWriter_Finish(&writer);
       13171                 :            : }
       13172                 :            :
       13173                 :            : /*[clinic input]
       13174                 :            : str.__sizeof__ as unicode_sizeof
       13175                 :            :
       13176                 :            : Return the size of the string in memory, in bytes.
       13177                 :            : [clinic start generated code]*/
       13178                 :            :
       13179                 :            : static PyObject *
       13180                 :          0 : unicode_sizeof_impl(PyObject *self)
       13181                 :            : /*[clinic end generated code: output=6dbc2f5a408b6d4f input=6dd011c108e33fb0]*/
       13182                 :            : {
       13183                 :            :     Py_ssize_t size;
       13184                 :            :
       13185                 :            :     /* If it's a compact object, account for base structure +
       13186                 :            :        character data. */
       13187         [ #  # ]:          0 :     if (PyUnicode_IS_COMPACT_ASCII(self)) {
       13188                 :          0 :         size = sizeof(PyASCIIObject) + PyUnicode_GET_LENGTH(self) + 1;
       13189                 :            :     }
       13190         [ #  # ]:          0 :     else if (PyUnicode_IS_COMPACT(self)) {
       13191                 :          0 :         size = sizeof(PyCompactUnicodeObject) +
       13192                 :          0 :             (PyUnicode_GET_LENGTH(self) + 1) * PyUnicode_KIND(self);
       13193                 :            :     }
       13194                 :            :     else {
       13195                 :            :         /* If it is a two-block object, account for base object, and
       13196                 :            :            for character block if present. */
       13197                 :          0 :         size = sizeof(PyUnicodeObject);
       13198         [ #  # ]:          0 :         if (_PyUnicode_DATA_ANY(self))
       13199                 :          0 :             size += (PyUnicode_GET_LENGTH(self) + 1) *
       13200                 :          0 :                 PyUnicode_KIND(self);
       13201                 :            :     }
       13202   [ #  #  #  #  :          0 :     if (_PyUnicode_HAS_UTF8_MEMORY(self))
                       #  # ]
       13203         [ #  # ]:          0 :         size += PyUnicode_UTF8_LENGTH(self) + 1;
       13204                 :            :
       13205                 :          0 :     return PyLong_FromSsize_t(size);
       13206                 :            : }
       13207                 :            :
       13208                 :            : static PyObject *
       13209                 :          0 : unicode_getnewargs(PyObject *v, PyObject *Py_UNUSED(ignored))
       13210                 :            : {
       13211                 :          0 :     PyObject *copy = _PyUnicode_Copy(v);
       13212         [ #  # ]:          0 :     if (!copy)
       13213                 :          0 :         return NULL;
       13214                 :          0 :     return Py_BuildValue("(N)", copy);
       13215                 :            : }
       13216                 :            :
       13217                 :            : static PyMethodDef unicode_methods[] = {
       13218                 :            :     UNICODE_ENCODE_METHODDEF
       13219                 :            :     UNICODE_REPLACE_METHODDEF
       13220                 :            :     UNICODE_SPLIT_METHODDEF
       13221                 :            :     UNICODE_RSPLIT_METHODDEF
       13222                 :            :     UNICODE_JOIN_METHODDEF
       13223                 :            :     UNICODE_CAPITALIZE_METHODDEF
       13224                 :            :     UNICODE_CASEFOLD_METHODDEF
       13225                 :            :     UNICODE_TITLE_METHODDEF
       13226                 :            :     UNICODE_CENTER_METHODDEF
       13227                 :            :     {"count", (PyCFunction) unicode_count, METH_VARARGS, count__doc__},
       13228                 :            :     UNICODE_EXPANDTABS_METHODDEF
       13229                 :            :     {"find", (PyCFunction) unicode_find, METH_VARARGS, find__doc__},
       13230                 :            :     UNICODE_PARTITION_METHODDEF
       13231                 :            :     {"index", (PyCFunction) unicode_index, METH_VARARGS, index__doc__},
       13232                 :            :     UNICODE_LJUST_METHODDEF
       13233                 :            :     UNICODE_LOWER_METHODDEF
       13234                 :            :     UNICODE_LSTRIP_METHODDEF
       13235                 :            :     {"rfind", (PyCFunction) unicode_rfind, METH_VARARGS, rfind__doc__},
       13236                 :            :     {"rindex", (PyCFunction) unicode_rindex, METH_VARARGS, rindex__doc__},
       13237                 :            :     UNICODE_RJUST_METHODDEF
       13238                 :            :     UNICODE_RSTRIP_METHODDEF
       13239                 :            :     UNICODE_RPARTITION_METHODDEF
       13240                 :            :     UNICODE_SPLITLINES_METHODDEF
       13241                 :            :     UNICODE_STRIP_METHODDEF
       13242                 :            :     UNICODE_SWAPCASE_METHODDEF
       13243                 :            :     UNICODE_TRANSLATE_METHODDEF
       13244                 :            :     UNICODE_UPPER_METHODDEF
       13245                 :            :     {"startswith", (PyCFunction) unicode_startswith, METH_VARARGS, startswith__doc__},
       13246                 :            :     {"endswith", (PyCFunction) unicode_endswith, METH_VARARGS, endswith__doc__},
       13247                 :            :     UNICODE_REMOVEPREFIX_METHODDEF
       13248                 :            :     UNICODE_REMOVESUFFIX_METHODDEF
       13249                 :            :     UNICODE_ISASCII_METHODDEF
       13250                 :            :     UNICODE_ISLOWER_METHODDEF
       13251                 :            :     UNICODE_ISUPPER_METHODDEF
       13252                 :            :     UNICODE_ISTITLE_METHODDEF
       13253                 :            :     UNICODE_ISSPACE_METHODDEF
       13254                 :            :     UNICODE_ISDECIMAL_METHODDEF
       13255                 :            :     UNICODE_ISDIGIT_METHODDEF
       13256                 :            :     UNICODE_ISNUMERIC_METHODDEF
       13257                 :            :     UNICODE_ISALPHA_METHODDEF
       13258                 :            :     UNICODE_ISALNUM_METHODDEF
       13259                 :            :     UNICODE_ISIDENTIFIER_METHODDEF
       13260                 :            :     UNICODE_ISPRINTABLE_METHODDEF
       13261                 :            :     UNICODE_ZFILL_METHODDEF
       13262                 :            :     {"format", _PyCFunction_CAST(do_string_format), METH_VARARGS | METH_KEYWORDS, format__doc__},
       13263                 :            :     {"format_map", (PyCFunction) do_string_format_map, METH_O, format_map__doc__},
       13264                 :            :     UNICODE___FORMAT___METHODDEF
       13265                 :            :     UNICODE_MAKETRANS_METHODDEF
       13266                 :            :     UNICODE_SIZEOF_METHODDEF
       13267                 :            :     {"__getnewargs__",  unicode_getnewargs, METH_NOARGS},
       13268                 :            :     {NULL, NULL}
       13269                 :            : };
       13270                 :            :
       13271                 :            : static PyObject *
       13272                 :        230 : unicode_mod(PyObject *v, PyObject *w)
       13273                 :            : {
       13274         [ -  + ]:        230 :     if (!PyUnicode_Check(v))
       13275                 :          0 :         Py_RETURN_NOTIMPLEMENTED;
       13276                 :        230 :     return PyUnicode_Format(v, w);
       13277                 :            : }
       13278                 :            :
       13279                 :            : static PyNumberMethods unicode_as_number = {
       13280                 :            :     0,              /*nb_add*/
       13281                 :            :     0,              /*nb_subtract*/
       13282                 :            :     0,              /*nb_multiply*/
       13283                 :            :     unicode_mod,            /*nb_remainder*/
       13284                 :            : };
       13285                 :            :
       13286                 :            : static PySequenceMethods unicode_as_sequence = {
       13287                 :            :     (lenfunc) unicode_length,       /* sq_length */
       13288                 :            :     PyUnicode_Concat,           /* sq_concat */
       13289                 :            :     (ssizeargfunc) unicode_repeat,  /* sq_repeat */
       13290                 :            :     (ssizeargfunc) unicode_getitem,     /* sq_item */
       13291                 :            :     0,                  /* sq_slice */
       13292                 :            :     0,                  /* sq_ass_item */
       13293                 :            :     0,                  /* sq_ass_slice */
       13294                 :            :     PyUnicode_Contains,         /* sq_contains */
       13295                 :            : };
       13296                 :            :
       13297                 :            : static PyObject*
       13298                 :      29761 : unicode_subscript(PyObject* self, PyObject* item)
       13299                 :            : {
       13300         [ +  + ]:      29761 :     if (_PyIndex_Check(item)) {
       13301                 :      20640 :         Py_ssize_t i = PyNumber_AsSsize_t(item, PyExc_IndexError);
       13302   [ +  +  -  + ]:      20640 :         if (i == -1 && PyErr_Occurred())
       13303                 :          0 :             return NULL;
       13304         [ +  + ]:      20640 :         if (i < 0)
       13305                 :       1039 :             i += PyUnicode_GET_LENGTH(self);
       13306                 :      20640 :         return unicode_getitem(self, i);
       13307         [ +  - ]:       9121 :     } else if (PySlice_Check(item)) {
       13308                 :            :         Py_ssize_t start, stop, step, slicelength, i;
       13309                 :            :         size_t cur;
       13310                 :            :         PyObject *result;
       13311                 :            :         const void *src_data;
       13312                 :            :         void *dest_data;
       13313                 :            :         int src_kind, dest_kind;
       13314                 :            :         Py_UCS4 ch, max_char, kind_limit;
       13315                 :            :
       13316         [ -  + ]:       9121 :         if (PySlice_Unpack(item, &start, &stop, &step) < 0) {
       13317                 :          0 :             return NULL;
       13318                 :            :         }
       13319                 :       9121 :         slicelength = PySlice_AdjustIndices(PyUnicode_GET_LENGTH(self),
       13320                 :            :                                             &start, &stop, step);
       13321                 :            :
       13322         [ +  + ]:       9121 :         if (slicelength <= 0) {
       13323                 :        553 :             _Py_RETURN_UNICODE_EMPTY();
       13324   [ +  +  +  -  :      13264 :         } else if (start == 0 && step == 1 &&
                       +  + ]
       13325                 :       4696 :                    slicelength == PyUnicode_GET_LENGTH(self)) {
       13326                 :         80 :             return unicode_result_unchanged(self);
       13327         [ +  - ]:       8488 :         } else if (step == 1) {
       13328                 :       8488 :             return PyUnicode_Substring(self,
       13329                 :            :                                        start, start + slicelength);
       13330                 :            :         }
       13331                 :            :         /* General case */
       13332                 :          0 :         src_kind = PyUnicode_KIND(self);
       13333                 :          0 :         src_data = PyUnicode_DATA(self);
       13334         [ #  # ]:          0 :         if (!PyUnicode_IS_ASCII(self)) {
       13335                 :          0 :             kind_limit = kind_maxchar_limit(src_kind);
       13336                 :          0 :             max_char = 0;
       13337         [ #  # ]:          0 :             for (cur = start, i = 0; i < slicelength; cur += step, i++) {
       13338                 :          0 :                 ch = PyUnicode_READ(src_kind, src_data, cur);
       13339         [ #  # ]:          0 :                 if (ch > max_char) {
       13340                 :          0 :                     max_char = ch;
       13341         [ #  # ]:          0 :                     if (max_char >= kind_limit)
       13342                 :          0 :                         break;
       13343                 :            :                 }
       13344                 :            :             }
       13345                 :            :         }
       13346                 :            :         else
       13347                 :          0 :             max_char = 127;
       13348                 :          0 :         result = PyUnicode_New(slicelength, max_char);
       13349         [ #  # ]:          0 :         if (result == NULL)
       13350                 :          0 :             return NULL;
       13351                 :          0 :         dest_kind = PyUnicode_KIND(result);
       13352                 :          0 :         dest_data = PyUnicode_DATA(result);
       13353                 :            :
       13354         [ #  # ]:          0 :         for (cur = start, i = 0; i < slicelength; cur += step, i++) {
       13355                 :          0 :             Py_UCS4 ch = PyUnicode_READ(src_kind, src_data, cur);
       13356                 :          0 :             PyUnicode_WRITE(dest_kind, dest_data, i, ch);
       13357                 :            :         }
       13358                 :            :         assert(_PyUnicode_CheckConsistency(result, 1));
       13359                 :          0 :         return result;
       13360                 :            :     } else {
       13361                 :          0 :         PyErr_Format(PyExc_TypeError, "string indices must be integers, not '%.200s'",
       13362                 :          0 :                      Py_TYPE(item)->tp_name);
       13363                 :          0 :         return NULL;
       13364                 :            :     }
       13365                 :            : }
       13366                 :            :
       13367                 :            : static PyMappingMethods unicode_as_mapping = {
       13368                 :            :     (lenfunc)unicode_length,        /* mp_length */
       13369                 :            :     (binaryfunc)unicode_subscript,  /* mp_subscript */
       13370                 :            :     (objobjargproc)0,           /* mp_ass_subscript */
       13371                 :            : };
       13372                 :            :
       13373                 :            :
       13374                 :            : /* Helpers for PyUnicode_Format() */
       13375                 :            :
       13376                 :            : struct unicode_formatter_t {
       13377                 :            :     PyObject *args;
       13378                 :            :     int args_owned;
       13379                 :            :     Py_ssize_t arglen, argidx;
       13380                 :            :     PyObject *dict;
       13381                 :            :
       13382                 :            :     int fmtkind;
       13383                 :            :     Py_ssize_t fmtcnt, fmtpos;
       13384                 :            :     const void *fmtdata;
       13385                 :            :     PyObject *fmtstr;
       13386                 :            :
       13387                 :            :     _PyUnicodeWriter writer;
       13388                 :            : };
       13389                 :            :
       13390                 :            : struct unicode_format_arg_t {
       13391                 :            :     Py_UCS4 ch;
       13392                 :            :     int flags;
       13393                 :            :     Py_ssize_t width;
       13394                 :            :     int prec;
       13395                 :            :     int sign;
       13396                 :            : };
       13397                 :            :
       13398                 :            : static PyObject *
       13399                 :        482 : unicode_format_getnextarg(struct unicode_formatter_t *ctx)
       13400                 :            : {
       13401                 :        482 :     Py_ssize_t argidx = ctx->argidx;
       13402                 :            :
       13403         [ +  - ]:        482 :     if (argidx < ctx->arglen) {
       13404                 :        482 :         ctx->argidx++;
       13405         [ +  + ]:        482 :         if (ctx->arglen < 0)
       13406                 :         77 :             return ctx->args;
       13407                 :            :         else
       13408                 :        405 :             return PyTuple_GetItem(ctx->args, argidx);
       13409                 :            :     }
       13410                 :          0 :     PyErr_SetString(PyExc_TypeError,
       13411                 :            :                     "not enough arguments for format string");
       13412                 :          0 :     return NULL;
       13413                 :            : }
       13414                 :            :
       13415                 :            : /* Returns a new reference to a PyUnicode object, or NULL on failure. */
       13416                 :            :
       13417                 :            : /* Format a float into the writer if the writer is not NULL, or into *p_output
       13418                 :            :    otherwise.
       13419                 :            :
       13420                 :            :    Return 0 on success, raise an exception and return -1 on error. */
       13421                 :            : static int
       13422                 :          0 : formatfloat(PyObject *v, struct unicode_format_arg_t *arg,
       13423                 :            :             PyObject **p_output,
       13424                 :            :             _PyUnicodeWriter *writer)
       13425                 :            : {
       13426                 :            :     char *p;
       13427                 :            :     double x;
       13428                 :            :     Py_ssize_t len;
       13429                 :            :     int prec;
       13430                 :          0 :     int dtoa_flags = 0;
       13431                 :            :
       13432                 :          0 :     x = PyFloat_AsDouble(v);
       13433   [ #  #  #  # ]:          0 :     if (x == -1.0 && PyErr_Occurred())
       13434                 :          0 :         return -1;
       13435                 :            :
       13436                 :          0 :     prec = arg->prec;
       13437         [ #  # ]:          0 :     if (prec < 0)
       13438                 :          0 :         prec = 6;
       13439                 :            :
       13440         [ #  # ]:          0 :     if (arg->flags & F_ALT)
       13441                 :          0 :         dtoa_flags |= Py_DTSF_ALT;
       13442         [ #  # ]:          0 :     if (arg->flags & F_NO_NEG_0)
       13443                 :          0 :         dtoa_flags |= Py_DTSF_NO_NEG_0;
       13444                 :          0 :     p = PyOS_double_to_string(x, arg->ch, prec, dtoa_flags, NULL);
       13445         [ #  # ]:          0 :     if (p == NULL)
       13446                 :          0 :         return -1;
       13447                 :          0 :     len = strlen(p);
       13448         [ #  # ]:          0 :     if (writer) {
       13449         [ #  # ]:          0 :         if (_PyUnicodeWriter_WriteASCIIString(writer, p, len) < 0) {
       13450                 :          0 :             PyMem_Free(p);
       13451                 :          0 :             return -1;
       13452                 :            :         }
       13453                 :            :     }
       13454                 :            :     else
       13455                 :          0 :         *p_output = _PyUnicode_FromASCII(p, len);
       13456                 :          0 :     PyMem_Free(p);
       13457                 :          0 :     return 0;
       13458                 :            : }
       13459                 :            :
       13460                 :            : /* formatlong() emulates the format codes d, u, o, x and X, and
       13461                 :            :  * the F_ALT flag, for Python's long (unbounded) ints.  It's not used for
       13462                 :            :  * Python's regular ints.
       13463                 :            :  * Return value:  a new PyUnicodeObject*, or NULL if error.
       13464                 :            :  *     The output string is of the form
       13465                 :            :  *         "-"? ("0x" | "0X")? digit+
       13466                 :            :  *     "0x"/"0X" are present only for x and X conversions, with F_ALT
       13467                 :            :  *         set in flags.  The case of hex digits will be correct,
       13468                 :            :  *     There will be at least prec digits, zero-filled on the left if
       13469                 :            :  *         necessary to get that many.
       13470                 :            :  * val          object to be converted
       13471                 :            :  * flags        bitmask of format flags; only F_ALT is looked at
       13472                 :            :  * prec         minimum number of digits; 0-fill on left if needed
       13473                 :            :  * type         a character in [duoxX]; u acts the same as d
       13474                 :            :  *
       13475                 :            :  * CAUTION:  o, x and X conversions on regular ints can never
       13476                 :            :  * produce a '-' sign, but can for Python's unbounded ints.
       13477                 :            :  */
       13478                 :            : PyObject *
       13479                 :          4 : _PyUnicode_FormatLong(PyObject *val, int alt, int prec, int type)
       13480                 :            : {
       13481                 :          4 :     PyObject *result = NULL;
       13482                 :            :     char *buf;
       13483                 :            :     Py_ssize_t i;
       13484                 :            :     int sign;           /* 1 if '-', else 0 */
       13485                 :            :     int len;            /* number of characters */
       13486                 :            :     Py_ssize_t llen;
       13487                 :            :     int numdigits;      /* len == numnondigits + numdigits */
       13488                 :          4 :     int numnondigits = 0;
       13489                 :            :
       13490                 :            :     /* Avoid exceeding SSIZE_T_MAX */
       13491         [ -  + ]:          4 :     if (prec > INT_MAX-3) {
       13492                 :          0 :         PyErr_SetString(PyExc_OverflowError,
       13493                 :            :                         "precision too large");
       13494                 :          0 :         return NULL;
       13495                 :            :     }
       13496                 :            :
       13497                 :            :     assert(PyLong_Check(val));
       13498                 :            :
       13499   [ -  +  -  - ]:          4 :     switch (type) {
       13500                 :          0 :     default:
       13501                 :          0 :         Py_UNREACHABLE();
       13502                 :          4 :     case 'd':
       13503                 :            :     case 'i':
       13504                 :            :     case 'u':
       13505                 :            :         /* int and int subclasses should print numerically when a numeric */
       13506                 :            :         /* format code is used (see issue18780) */
       13507                 :          4 :         result = PyNumber_ToBase(val, 10);
       13508                 :          4 :         break;
       13509                 :          0 :     case 'o':
       13510                 :          0 :         numnondigits = 2;
       13511                 :          0 :         result = PyNumber_ToBase(val, 8);
       13512                 :          0 :         break;
       13513                 :          0 :     case 'x':
       13514                 :            :     case 'X':
       13515                 :          0 :         numnondigits = 2;
       13516                 :          0 :         result = PyNumber_ToBase(val, 16);
       13517                 :          0 :         break;
       13518                 :            :     }
       13519         [ -  + ]:          4 :     if (!result)
       13520                 :          0 :         return NULL;
       13521                 :            :
       13522                 :            :     assert(unicode_modifiable(result));
       13523                 :            :     assert(PyUnicode_IS_ASCII(result));
       13524                 :            :
       13525                 :            :     /* To modify the string in-place, there can only be one reference. */
       13526         [ -  + ]:          4 :     if (Py_REFCNT(result) != 1) {
       13527                 :          0 :         Py_DECREF(result);
       13528                 :          0 :         PyErr_BadInternalCall();
       13529                 :          0 :         return NULL;
       13530                 :            :     }
       13531                 :          4 :     buf = PyUnicode_DATA(result);
       13532                 :          4 :     llen = PyUnicode_GET_LENGTH(result);
       13533         [ -  + ]:          4 :     if (llen > INT_MAX) {
       13534                 :          0 :         Py_DECREF(result);
       13535                 :          0 :         PyErr_SetString(PyExc_ValueError,
       13536                 :            :                         "string too large in _PyUnicode_FormatLong");
       13537                 :          0 :         return NULL;
       13538                 :            :     }
       13539                 :          4 :     len = (int)llen;
       13540                 :          4 :     sign = buf[0] == '-';
       13541                 :          4 :     numnondigits += sign;
       13542                 :          4 :     numdigits = len - numnondigits;
       13543                 :            :     assert(numdigits > 0);
       13544                 :            :
       13545                 :            :     /* Get rid of base marker unless F_ALT */
       13546   [ +  -  +  - ]:          4 :     if (((alt) == 0 &&
       13547   [ +  -  -  + ]:          4 :         (type == 'o' || type == 'x' || type == 'X'))) {
       13548                 :            :         assert(buf[sign] == '0');
       13549                 :            :         assert(buf[sign+1] == 'x' || buf[sign+1] == 'X' ||
       13550                 :            :                buf[sign+1] == 'o');
       13551                 :          0 :         numnondigits -= 2;
       13552                 :          0 :         buf += 2;
       13553                 :          0 :         len -= 2;
       13554         [ #  # ]:          0 :         if (sign)
       13555                 :          0 :             buf[0] = '-';
       13556                 :            :         assert(len == numnondigits + numdigits);
       13557                 :            :         assert(numdigits > 0);
       13558                 :            :     }
       13559                 :            :
       13560                 :            :     /* Fill with leading zeroes to meet minimum width. */
       13561         [ -  + ]:          4 :     if (prec > numdigits) {
       13562                 :          0 :         PyObject *r1 = PyBytes_FromStringAndSize(NULL,
       13563                 :          0 :                                 numnondigits + prec);
       13564                 :            :         char *b1;
       13565         [ #  # ]:          0 :         if (!r1) {
       13566                 :          0 :             Py_DECREF(result);
       13567                 :          0 :             return NULL;
       13568                 :            :         }
       13569                 :          0 :         b1 = PyBytes_AS_STRING(r1);
       13570         [ #  # ]:          0 :         for (i = 0; i < numnondigits; ++i)
       13571                 :          0 :             *b1++ = *buf++;
       13572         [ #  # ]:          0 :         for (i = 0; i < prec - numdigits; i++)
       13573                 :          0 :             *b1++ = '0';
       13574         [ #  # ]:          0 :         for (i = 0; i < numdigits; i++)
       13575                 :          0 :             *b1++ = *buf++;
       13576                 :          0 :         *b1 = '\0';
       13577                 :          0 :         Py_SETREF(result, r1);
       13578                 :          0 :         buf = PyBytes_AS_STRING(result);
       13579                 :          0 :         len = numnondigits + prec;
       13580                 :            :     }
       13581                 :            :
       13582                 :            :     /* Fix up case for hex conversions. */
       13583         [ -  + ]:          4 :     if (type == 'X') {
       13584                 :            :         /* Need to convert all lower case letters to upper case.
       13585                 :            :            and need to convert 0x to 0X (and -0x to -0X). */
       13586         [ #  # ]:          0 :         for (i = 0; i < len; i++)
       13587   [ #  #  #  # ]:          0 :             if (buf[i] >= 'a' && buf[i] <= 'x')
       13588                 :          0 :                 buf[i] -= 'a'-'A';
       13589                 :            :     }
       13590         [ +  - ]:          4 :     if (!PyUnicode_Check(result)
       13591         [ -  + ]:          4 :         || buf != PyUnicode_DATA(result)) {
       13592                 :            :         PyObject *unicode;
       13593                 :          0 :         unicode = _PyUnicode_FromASCII(buf, len);
       13594                 :          0 :         Py_SETREF(result, unicode);
       13595                 :            :     }
       13596         [ -  + ]:          4 :     else if (len != PyUnicode_GET_LENGTH(result)) {
       13597         [ #  # ]:          0 :         if (PyUnicode_Resize(&result, len) < 0)
       13598         [ #  # ]:          0 :             Py_CLEAR(result);
       13599                 :            :     }
       13600                 :          4 :     return result;
       13601                 :            : }
       13602                 :            :
       13603                 :            : /* Format an integer or a float as an integer.
       13604                 :            :  * Return 1 if the number has been formatted into the writer,
       13605                 :            :  *        0 if the number has been formatted into *p_output
       13606                 :            :  *       -1 and raise an exception on error */
       13607                 :            : static int
       13608                 :        113 : mainformatlong(PyObject *v,
       13609                 :            :                struct unicode_format_arg_t *arg,
       13610                 :            :                PyObject **p_output,
       13611                 :            :                _PyUnicodeWriter *writer)
       13612                 :            : {
       13613                 :            :     PyObject *iobj, *res;
       13614                 :        113 :     char type = (char)arg->ch;
       13615                 :            :
       13616         [ -  + ]:        113 :     if (!PyNumber_Check(v))
       13617                 :          0 :         goto wrongtype;
       13618                 :            :
       13619                 :            :     /* make sure number is a type of integer for o, x, and X */
       13620         [ -  + ]:        113 :     if (!PyLong_Check(v)) {
       13621   [ #  #  #  #  :          0 :         if (type == 'o' || type == 'x' || type == 'X') {
                       #  # ]
       13622                 :          0 :             iobj = _PyNumber_Index(v);
       13623                 :            :         }
       13624                 :            :         else {
       13625                 :          0 :             iobj = PyNumber_Long(v);
       13626                 :            :         }
       13627         [ #  # ]:          0 :         if (iobj == NULL ) {
       13628         [ #  # ]:          0 :             if (PyErr_ExceptionMatches(PyExc_TypeError))
       13629                 :          0 :                 goto wrongtype;
       13630                 :          0 :             return -1;
       13631                 :            :         }
       13632                 :            :         assert(PyLong_Check(iobj));
       13633                 :            :     }
       13634                 :            :     else {
       13635                 :        113 :         iobj = Py_NewRef(v);
       13636                 :            :     }
       13637                 :            :
       13638         [ +  - ]:        113 :     if (PyLong_CheckExact(v)
       13639   [ +  +  +  - ]:        113 :         && arg->width == -1 && arg->prec == -1
       13640         [ +  - ]:        109 :         && !(arg->flags & (F_SIGN | F_BLANK))
       13641         [ +  - ]:        109 :         && type != 'X')
       13642                 :            :     {
       13643                 :            :         /* Fast path */
       13644                 :        109 :         int alternate = arg->flags & F_ALT;
       13645                 :            :         int base;
       13646                 :            :
       13647   [ -  +  -  - ]:        109 :         switch(type)
       13648                 :            :         {
       13649                 :          0 :             default:
       13650                 :          0 :                 Py_UNREACHABLE();
       13651                 :        109 :             case 'd':
       13652                 :            :             case 'i':
       13653                 :            :             case 'u':
       13654                 :        109 :                 base = 10;
       13655                 :        109 :                 break;
       13656                 :          0 :             case 'o':
       13657                 :          0 :                 base = 8;
       13658                 :          0 :                 break;
       13659                 :          0 :             case 'x':
       13660                 :            :             case 'X':
       13661                 :          0 :                 base = 16;
       13662                 :          0 :                 break;
       13663                 :            :         }
       13664                 :            :
       13665         [ -  + ]:        109 :         if (_PyLong_FormatWriter(writer, v, base, alternate) == -1) {
       13666                 :          0 :             Py_DECREF(iobj);
       13667                 :          0 :             return -1;
       13668                 :            :         }
       13669                 :        109 :         Py_DECREF(iobj);
       13670                 :        109 :         return 1;
       13671                 :            :     }
       13672                 :            :
       13673                 :          4 :     res = _PyUnicode_FormatLong(iobj, arg->flags & F_ALT, arg->prec, type);
       13674                 :          4 :     Py_DECREF(iobj);
       13675         [ -  + ]:          4 :     if (res == NULL)
       13676                 :          0 :         return -1;
       13677                 :          4 :     *p_output = res;
       13678                 :          4 :     return 0;
       13679                 :            :
       13680                 :          0 : wrongtype:
       13681         [ #  # ]:          0 :     switch(type)
       13682                 :            :     {
       13683                 :          0 :         case 'o':
       13684                 :            :         case 'x':
       13685                 :            :         case 'X':
       13686                 :          0 :             PyErr_Format(PyExc_TypeError,
       13687                 :            :                     "%%%c format: an integer is required, "
       13688                 :            :                     "not %.200s",
       13689                 :          0 :                     type, Py_TYPE(v)->tp_name);
       13690                 :          0 :             break;
       13691                 :          0 :         default:
       13692                 :          0 :             PyErr_Format(PyExc_TypeError,
       13693                 :            :                     "%%%c format: a real number is required, "
       13694                 :            :                     "not %.200s",
       13695                 :          0 :                     type, Py_TYPE(v)->tp_name);
       13696                 :          0 :             break;
       13697                 :            :     }
       13698                 :          0 :     return -1;
       13699                 :            : }
       13700                 :            :
       13701                 :            : static Py_UCS4
       13702                 :          0 : formatchar(PyObject *v)
       13703                 :            : {
       13704                 :            :     /* presume that the buffer is at least 3 characters long */
       13705         [ #  # ]:          0 :     if (PyUnicode_Check(v)) {
       13706         [ #  # ]:          0 :         if (PyUnicode_GET_LENGTH(v) == 1) {
       13707                 :          0 :             return PyUnicode_READ_CHAR(v, 0);
       13708                 :            :         }
       13709                 :          0 :         goto onError;
       13710                 :            :     }
       13711                 :            :     else {
       13712                 :            :         int overflow;
       13713                 :          0 :         long x = PyLong_AsLongAndOverflow(v, &overflow);
       13714   [ #  #  #  # ]:          0 :         if (x == -1 && PyErr_Occurred()) {
       13715         [ #  # ]:          0 :             if (PyErr_ExceptionMatches(PyExc_TypeError)) {
       13716                 :          0 :                 goto onError;
       13717                 :            :             }
       13718                 :          0 :             return (Py_UCS4) -1;
       13719                 :            :         }
       13720                 :            :
       13721   [ #  #  #  # ]:          0 :         if (x < 0 || x > MAX_UNICODE) {
       13722                 :            :             /* this includes an overflow in converting to C long */
       13723                 :          0 :             PyErr_SetString(PyExc_OverflowError,
       13724                 :            :                             "%c arg not in range(0x110000)");
       13725                 :          0 :             return (Py_UCS4) -1;
       13726                 :            :         }
       13727                 :            :
       13728                 :          0 :         return (Py_UCS4) x;
       13729                 :            :     }
       13730                 :            :
       13731                 :          0 :   onError:
       13732                 :          0 :     PyErr_SetString(PyExc_TypeError,
       13733                 :            :                     "%c requires int or char");
       13734                 :          0 :     return (Py_UCS4) -1;
       13735                 :            : }
       13736                 :            :
       13737                 :            : /* Parse options of an argument: flags, width, precision.
       13738                 :            :    Handle also "%(name)" syntax.
       13739                 :            :
       13740                 :            :    Return 0 if the argument has been formatted into arg->str.
       13741                 :            :    Return 1 if the argument has been written into ctx->writer,
       13742                 :            :    Raise an exception and return -1 on error. */
       13743                 :            : static int
       13744                 :        482 : unicode_format_arg_parse(struct unicode_formatter_t *ctx,
       13745                 :            :                          struct unicode_format_arg_t *arg)
       13746                 :            : {
       13747                 :            : #define FORMAT_READ(ctx) \
       13748                 :            :         PyUnicode_READ((ctx)->fmtkind, (ctx)->fmtdata, (ctx)->fmtpos)
       13749                 :            :
       13750                 :            :     PyObject *v;
       13751                 :            :
       13752         [ +  + ]:        482 :     if (arg->ch == '(') {
       13753                 :            :         /* Get argument value from a dictionary. Example: "%(name)s". */
       13754                 :            :         Py_ssize_t keystart;
       13755                 :            :         Py_ssize_t keylen;
       13756                 :            :         PyObject *key;
       13757                 :         20 :         int pcount = 1;
       13758                 :            :
       13759         [ -  + ]:         20 :         if (ctx->dict == NULL) {
       13760                 :          0 :             PyErr_SetString(PyExc_TypeError,
       13761                 :            :                             "format requires a mapping");
       13762                 :          0 :             return -1;
       13763                 :            :         }
       13764                 :         20 :         ++ctx->fmtpos;
       13765                 :         20 :         --ctx->fmtcnt;
       13766                 :         20 :         keystart = ctx->fmtpos;
       13767                 :            :         /* Skip over balanced parentheses */
       13768   [ +  +  +  - ]:         82 :         while (pcount > 0 && --ctx->fmtcnt >= 0) {
       13769                 :         62 :             arg->ch = FORMAT_READ(ctx);
       13770         [ +  + ]:         62 :             if (arg->ch == ')')
       13771                 :         20 :                 --pcount;
       13772         [ -  + ]:         42 :             else if (arg->ch == '(')
       13773                 :          0 :                 ++pcount;
       13774                 :         62 :             ctx->fmtpos++;
       13775                 :            :         }
       13776                 :         20 :         keylen = ctx->fmtpos - keystart - 1;
       13777   [ +  -  -  + ]:         20 :         if (ctx->fmtcnt < 0 || pcount > 0) {
       13778                 :          0 :             PyErr_SetString(PyExc_ValueError,
       13779                 :            :                             "incomplete format key");
       13780                 :          0 :             return -1;
       13781                 :            :         }
       13782                 :         20 :         key = PyUnicode_Substring(ctx->fmtstr,
       13783                 :            :                                   keystart, keystart + keylen);
       13784         [ -  + ]:         20 :         if (key == NULL)
       13785                 :          0 :             return -1;
       13786         [ +  + ]:         20 :         if (ctx->args_owned) {
       13787                 :         18 :             ctx->args_owned = 0;
       13788                 :         18 :             Py_DECREF(ctx->args);
       13789                 :            :         }
       13790                 :         20 :         ctx->args = PyObject_GetItem(ctx->dict, key);
       13791                 :         20 :         Py_DECREF(key);
       13792         [ -  + ]:         20 :         if (ctx->args == NULL)
       13793                 :          0 :             return -1;
       13794                 :         20 :         ctx->args_owned = 1;
       13795                 :         20 :         ctx->arglen = -1;
       13796                 :         20 :         ctx->argidx = -2;
       13797                 :            :     }
       13798                 :            :
       13799                 :            :     /* Parse flags. Example: "%+i" => flags=F_SIGN. */
       13800         [ +  - ]:        486 :     while (--ctx->fmtcnt >= 0) {
       13801                 :        486 :         arg->ch = FORMAT_READ(ctx);
       13802                 :        486 :         ctx->fmtpos++;
       13803   [ -  -  -  -  :        486 :         switch (arg->ch) {
                       +  + ]
       13804                 :          0 :         case '-': arg->flags |= F_LJUST; continue;
       13805                 :          0 :         case '+': arg->flags |= F_SIGN; continue;
       13806                 :          0 :         case ' ': arg->flags |= F_BLANK; continue;
       13807                 :          0 :         case '#': arg->flags |= F_ALT; continue;
       13808                 :          4 :         case '0': arg->flags |= F_ZERO; continue;
       13809                 :            :         }
       13810                 :        482 :         break;
       13811                 :            :     }
       13812                 :            :
       13813                 :            :     /* Parse width. Example: "%10s" => width=10 */
       13814         [ -  + ]:        482 :     if (arg->ch == '*') {
       13815                 :          0 :         v = unicode_format_getnextarg(ctx);
       13816         [ #  # ]:          0 :         if (v == NULL)
       13817                 :          0 :             return -1;
       13818         [ #  # ]:          0 :         if (!PyLong_Check(v)) {
       13819                 :          0 :             PyErr_SetString(PyExc_TypeError,
       13820                 :            :                             "* wants int");
       13821                 :          0 :             return -1;
       13822                 :            :         }
       13823                 :          0 :         arg->width = PyLong_AsSsize_t(v);
       13824   [ #  #  #  # ]:          0 :         if (arg->width == -1 && PyErr_Occurred())
       13825                 :          0 :             return -1;
       13826         [ #  # ]:          0 :         if (arg->width < 0) {
       13827                 :          0 :             arg->flags |= F_LJUST;
       13828                 :          0 :             arg->width = -arg->width;
       13829                 :            :         }
       13830         [ #  # ]:          0 :         if (--ctx->fmtcnt >= 0) {
       13831                 :          0 :             arg->ch = FORMAT_READ(ctx);
       13832                 :          0 :             ctx->fmtpos++;
       13833                 :            :         }
       13834                 :            :     }
       13835   [ +  -  +  + ]:        482 :     else if (arg->ch >= '0' && arg->ch <= '9') {
       13836                 :          4 :         arg->width = arg->ch - '0';
       13837         [ +  - ]:          4 :         while (--ctx->fmtcnt >= 0) {
       13838                 :          4 :             arg->ch = FORMAT_READ(ctx);
       13839                 :          4 :             ctx->fmtpos++;
       13840   [ +  -  -  + ]:          4 :             if (arg->ch < '0' || arg->ch > '9')
       13841                 :            :                 break;
       13842                 :            :             /* Since arg->ch is unsigned, the RHS would end up as unsigned,
       13843                 :            :                mixing signed and unsigned comparison. Since arg->ch is between
       13844                 :            :                '0' and '9', casting to int is safe. */
       13845         [ #  # ]:          0 :             if (arg->width > (PY_SSIZE_T_MAX - ((int)arg->ch - '0')) / 10) {
       13846                 :          0 :                 PyErr_SetString(PyExc_ValueError,
       13847                 :            :                                 "width too big");
       13848                 :          0 :                 return -1;
       13849                 :            :             }
       13850                 :          0 :             arg->width = arg->width*10 + (arg->ch - '0');
       13851                 :            :         }
       13852                 :            :     }
       13853                 :            :
       13854                 :            :     /* Parse precision. Example: "%.3f" => prec=3 */
       13855         [ -  + ]:        482 :     if (arg->ch == '.') {
       13856                 :          0 :         arg->prec = 0;
       13857         [ #  # ]:          0 :         if (--ctx->fmtcnt >= 0) {
       13858                 :          0 :             arg->ch = FORMAT_READ(ctx);
       13859                 :          0 :             ctx->fmtpos++;
       13860                 :            :         }
       13861         [ #  # ]:          0 :         if (arg->ch == '*') {
       13862                 :          0 :             v = unicode_format_getnextarg(ctx);
       13863         [ #  # ]:          0 :             if (v == NULL)
       13864                 :          0 :                 return -1;
       13865         [ #  # ]:          0 :             if (!PyLong_Check(v)) {
       13866                 :          0 :                 PyErr_SetString(PyExc_TypeError,
       13867                 :            :                                 "* wants int");
       13868                 :          0 :                 return -1;
       13869                 :            :             }
       13870                 :          0 :             arg->prec = _PyLong_AsInt(v);
       13871   [ #  #  #  # ]:          0 :             if (arg->prec == -1 && PyErr_Occurred())
       13872                 :          0 :                 return -1;
       13873         [ #  # ]:          0 :             if (arg->prec < 0)
       13874                 :          0 :                 arg->prec = 0;
       13875         [ #  # ]:          0 :             if (--ctx->fmtcnt >= 0) {
       13876                 :          0 :                 arg->ch = FORMAT_READ(ctx);
       13877                 :          0 :                 ctx->fmtpos++;
       13878                 :            :             }
       13879                 :            :         }
       13880   [ #  #  #  # ]:          0 :         else if (arg->ch >= '0' && arg->ch <= '9') {
       13881                 :          0 :             arg->prec = arg->ch - '0';
       13882         [ #  # ]:          0 :             while (--ctx->fmtcnt >= 0) {
       13883                 :          0 :                 arg->ch = FORMAT_READ(ctx);
       13884                 :          0 :                 ctx->fmtpos++;
       13885   [ #  #  #  # ]:          0 :                 if (arg->ch < '0' || arg->ch > '9')
       13886                 :            :                     break;
       13887         [ #  # ]:          0 :                 if (arg->prec > (INT_MAX - ((int)arg->ch - '0')) / 10) {
       13888                 :          0 :                     PyErr_SetString(PyExc_ValueError,
       13889                 :            :                                     "precision too big");
       13890                 :          0 :                     return -1;
       13891                 :            :                 }
       13892                 :          0 :                 arg->prec = arg->prec*10 + (arg->ch - '0');
       13893                 :            :             }
       13894                 :            :         }
       13895                 :            :     }
       13896                 :            :
       13897                 :            :     /* Ignore "h", "l" and "L" format prefix (ex: "%hi" or "%ls") */
       13898         [ +  - ]:        482 :     if (ctx->fmtcnt >= 0) {
       13899   [ +  -  +  -  :        482 :         if (arg->ch == 'h' || arg->ch == 'l' || arg->ch == 'L') {
                       -  + ]
       13900         [ #  # ]:          0 :             if (--ctx->fmtcnt >= 0) {
       13901                 :          0 :                 arg->ch = FORMAT_READ(ctx);
       13902                 :          0 :                 ctx->fmtpos++;
       13903                 :            :             }
       13904                 :            :         }
       13905                 :            :     }
       13906         [ -  + ]:        482 :     if (ctx->fmtcnt < 0) {
       13907                 :          0 :         PyErr_SetString(PyExc_ValueError,
       13908                 :            :                         "incomplete format");
       13909                 :          0 :         return -1;
       13910                 :            :     }
       13911                 :        482 :     return 0;
       13912                 :            :
       13913                 :            : #undef FORMAT_READ
       13914                 :            : }
       13915                 :            :
       13916                 :            : /* Format one argument. Supported conversion specifiers:
       13917                 :            :
       13918                 :            :    - "s", "r", "a": any type
       13919                 :            :    - "i", "d", "u": int or float
       13920                 :            :    - "o", "x", "X": int
       13921                 :            :    - "e", "E", "f", "F", "g", "G": float
       13922                 :            :    - "c": int or str (1 character)
       13923                 :            :
       13924                 :            :    When possible, the output is written directly into the Unicode writer
       13925                 :            :    (ctx->writer). A string is created when padding is required.
       13926                 :            :
       13927                 :            :    Return 0 if the argument has been formatted into *p_str,
       13928                 :            :           1 if the argument has been written into ctx->writer,
       13929                 :            :          -1 on error. */
       13930                 :            : static int
       13931                 :        482 : unicode_format_arg_format(struct unicode_formatter_t *ctx,
       13932                 :            :                           struct unicode_format_arg_t *arg,
       13933                 :            :                           PyObject **p_str)
       13934                 :            : {
       13935                 :            :     PyObject *v;
       13936                 :        482 :     _PyUnicodeWriter *writer = &ctx->writer;
       13937                 :            :
       13938         [ +  + ]:        482 :     if (ctx->fmtcnt == 0)
       13939                 :        121 :         ctx->writer.overallocate = 0;
       13940                 :            :
       13941                 :        482 :     v = unicode_format_getnextarg(ctx);
       13942         [ -  + ]:        482 :     if (v == NULL)
       13943                 :          0 :         return -1;
       13944                 :            :
       13945                 :            :
       13946   [ +  +  -  -  :        482 :     switch (arg->ch) {
                          - ]
       13947                 :        369 :     case 's':
       13948                 :            :     case 'r':
       13949                 :            :     case 'a':
       13950   [ +  +  +  -  :        369 :         if (PyLong_CheckExact(v) && arg->width == -1 && arg->prec == -1) {
                       +  - ]
       13951                 :            :             /* Fast path */
       13952         [ -  + ]:          4 :             if (_PyLong_FormatWriter(writer, v, 10, arg->flags & F_ALT) == -1)
       13953                 :          0 :                 return -1;
       13954                 :          4 :             return 1;
       13955                 :            :         }
       13956                 :            :
       13957   [ +  +  +  - ]:        365 :         if (PyUnicode_CheckExact(v) && arg->ch == 's') {
       13958                 :        362 :             *p_str = Py_NewRef(v);
       13959                 :            :         }
       13960                 :            :         else {
       13961         [ +  - ]:          3 :             if (arg->ch == 's')
       13962                 :          3 :                 *p_str = PyObject_Str(v);
       13963         [ #  # ]:          0 :             else if (arg->ch == 'r')
       13964                 :          0 :                 *p_str = PyObject_Repr(v);
       13965                 :            :             else
       13966                 :          0 :                 *p_str = PyObject_ASCII(v);
       13967                 :            :         }
       13968                 :        365 :         break;
       13969                 :            :
       13970                 :        113 :     case 'i':
       13971                 :            :     case 'd':
       13972                 :            :     case 'u':
       13973                 :            :     case 'o':
       13974                 :            :     case 'x':
       13975                 :            :     case 'X':
       13976                 :            :     {
       13977                 :        113 :         int ret = mainformatlong(v, arg, p_str, writer);
       13978         [ +  + ]:        113 :         if (ret != 0)
       13979                 :        109 :             return ret;
       13980                 :          4 :         arg->sign = 1;
       13981                 :          4 :         break;
       13982                 :            :     }
       13983                 :            :
       13984                 :          0 :     case 'e':
       13985                 :            :     case 'E':
       13986                 :            :     case 'f':
       13987                 :            :     case 'F':
       13988                 :            :     case 'g':
       13989                 :            :     case 'G':
       13990   [ #  #  #  # ]:          0 :         if (arg->width == -1 && arg->prec == -1
       13991         [ #  # ]:          0 :             && !(arg->flags & (F_SIGN | F_BLANK)))
       13992                 :            :         {
       13993                 :            :             /* Fast path */
       13994         [ #  # ]:          0 :             if (formatfloat(v, arg, NULL, writer) == -1)
       13995                 :          0 :                 return -1;
       13996                 :          0 :             return 1;
       13997                 :            :         }
       13998                 :            :
       13999                 :          0 :         arg->sign = 1;
       14000         [ #  # ]:          0 :         if (formatfloat(v, arg, p_str, NULL) == -1)
       14001                 :          0 :             return -1;
       14002                 :          0 :         break;
       14003                 :            :
       14004                 :          0 :     case 'c':
       14005                 :            :     {
       14006                 :          0 :         Py_UCS4 ch = formatchar(v);
       14007         [ #  # ]:          0 :         if (ch == (Py_UCS4) -1)
       14008                 :          0 :             return -1;
       14009   [ #  #  #  # ]:          0 :         if (arg->width == -1 && arg->prec == -1) {
       14010                 :            :             /* Fast path */
       14011         [ #  # ]:          0 :             if (_PyUnicodeWriter_WriteCharInline(writer, ch) < 0)
       14012                 :          0 :                 return -1;
       14013                 :          0 :             return 1;
       14014                 :            :         }
       14015                 :          0 :         *p_str = PyUnicode_FromOrdinal(ch);
       14016                 :          0 :         break;
       14017                 :            :     }
       14018                 :            :
       14019                 :          0 :     default:
       14020                 :          0 :         PyErr_Format(PyExc_ValueError,
       14021                 :            :                      "unsupported format character '%c' (0x%x) "
       14022                 :            :                      "at index %zd",
       14023         [ #  # ]:          0 :                      (31<=arg->ch && arg->ch<=126) ? (char)arg->ch : '?',
       14024                 :          0 :                      (int)arg->ch,
       14025         [ #  # ]:          0 :                      ctx->fmtpos - 1);
       14026                 :          0 :         return -1;
       14027                 :            :     }
       14028         [ -  + ]:        369 :     if (*p_str == NULL)
       14029                 :          0 :         return -1;
       14030                 :            :     assert (PyUnicode_Check(*p_str));
       14031                 :        369 :     return 0;
       14032                 :            : }
       14033                 :            :
       14034                 :            : static int
       14035                 :        369 : unicode_format_arg_output(struct unicode_formatter_t *ctx,
       14036                 :            :                           struct unicode_format_arg_t *arg,
       14037                 :            :                           PyObject *str)
       14038                 :            : {
       14039                 :            :     Py_ssize_t len;
       14040                 :            :     int kind;
       14041                 :            :     const void *pbuf;
       14042                 :            :     Py_ssize_t pindex;
       14043                 :            :     Py_UCS4 signchar;
       14044                 :            :     Py_ssize_t buflen;
       14045                 :            :     Py_UCS4 maxchar;
       14046                 :            :     Py_ssize_t sublen;
       14047                 :        369 :     _PyUnicodeWriter *writer = &ctx->writer;
       14048                 :            :     Py_UCS4 fill;
       14049                 :            :
       14050                 :        369 :     fill = ' ';
       14051   [ +  +  +  - ]:        369 :     if (arg->sign && arg->flags & F_ZERO)
       14052                 :          4 :         fill = '0';
       14053                 :            :
       14054                 :        369 :     len = PyUnicode_GET_LENGTH(str);
       14055   [ +  +  -  + ]:        369 :     if ((arg->width == -1 || arg->width <= len)
       14056   [ -  +  -  - ]:        365 :         && (arg->prec == -1 || arg->prec >= len)
       14057         [ +  - ]:        365 :         && !(arg->flags & (F_SIGN | F_BLANK)))
       14058                 :            :     {
       14059                 :            :         /* Fast path */
       14060         [ -  + ]:        365 :         if (_PyUnicodeWriter_WriteStr(writer, str) == -1)
       14061                 :          0 :             return -1;
       14062                 :        365 :         return 0;
       14063                 :            :     }
       14064                 :            :
       14065                 :            :     /* Truncate the string for "s", "r" and "a" formats
       14066                 :            :        if the precision is set */
       14067   [ +  -  +  -  :          4 :     if (arg->ch == 's' || arg->ch == 'r' || arg->ch == 'a') {
                       -  + ]
       14068   [ #  #  #  # ]:          0 :         if (arg->prec >= 0 && len > arg->prec)
       14069                 :          0 :             len = arg->prec;
       14070                 :            :     }
       14071                 :            :
       14072                 :            :     /* Adjust sign and width */
       14073                 :          4 :     kind = PyUnicode_KIND(str);
       14074                 :          4 :     pbuf = PyUnicode_DATA(str);
       14075                 :          4 :     pindex = 0;
       14076                 :          4 :     signchar = '\0';
       14077         [ +  - ]:          4 :     if (arg->sign) {
       14078                 :          4 :         Py_UCS4 ch = PyUnicode_READ(kind, pbuf, pindex);
       14079   [ +  -  -  + ]:          4 :         if (ch == '-' || ch == '+') {
       14080                 :          0 :             signchar = ch;
       14081                 :          0 :             len--;
       14082                 :          0 :             pindex++;
       14083                 :            :         }
       14084         [ -  + ]:          4 :         else if (arg->flags & F_SIGN)
       14085                 :          0 :             signchar = '+';
       14086         [ -  + ]:          4 :         else if (arg->flags & F_BLANK)
       14087                 :          0 :             signchar = ' ';
       14088                 :            :         else
       14089                 :          4 :             arg->sign = 0;
       14090                 :            :     }
       14091         [ -  + ]:          4 :     if (arg->width < len)
       14092                 :          0 :         arg->width = len;
       14093                 :            :
       14094                 :            :     /* Prepare the writer */
       14095                 :          4 :     maxchar = writer->maxchar;
       14096         [ +  - ]:          4 :     if (!(arg->flags & F_LJUST)) {
       14097         [ -  + ]:          4 :         if (arg->sign) {
       14098         [ #  # ]:          0 :             if ((arg->width-1) > len)
       14099                 :          0 :                 maxchar = Py_MAX(maxchar, fill);
       14100                 :            :         }
       14101                 :            :         else {
       14102         [ +  - ]:          4 :             if (arg->width > len)
       14103                 :          4 :                 maxchar = Py_MAX(maxchar, fill);
       14104                 :            :         }
       14105                 :            :     }
       14106         [ -  + ]:          4 :     if (PyUnicode_MAX_CHAR_VALUE(str) > maxchar) {
       14107                 :          0 :         Py_UCS4 strmaxchar = _PyUnicode_FindMaxChar(str, 0, pindex+len);
       14108                 :          0 :         maxchar = Py_MAX(maxchar, strmaxchar);
       14109                 :            :     }
       14110                 :            :
       14111                 :          4 :     buflen = arg->width;
       14112   [ -  +  -  - ]:          4 :     if (arg->sign && len == arg->width)
       14113                 :          0 :         buflen++;
       14114   [ +  -  -  +  :          4 :     if (_PyUnicodeWriter_Prepare(writer, buflen, maxchar) == -1)
                 -  -  -  - ]
       14115                 :          0 :         return -1;
       14116                 :            :
       14117                 :            :     /* Write the sign if needed */
       14118         [ -  + ]:          4 :     if (arg->sign) {
       14119         [ #  # ]:          0 :         if (fill != ' ') {
       14120                 :          0 :             PyUnicode_WRITE(writer->kind, writer->data, writer->pos, signchar);
       14121                 :          0 :             writer->pos += 1;
       14122                 :            :         }
       14123         [ #  # ]:          0 :         if (arg->width > len)
       14124                 :          0 :             arg->width--;
       14125                 :            :     }
       14126                 :            :
       14127                 :            :     /* Write the numeric prefix for "x", "X" and "o" formats
       14128                 :            :        if the alternate form is used.
       14129                 :            :        For example, write "0x" for the "%#x" format. */
       14130   [ -  +  -  -  :          4 :     if ((arg->flags & F_ALT) && (arg->ch == 'x' || arg->ch == 'X' || arg->ch == 'o')) {
                 -  -  -  - ]
       14131                 :            :         assert(PyUnicode_READ(kind, pbuf, pindex) == '0');
       14132                 :            :         assert(PyUnicode_READ(kind, pbuf, pindex + 1) == arg->ch);
       14133         [ #  # ]:          0 :         if (fill != ' ') {
       14134                 :          0 :             PyUnicode_WRITE(writer->kind, writer->data, writer->pos, '0');
       14135                 :          0 :             PyUnicode_WRITE(writer->kind, writer->data, writer->pos+1, arg->ch);
       14136                 :          0 :             writer->pos += 2;
       14137                 :          0 :             pindex += 2;
       14138                 :            :         }
       14139                 :          0 :         arg->width -= 2;
       14140         [ #  # ]:          0 :         if (arg->width < 0)
       14141                 :          0 :             arg->width = 0;
       14142                 :          0 :         len -= 2;
       14143                 :            :     }
       14144                 :            :
       14145                 :            :     /* Pad left with the fill character if needed */
       14146   [ +  -  +  - ]:          4 :     if (arg->width > len && !(arg->flags & F_LJUST)) {
       14147                 :          4 :         sublen = arg->width - len;
       14148                 :          4 :         unicode_fill(writer->kind, writer->data, fill, writer->pos, sublen);
       14149                 :          4 :         writer->pos += sublen;
       14150                 :          4 :         arg->width = len;
       14151                 :            :     }
       14152                 :            :
       14153                 :            :     /* If padding with spaces: write sign if needed and/or numeric prefix if
       14154                 :            :        the alternate form is used */
       14155         [ -  + ]:          4 :     if (fill == ' ') {
       14156         [ #  # ]:          0 :         if (arg->sign) {
       14157                 :          0 :             PyUnicode_WRITE(writer->kind, writer->data, writer->pos, signchar);
       14158                 :          0 :             writer->pos += 1;
       14159                 :            :         }
       14160   [ #  #  #  #  :          0 :         if ((arg->flags & F_ALT) && (arg->ch == 'x' || arg->ch == 'X' || arg->ch == 'o')) {
                 #  #  #  # ]
       14161                 :            :             assert(PyUnicode_READ(kind, pbuf, pindex) == '0');
       14162                 :            :             assert(PyUnicode_READ(kind, pbuf, pindex+1) == arg->ch);
       14163                 :          0 :             PyUnicode_WRITE(writer->kind, writer->data, writer->pos, '0');
       14164                 :          0 :             PyUnicode_WRITE(writer->kind, writer->data, writer->pos+1, arg->ch);
       14165                 :          0 :             writer->pos += 2;
       14166                 :          0 :             pindex += 2;
       14167                 :            :         }
       14168                 :            :     }
       14169                 :            :
       14170                 :            :     /* Write characters */
       14171         [ +  - ]:          4 :     if (len) {
       14172                 :          4 :         _PyUnicode_FastCopyCharacters(writer->buffer, writer->pos,
       14173                 :            :                                       str, pindex, len);
       14174                 :          4 :         writer->pos += len;
       14175                 :            :     }
       14176                 :            :
       14177                 :            :     /* Pad right with the fill character if needed */
       14178         [ -  + ]:          4 :     if (arg->width > len) {
       14179                 :          0 :         sublen = arg->width - len;
       14180                 :          0 :         unicode_fill(writer->kind, writer->data, ' ', writer->pos, sublen);
       14181                 :          0 :         writer->pos += sublen;
       14182                 :            :     }
       14183                 :          4 :     return 0;
       14184                 :            : }
       14185                 :            :
       14186                 :            : /* Helper of PyUnicode_Format(): format one arg.
       14187                 :            :    Return 0 on success, raise an exception and return -1 on error. */
       14188                 :            : static int
       14189                 :        482 : unicode_format_arg(struct unicode_formatter_t *ctx)
       14190                 :            : {
       14191                 :            :     struct unicode_format_arg_t arg;
       14192                 :            :     PyObject *str;
       14193                 :            :     int ret;
       14194                 :            :
       14195                 :        482 :     arg.ch = PyUnicode_READ(ctx->fmtkind, ctx->fmtdata, ctx->fmtpos);
       14196         [ -  + ]:        482 :     if (arg.ch == '%') {
       14197                 :          0 :         ctx->fmtpos++;
       14198                 :          0 :         ctx->fmtcnt--;
       14199         [ #  # ]:          0 :         if (_PyUnicodeWriter_WriteCharInline(&ctx->writer, '%') < 0)
       14200                 :          0 :             return -1;
       14201                 :          0 :         return 0;
       14202                 :            :     }
       14203                 :        482 :     arg.flags = 0;
       14204                 :        482 :     arg.width = -1;
       14205                 :        482 :     arg.prec = -1;
       14206                 :        482 :     arg.sign = 0;
       14207                 :        482 :     str = NULL;
       14208                 :            :
       14209                 :        482 :     ret = unicode_format_arg_parse(ctx, &arg);
       14210         [ -  + ]:        482 :     if (ret == -1)
       14211                 :          0 :         return -1;
       14212                 :            :
       14213                 :        482 :     ret = unicode_format_arg_format(ctx, &arg, &str);
       14214         [ -  + ]:        482 :     if (ret == -1)
       14215                 :          0 :         return -1;
       14216                 :            :
       14217         [ +  + ]:        482 :     if (ret != 1) {
       14218                 :        369 :         ret = unicode_format_arg_output(ctx, &arg, str);
       14219                 :        369 :         Py_DECREF(str);
       14220         [ -  + ]:        369 :         if (ret == -1)
       14221                 :          0 :             return -1;
       14222                 :            :     }
       14223                 :            :
       14224   [ +  +  -  + ]:        482 :     if (ctx->dict && (ctx->argidx < ctx->arglen)) {
       14225                 :          0 :         PyErr_SetString(PyExc_TypeError,
       14226                 :            :                         "not all arguments converted during string formatting");
       14227                 :          0 :         return -1;
       14228                 :            :     }
       14229                 :        482 :     return 0;
       14230                 :            : }
       14231                 :            :
       14232                 :            : PyObject *
       14233                 :        230 : PyUnicode_Format(PyObject *format, PyObject *args)
       14234                 :            : {
       14235                 :            :     struct unicode_formatter_t ctx;
       14236                 :            :
       14237   [ +  -  -  + ]:        230 :     if (format == NULL || args == NULL) {
       14238                 :          0 :         PyErr_BadInternalCall();
       14239                 :          0 :         return NULL;
       14240                 :            :     }
       14241                 :            :
       14242         [ -  + ]:        230 :     if (ensure_unicode(format) < 0)
       14243                 :          0 :         return NULL;
       14244                 :            :
       14245                 :        230 :     ctx.fmtstr = format;
       14246                 :        230 :     ctx.fmtdata = PyUnicode_DATA(ctx.fmtstr);
       14247                 :        230 :     ctx.fmtkind = PyUnicode_KIND(ctx.fmtstr);
       14248                 :        230 :     ctx.fmtcnt = PyUnicode_GET_LENGTH(ctx.fmtstr);
       14249                 :        230 :     ctx.fmtpos = 0;
       14250                 :            :
       14251                 :        230 :     _PyUnicodeWriter_Init(&ctx.writer);
       14252                 :        230 :     ctx.writer.min_length = ctx.fmtcnt + 100;
       14253                 :        230 :     ctx.writer.overallocate = 1;
       14254                 :            :
       14255         [ +  + ]:        230 :     if (PyTuple_Check(args)) {
       14256                 :        171 :         ctx.arglen = PyTuple_Size(args);
       14257                 :        171 :         ctx.argidx = 0;
       14258                 :            :     }
       14259                 :            :     else {
       14260                 :         59 :         ctx.arglen = -1;
       14261                 :         59 :         ctx.argidx = -2;
       14262                 :            :     }
       14263                 :        230 :     ctx.args_owned = 0;
       14264   [ +  +  +  +  :        230 :     if (PyMapping_Check(args) && !PyTuple_Check(args) && !PyUnicode_Check(args))
                       +  + ]
       14265                 :          2 :         ctx.dict = args;
       14266                 :            :     else
       14267                 :        228 :         ctx.dict = NULL;
       14268                 :        230 :     ctx.args = args;
       14269                 :            :
       14270         [ +  + ]:       1176 :     while (--ctx.fmtcnt >= 0) {
       14271         [ +  + ]:        946 :         if (PyUnicode_READ(ctx.fmtkind, ctx.fmtdata, ctx.fmtpos) != '%') {
       14272                 :            :             Py_ssize_t nonfmtpos;
       14273                 :            :
       14274                 :        464 :             nonfmtpos = ctx.fmtpos++;
       14275   [ +  +  +  + ]:       4431 :             while (ctx.fmtcnt >= 0 &&
       14276                 :       2165 :                    PyUnicode_READ(ctx.fmtkind, ctx.fmtdata, ctx.fmtpos) != '%') {
       14277                 :       1802 :                 ctx.fmtpos++;
       14278                 :       1802 :                 ctx.fmtcnt--;
       14279                 :            :             }
       14280         [ +  + ]:        464 :             if (ctx.fmtcnt < 0) {
       14281                 :        101 :                 ctx.fmtpos--;
       14282                 :        101 :                 ctx.writer.overallocate = 0;
       14283                 :            :             }
       14284                 :            :
       14285         [ -  + ]:        464 :             if (_PyUnicodeWriter_WriteSubstring(&ctx.writer, ctx.fmtstr,
       14286                 :            :                                                 nonfmtpos, ctx.fmtpos) < 0)
       14287                 :          0 :                 goto onError;
       14288                 :            :         }
       14289                 :            :         else {
       14290                 :        482 :             ctx.fmtpos++;
       14291         [ -  + ]:        482 :             if (unicode_format_arg(&ctx) == -1)
       14292                 :          0 :                 goto onError;
       14293                 :            :         }
       14294                 :            :     }
       14295                 :            :
       14296   [ -  +  -  - ]:        230 :     if (ctx.argidx < ctx.arglen && !ctx.dict) {
       14297                 :          0 :         PyErr_SetString(PyExc_TypeError,
       14298                 :            :                         "not all arguments converted during string formatting");
       14299                 :          0 :         goto onError;
       14300                 :            :     }
       14301                 :            :
       14302         [ +  + ]:        230 :     if (ctx.args_owned) {
       14303                 :          2 :         Py_DECREF(ctx.args);
       14304                 :            :     }
       14305                 :        230 :     return _PyUnicodeWriter_Finish(&ctx.writer);
       14306                 :            :
       14307                 :          0 :   onError:
       14308                 :          0 :     _PyUnicodeWriter_Dealloc(&ctx.writer);
       14309         [ #  # ]:          0 :     if (ctx.args_owned) {
       14310                 :          0 :         Py_DECREF(ctx.args);
       14311                 :            :     }
       14312                 :          0 :     return NULL;
       14313                 :            : }
       14314                 :            :
       14315                 :            : static PyObject *
       14316                 :            : unicode_subtype_new(PyTypeObject *type, PyObject *unicode);
       14317                 :            :
       14318                 :            : /*[clinic input]
       14319                 :            : @classmethod
       14320                 :            : str.__new__ as unicode_new
       14321                 :            :
       14322                 :            :     object as x: object = NULL
       14323                 :            :     encoding: str = NULL
       14324                 :            :     errors: str = NULL
       14325                 :            :
       14326                 :            : [clinic start generated code]*/
       14327                 :            :
       14328                 :            : static PyObject *
       14329                 :       2168 : unicode_new_impl(PyTypeObject *type, PyObject *x, const char *encoding,
       14330                 :            :                  const char *errors)
       14331                 :            : /*[clinic end generated code: output=fc72d4878b0b57e9 input=e81255e5676d174e]*/
       14332                 :            : {
       14333                 :            :     PyObject *unicode;
       14334         [ -  + ]:       2168 :     if (x == NULL) {
       14335                 :          0 :         unicode = unicode_new_empty();
       14336                 :            :     }
       14337   [ +  +  +  - ]:       2168 :     else if (encoding == NULL && errors == NULL) {
       14338                 :       2051 :         unicode = PyObject_Str(x);
       14339                 :            :     }
       14340                 :            :     else {
       14341                 :        117 :         unicode = PyUnicode_FromEncodedObject(x, encoding, errors);
       14342                 :            :     }
       14343                 :            :
       14344   [ +  -  +  + ]:       2168 :     if (unicode != NULL && type != &PyUnicode_Type) {
       14345                 :         28 :         Py_SETREF(unicode, unicode_subtype_new(type, unicode));
       14346                 :            :     }
       14347                 :       2168 :     return unicode;
       14348                 :            : }
       14349                 :            :
       14350                 :            : static PyObject *
       14351                 :         28 : unicode_subtype_new(PyTypeObject *type, PyObject *unicode)
       14352                 :            : {
       14353                 :            :     PyObject *self;
       14354                 :            :     Py_ssize_t length, char_size;
       14355                 :            :     int share_utf8;
       14356                 :            :     int kind;
       14357                 :            :     void *data;
       14358                 :            :
       14359                 :            :     assert(PyType_IsSubtype(type, &PyUnicode_Type));
       14360                 :            :     assert(_PyUnicode_CHECK(unicode));
       14361                 :            :
       14362                 :         28 :     self = type->tp_alloc(type, 0);
       14363         [ -  + ]:         28 :     if (self == NULL) {
       14364                 :          0 :         return NULL;
       14365                 :            :     }
       14366                 :         28 :     kind = PyUnicode_KIND(unicode);
       14367                 :         28 :     length = PyUnicode_GET_LENGTH(unicode);
       14368                 :            :
       14369                 :         28 :     _PyUnicode_LENGTH(self) = length;
       14370                 :            : #ifdef Py_DEBUG
       14371                 :            :     _PyUnicode_HASH(self) = -1;
       14372                 :            : #else
       14373                 :         28 :     _PyUnicode_HASH(self) = _PyUnicode_HASH(unicode);
       14374                 :            : #endif
       14375                 :         28 :     _PyUnicode_STATE(self).interned = 0;
       14376                 :         28 :     _PyUnicode_STATE(self).kind = kind;
       14377                 :         28 :     _PyUnicode_STATE(self).compact = 0;
       14378                 :         28 :     _PyUnicode_STATE(self).ascii = _PyUnicode_STATE(unicode).ascii;
       14379                 :         28 :     _PyUnicode_UTF8_LENGTH(self) = 0;
       14380                 :         28 :     _PyUnicode_UTF8(self) = NULL;
       14381                 :         28 :     _PyUnicode_DATA_ANY(self) = NULL;
       14382                 :            :
       14383                 :         28 :     share_utf8 = 0;
       14384         [ +  - ]:         28 :     if (kind == PyUnicode_1BYTE_KIND) {
       14385                 :         28 :         char_size = 1;
       14386         [ +  - ]:         28 :         if (PyUnicode_MAX_CHAR_VALUE(unicode) < 128)
       14387                 :         28 :             share_utf8 = 1;
       14388                 :            :     }
       14389         [ #  # ]:          0 :     else if (kind == PyUnicode_2BYTE_KIND) {
       14390                 :          0 :         char_size = 2;
       14391                 :            :     }
       14392                 :            :     else {
       14393                 :            :         assert(kind == PyUnicode_4BYTE_KIND);
       14394                 :          0 :         char_size = 4;
       14395                 :            :     }
       14396                 :            :
       14397                 :            :     /* Ensure we won't overflow the length. */
       14398         [ -  + ]:         28 :     if (length > (PY_SSIZE_T_MAX / char_size - 1)) {
       14399                 :          0 :         PyErr_NoMemory();
       14400                 :          0 :         goto onError;
       14401                 :            :     }
       14402                 :         28 :     data = PyObject_Malloc((length + 1) * char_size);
       14403         [ -  + ]:         28 :     if (data == NULL) {
       14404                 :          0 :         PyErr_NoMemory();
       14405                 :          0 :         goto onError;
       14406                 :            :     }
       14407                 :            :
       14408                 :         28 :     _PyUnicode_DATA_ANY(self) = data;
       14409         [ +  - ]:         28 :     if (share_utf8) {
       14410                 :         28 :         _PyUnicode_UTF8_LENGTH(self) = length;
       14411                 :         28 :         _PyUnicode_UTF8(self) = data;
       14412                 :            :     }
       14413                 :            :
       14414                 :         28 :     memcpy(data, PyUnicode_DATA(unicode), kind * (length + 1));
       14415                 :            :     assert(_PyUnicode_CheckConsistency(self, 1));
       14416                 :            : #ifdef Py_DEBUG
       14417                 :            :     _PyUnicode_HASH(self) = _PyUnicode_HASH(unicode);
       14418                 :            : #endif
       14419                 :         28 :     return self;
       14420                 :            :
       14421                 :          0 : onError:
       14422                 :          0 :     Py_DECREF(self);
       14423                 :          0 :     return NULL;
       14424                 :            : }
       14425                 :            :
       14426                 :            : void
       14427                 :       5158 : _PyUnicode_ExactDealloc(PyObject *op)
       14428                 :            : {
       14429                 :            :     assert(PyUnicode_CheckExact(op));
       14430                 :       5158 :     unicode_dealloc(op);
       14431                 :       5158 : }
       14432                 :            :
       14433                 :            : PyDoc_STRVAR(unicode_doc,
       14434                 :            : "str(object='') -> str\n\
       14435                 :            : str(bytes_or_buffer[, encoding[, errors]]) -> str\n\
       14436                 :            : \n\
       14437                 :            : Create a new string object from the given object. If encoding or\n\
       14438                 :            : errors is specified, then the object must expose a data buffer\n\
       14439                 :            : that will be decoded using the given encoding and error handler.\n\
       14440                 :            : Otherwise, returns the result of object.__str__() (if defined)\n\
       14441                 :            : or repr(object).\n\
       14442                 :            : encoding defaults to sys.getdefaultencoding().\n\
       14443                 :            : errors defaults to 'strict'.");
       14444                 :            :
       14445                 :            : static PyObject *unicode_iter(PyObject *seq);
       14446                 :            :
       14447                 :            : PyTypeObject PyUnicode_Type = {
       14448                 :            :     PyVarObject_HEAD_INIT(&PyType_Type, 0)
       14449                 :            :     "str",                        /* tp_name */
       14450                 :            :     sizeof(PyUnicodeObject),      /* tp_basicsize */
       14451                 :            :     0,                            /* tp_itemsize */
       14452                 :            :     /* Slots */
       14453                 :            :     (destructor)unicode_dealloc,  /* tp_dealloc */
       14454                 :            :     0,                            /* tp_vectorcall_offset */
       14455                 :            :     0,                            /* tp_getattr */
       14456                 :            :     0,                            /* tp_setattr */
       14457                 :            :     0,                            /* tp_as_async */
       14458                 :            :     unicode_repr,                 /* tp_repr */
       14459                 :            :     &unicode_as_number,           /* tp_as_number */
       14460                 :            :     &unicode_as_sequence,         /* tp_as_sequence */
       14461                 :            :     &unicode_as_mapping,          /* tp_as_mapping */
       14462                 :            :     (hashfunc) unicode_hash,      /* tp_hash*/
       14463                 :            :     0,                            /* tp_call*/
       14464                 :            :     (reprfunc) unicode_str,       /* tp_str */
       14465                 :            :     PyObject_GenericGetAttr,      /* tp_getattro */
       14466                 :            :     0,                            /* tp_setattro */
       14467                 :            :     0,                            /* tp_as_buffer */
       14468                 :            :     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE |
       14469                 :            :         Py_TPFLAGS_UNICODE_SUBCLASS |
       14470                 :            :         _Py_TPFLAGS_MATCH_SELF, /* tp_flags */
       14471                 :            :     unicode_doc,                  /* tp_doc */
       14472                 :            :     0,                            /* tp_traverse */
       14473                 :            :     0,                            /* tp_clear */
       14474                 :            :     PyUnicode_RichCompare,        /* tp_richcompare */
       14475                 :            :     0,                            /* tp_weaklistoffset */
       14476                 :            :     unicode_iter,                 /* tp_iter */
       14477                 :            :     0,                            /* tp_iternext */
       14478                 :            :     unicode_methods,              /* tp_methods */
       14479                 :            :     0,                            /* tp_members */
       14480                 :            :     0,                            /* tp_getset */
       14481                 :            :     0,                            /* tp_base */
       14482                 :            :     0,                            /* tp_dict */
       14483                 :            :     0,                            /* tp_descr_get */
       14484                 :            :     0,                            /* tp_descr_set */
       14485                 :            :     0,                            /* tp_dictoffset */
       14486                 :            :     0,                            /* tp_init */
       14487                 :            :     0,                            /* tp_alloc */
       14488                 :            :     unicode_new,                  /* tp_new */
       14489                 :            :     PyObject_Del,                 /* tp_free */
       14490                 :            : };
       14491                 :            :
       14492                 :            : /* Initialize the Unicode implementation */
       14493                 :            :
       14494                 :            : static void
       14495                 :         29 : _init_global_state(void)
       14496                 :            : {
       14497                 :            :     static int initialized = 0;
       14498         [ -  + ]:         29 :     if (initialized) {
       14499                 :          0 :         return;
       14500                 :            :     }
       14501                 :         29 :     initialized = 1;
       14502                 :            :
       14503                 :            :     /* initialize the linebreak bloom filter */
       14504                 :         29 :     const Py_UCS2 linebreak[] = {
       14505                 :            :         0x000A, /* LINE FEED */
       14506                 :            :         0x000D, /* CARRIAGE RETURN */
       14507                 :            :         0x001C, /* FILE SEPARATOR */
       14508                 :            :         0x001D, /* GROUP SEPARATOR */
       14509                 :            :         0x001E, /* RECORD SEPARATOR */
       14510                 :            :         0x0085, /* NEXT LINE */
       14511                 :            :         0x2028, /* LINE SEPARATOR */
       14512                 :            :         0x2029, /* PARAGRAPH SEPARATOR */
       14513                 :            :     };
       14514                 :         29 :     bloom_linebreak = make_bloom_mask(
       14515                 :            :         PyUnicode_2BYTE_KIND, linebreak,
       14516                 :            :         Py_ARRAY_LENGTH(linebreak));
       14517                 :            : }
       14518                 :            :
       14519                 :            : void
       14520                 :         29 : _PyUnicode_InitState(PyInterpreterState *interp)
       14521                 :            : {
       14522         [ -  + ]:         29 :     if (!_Py_IsMainInterpreter(interp)) {
       14523                 :          0 :         return;
       14524                 :            :     }
       14525                 :         29 :     _init_global_state();
       14526                 :            : }
       14527                 :            :
       14528                 :            :
       14529                 :            : PyStatus
       14530                 :         29 : _PyUnicode_InitGlobalObjects(PyInterpreterState *interp)
       14531                 :            : {
       14532         [ -  + ]:         29 :     if (!_Py_IsMainInterpreter(interp)) {
       14533                 :          0 :         return _PyStatus_OK();
       14534                 :            :     }
       14535                 :            :
       14536                 :            :     // Initialize the global interned dict
       14537                 :         29 :     PyObject *interned = PyDict_New();
       14538         [ -  + ]:         29 :     if (interned == NULL) {
       14539                 :          0 :         PyErr_Clear();
       14540                 :          0 :         return _PyStatus_ERR("failed to create interned dict");
       14541                 :            :     }
       14542                 :            :
       14543                 :         29 :     set_interned_dict(interned);
       14544                 :            :
       14545                 :            :     /* Intern statically allocated string identifiers and deepfreeze strings.
       14546                 :            :      * This must be done before any module initialization so that statically
       14547                 :            :      * allocated string identifiers are used instead of heap allocated strings.
       14548                 :            :      * Deepfreeze uses the interned identifiers if present to save space
       14549                 :            :      * else generates them and they are interned to speed up dict lookups.
       14550                 :            :     */
       14551                 :         29 :     _PyUnicode_InitStaticStrings();
       14552                 :            :
       14553                 :            : #ifdef Py_DEBUG
       14554                 :            :     assert(_PyUnicode_CheckConsistency(&_Py_STR(empty), 1));
       14555                 :            :
       14556                 :            :     for (int i = 0; i < 256; i++) {
       14557                 :            :         assert(_PyUnicode_CheckConsistency(LATIN1(i), 1));
       14558                 :            :     }
       14559                 :            : #endif
       14560                 :            :
       14561                 :         29 :     return _PyStatus_OK();
       14562                 :            : }
       14563                 :            :
       14564                 :            :
       14565                 :            : PyStatus
       14566                 :         29 : _PyUnicode_InitTypes(PyInterpreterState *interp)
       14567                 :            : {
       14568         [ -  + ]:         29 :     if (!_Py_IsMainInterpreter(interp)) {
       14569                 :          0 :         return _PyStatus_OK();
       14570                 :            :     }
       14571                 :            :
       14572         [ -  + ]:         29 :     if (_PyStaticType_InitBuiltin(&EncodingMapType) < 0) {
       14573                 :          0 :         goto error;
       14574                 :            :     }
       14575         [ -  + ]:         29 :     if (_PyStaticType_InitBuiltin(&PyFieldNameIter_Type) < 0) {
       14576                 :          0 :         goto error;
       14577                 :            :     }
       14578         [ -  + ]:         29 :     if (_PyStaticType_InitBuiltin(&PyFormatterIter_Type) < 0) {
       14579                 :          0 :         goto error;
       14580                 :            :     }
       14581                 :         29 :     return _PyStatus_OK();
       14582                 :            :
       14583                 :          0 : error:
       14584                 :          0 :     return _PyStatus_ERR("Can't initialize unicode types");
       14585                 :            : }
       14586                 :            :
       14587                 :            :
       14588                 :            : void
       14589                 :    4325172 : PyUnicode_InternInPlace(PyObject **p)
       14590                 :            : {
       14591                 :    4325172 :     PyObject *s = *p;
       14592                 :            : #ifdef Py_DEBUG
       14593                 :            :     assert(s != NULL);
       14594                 :            :     assert(_PyUnicode_CHECK(s));
       14595                 :            : #else
       14596   [ +  -  -  + ]:    4325172 :     if (s == NULL || !PyUnicode_Check(s)) {
       14597                 :          0 :         return;
       14598                 :            :     }
       14599                 :            : #endif
       14600                 :            :
       14601                 :            :     /* If it's a subclass, we don't really know what putting
       14602                 :            :        it in the interned dict might do. */
       14603         [ -  + ]:    4325172 :     if (!PyUnicode_CheckExact(s)) {
       14604                 :          0 :         return;
       14605                 :            :     }
       14606                 :            :
       14607         [ +  + ]:    4325172 :     if (PyUnicode_CHECK_INTERNED(s)) {
       14608                 :    3559213 :         return;
       14609                 :            :     }
       14610                 :            :
       14611                 :     765959 :     PyObject *interned = get_interned_dict();
       14612                 :            :     assert(interned != NULL);
       14613                 :            :
       14614                 :     765959 :     PyObject *t = PyDict_SetDefault(interned, s, s);
       14615         [ -  + ]:     765959 :     if (t == NULL) {
       14616                 :          0 :         PyErr_Clear();
       14617                 :          0 :         return;
       14618                 :            :     }
       14619                 :            :
       14620         [ +  + ]:     765959 :     if (t != s) {
       14621                 :     645198 :         Py_SETREF(*p, Py_NewRef(t));
       14622                 :     645198 :         return;
       14623                 :            :     }
       14624                 :            :
       14625                 :            :     /* The two references in interned dict (key and value) are not counted by
       14626                 :            :        refcnt. unicode_dealloc() and _PyUnicode_ClearInterned() take care of
       14627                 :            :        this. */
       14628                 :     120761 :     Py_SET_REFCNT(s, Py_REFCNT(s) - 2);
       14629                 :     120761 :     _PyUnicode_STATE(s).interned = 1;
       14630                 :            : }
       14631                 :            :
       14632                 :            : // Function kept for the stable ABI.
       14633                 :            : PyAPI_FUNC(void) PyUnicode_InternImmortal(PyObject **);
       14634                 :            : void
       14635                 :          0 : PyUnicode_InternImmortal(PyObject **p)
       14636                 :            : {
       14637                 :          0 :     PyUnicode_InternInPlace(p);
       14638                 :            :     // Leak a reference on purpose
       14639                 :          0 :     Py_INCREF(*p);
       14640                 :          0 : }
       14641                 :            :
       14642                 :            : PyObject *
       14643                 :      86651 : PyUnicode_InternFromString(const char *cp)
       14644                 :            : {
       14645                 :      86651 :     PyObject *s = PyUnicode_FromString(cp);
       14646         [ -  + ]:      86651 :     if (s == NULL)
       14647                 :          0 :         return NULL;
       14648                 :      86651 :     PyUnicode_InternInPlace(&s);
       14649                 :      86651 :     return s;
       14650                 :            : }
       14651                 :            :
       14652                 :            :
       14653                 :            : void
       14654                 :         25 : _PyUnicode_ClearInterned(PyInterpreterState *interp)
       14655                 :            : {
       14656         [ -  + ]:         25 :     if (!_Py_IsMainInterpreter(interp)) {
       14657                 :            :         // interned dict is shared by all interpreters
       14658                 :          0 :         return;
       14659                 :            :     }
       14660                 :            :
       14661                 :         25 :     PyObject *interned = get_interned_dict();
       14662         [ -  + ]:         25 :     if (interned == NULL) {
       14663                 :          0 :         return;
       14664                 :            :     }
       14665                 :            :     assert(PyDict_CheckExact(interned));
       14666                 :            :
       14667                 :            :     /* Interned unicode strings are not forcibly deallocated; rather, we give
       14668                 :            :        them their stolen references back, and then clear and DECREF the
       14669                 :            :        interned dict. */
       14670                 :            :
       14671                 :            : #ifdef INTERNED_STATS
       14672                 :            :     fprintf(stderr, "releasing %zd interned strings\n",
       14673                 :            :             PyDict_GET_SIZE(interned));
       14674                 :            :
       14675                 :            :     Py_ssize_t total_length = 0;
       14676                 :            : #endif
       14677                 :         25 :     Py_ssize_t pos = 0;
       14678                 :            :     PyObject *s, *ignored_value;
       14679         [ +  + ]:      24593 :     while (PyDict_Next(interned, &pos, &s, &ignored_value)) {
       14680                 :            :         assert(PyUnicode_CHECK_INTERNED(s));
       14681                 :            :         // Restore the two references (key and value) ignored
       14682                 :            :         // by PyUnicode_InternInPlace().
       14683                 :      24568 :         Py_SET_REFCNT(s, Py_REFCNT(s) + 2);
       14684                 :            : #ifdef INTERNED_STATS
       14685                 :            :         total_length += PyUnicode_GET_LENGTH(s);
       14686                 :            : #endif
       14687                 :            :
       14688                 :      24568 :         _PyUnicode_STATE(s).interned = 0;
       14689                 :            :     }
       14690                 :            : #ifdef INTERNED_STATS
       14691                 :            :     fprintf(stderr,
       14692                 :            :             "total length of all interned strings: %zd characters\n",
       14693                 :            :             total_length);
       14694                 :            : #endif
       14695                 :            :
       14696                 :         25 :     PyDict_Clear(interned);
       14697                 :         25 :     Py_DECREF(interned);
       14698                 :         25 :     set_interned_dict(NULL);
       14699                 :            : }
       14700                 :            :
       14701                 :            :
       14702                 :            : /********************* Unicode Iterator **************************/
       14703                 :            :
       14704                 :            : typedef struct {
       14705                 :            :     PyObject_HEAD
       14706                 :            :     Py_ssize_t it_index;
       14707                 :            :     PyObject *it_seq;    /* Set to NULL when iterator is exhausted */
       14708                 :            : } unicodeiterobject;
       14709                 :            :
       14710                 :            : static void
       14711                 :       4314 : unicodeiter_dealloc(unicodeiterobject *it)
       14712                 :            : {
       14713                 :       4314 :     _PyObject_GC_UNTRACK(it);
       14714                 :       4314 :     Py_XDECREF(it->it_seq);
       14715                 :       4314 :     PyObject_GC_Del(it);
       14716                 :       4314 : }
       14717                 :            :
       14718                 :            : static int
       14719                 :          0 : unicodeiter_traverse(unicodeiterobject *it, visitproc visit, void *arg)
       14720                 :            : {
       14721   [ #  #  #  # ]:          0 :     Py_VISIT(it->it_seq);
       14722                 :          0 :     return 0;
       14723                 :            : }
       14724                 :            :
       14725                 :            : static PyObject *
       14726                 :       1797 : unicodeiter_next(unicodeiterobject *it)
       14727                 :            : {
       14728                 :            :     PyObject *seq;
       14729                 :            :
       14730                 :            :     assert(it != NULL);
       14731                 :       1797 :     seq = it->it_seq;
       14732         [ -  + ]:       1797 :     if (seq == NULL)
       14733                 :          0 :         return NULL;
       14734                 :            :     assert(_PyUnicode_CHECK(seq));
       14735                 :            :
       14736         [ +  + ]:       1797 :     if (it->it_index < PyUnicode_GET_LENGTH(seq)) {
       14737                 :       1776 :         int kind = PyUnicode_KIND(seq);
       14738                 :       1776 :         const void *data = PyUnicode_DATA(seq);
       14739                 :       1776 :         Py_UCS4 chr = PyUnicode_READ(kind, data, it->it_index);
       14740                 :       1776 :         it->it_index++;
       14741                 :       1776 :         return unicode_char(chr);
       14742                 :            :     }
       14743                 :            :
       14744                 :         21 :     it->it_seq = NULL;
       14745                 :         21 :     Py_DECREF(seq);
       14746                 :         21 :     return NULL;
       14747                 :            : }
       14748                 :            :
       14749                 :            : static PyObject *
       14750                 :     114454 : unicode_ascii_iter_next(unicodeiterobject *it)
       14751                 :            : {
       14752                 :            :     assert(it != NULL);
       14753                 :     114454 :     PyObject *seq = it->it_seq;
       14754         [ -  + ]:     114454 :     if (seq == NULL) {
       14755                 :          0 :         return NULL;
       14756                 :            :     }
       14757                 :            :     assert(_PyUnicode_CHECK(seq));
       14758                 :            :     assert(PyUnicode_IS_COMPACT_ASCII(seq));
       14759         [ +  + ]:     114454 :     if (it->it_index < PyUnicode_GET_LENGTH(seq)) {
       14760                 :     110186 :         const void *data = ((void*)(_PyASCIIObject_CAST(seq) + 1));
       14761                 :     110186 :         Py_UCS1 chr = (Py_UCS1)PyUnicode_READ(PyUnicode_1BYTE_KIND,
       14762                 :            :                                               data, it->it_index);
       14763                 :     110186 :         it->it_index++;
       14764                 :     110186 :         PyObject *item = (PyObject*)&_Py_SINGLETON(strings).ascii[chr];
       14765                 :     110186 :         return Py_NewRef(item);
       14766                 :            :     }
       14767                 :       4268 :     it->it_seq = NULL;
       14768                 :       4268 :     Py_DECREF(seq);
       14769                 :       4268 :     return NULL;
       14770                 :            : }
       14771                 :            :
       14772                 :            : static PyObject *
       14773                 :          0 : unicodeiter_len(unicodeiterobject *it, PyObject *Py_UNUSED(ignored))
       14774                 :            : {
       14775                 :          0 :     Py_ssize_t len = 0;
       14776         [ #  # ]:          0 :     if (it->it_seq)
       14777                 :          0 :         len = PyUnicode_GET_LENGTH(it->it_seq) - it->it_index;
       14778                 :          0 :     return PyLong_FromSsize_t(len);
       14779                 :            : }
       14780                 :            :
       14781                 :            : PyDoc_STRVAR(length_hint_doc, "Private method returning an estimate of len(list(it)).");
       14782                 :            :
       14783                 :            : static PyObject *
       14784                 :          0 : unicodeiter_reduce(unicodeiterobject *it, PyObject *Py_UNUSED(ignored))
       14785                 :            : {
       14786                 :          0 :     PyObject *iter = _PyEval_GetBuiltin(&_Py_ID(iter));
       14787                 :            :
       14788                 :            :     /* _PyEval_GetBuiltin can invoke arbitrary code,
       14789                 :            :      * call must be before access of iterator pointers.
       14790                 :            :      * see issue #101765 */
       14791                 :            :
       14792         [ #  # ]:          0 :     if (it->it_seq != NULL) {
       14793                 :          0 :         return Py_BuildValue("N(O)n", iter, it->it_seq, it->it_index);
       14794                 :            :     } else {
       14795                 :          0 :         PyObject *u = unicode_new_empty();
       14796         [ #  # ]:          0 :         if (u == NULL) {
       14797                 :          0 :             Py_XDECREF(iter);
       14798                 :          0 :             return NULL;
       14799                 :            :         }
       14800                 :          0 :         return Py_BuildValue("N(N)", iter, u);
       14801                 :            :     }
       14802                 :            : }
       14803                 :            :
       14804                 :            : PyDoc_STRVAR(reduce_doc, "Return state information for pickling.");
       14805                 :            :
       14806                 :            : static PyObject *
       14807                 :          0 : unicodeiter_setstate(unicodeiterobject *it, PyObject *state)
       14808                 :            : {
       14809                 :          0 :     Py_ssize_t index = PyLong_AsSsize_t(state);
       14810   [ #  #  #  # ]:          0 :     if (index == -1 && PyErr_Occurred())
       14811                 :          0 :         return NULL;
       14812         [ #  # ]:          0 :     if (it->it_seq != NULL) {
       14813         [ #  # ]:          0 :         if (index < 0)
       14814                 :          0 :             index = 0;
       14815         [ #  # ]:          0 :         else if (index > PyUnicode_GET_LENGTH(it->it_seq))
       14816                 :          0 :             index = PyUnicode_GET_LENGTH(it->it_seq); /* iterator truncated */
       14817                 :          0 :         it->it_index = index;
       14818                 :            :     }
       14819                 :          0 :     Py_RETURN_NONE;
       14820                 :            : }
       14821                 :            :
       14822                 :            : PyDoc_STRVAR(setstate_doc, "Set state information for unpickling.");
       14823                 :            :
       14824                 :            : static PyMethodDef unicodeiter_methods[] = {
       14825                 :            :     {"__length_hint__", (PyCFunction)unicodeiter_len, METH_NOARGS,
       14826                 :            :      length_hint_doc},
       14827                 :            :     {"__reduce__",      (PyCFunction)unicodeiter_reduce, METH_NOARGS,
       14828                 :            :      reduce_doc},
       14829                 :            :     {"__setstate__",    (PyCFunction)unicodeiter_setstate, METH_O,
       14830                 :            :      setstate_doc},
       14831                 :            :     {NULL,      NULL}       /* sentinel */
       14832                 :            : };
       14833                 :            :
       14834                 :            : PyTypeObject PyUnicodeIter_Type = {
       14835                 :            :     PyVarObject_HEAD_INIT(&PyType_Type, 0)
       14836                 :            :     "str_iterator",         /* tp_name */
       14837                 :            :     sizeof(unicodeiterobject),      /* tp_basicsize */
       14838                 :            :     0,                  /* tp_itemsize */
       14839                 :            :     /* methods */
       14840                 :            :     (destructor)unicodeiter_dealloc,    /* tp_dealloc */
       14841                 :            :     0,                  /* tp_vectorcall_offset */
       14842                 :            :     0,                  /* tp_getattr */
       14843                 :            :     0,                  /* tp_setattr */
       14844                 :            :     0,                  /* tp_as_async */
       14845                 :            :     0,                  /* tp_repr */
       14846                 :            :     0,                  /* tp_as_number */
       14847                 :            :     0,                  /* tp_as_sequence */
       14848                 :            :     0,                  /* tp_as_mapping */
       14849                 :            :     0,                  /* tp_hash */
       14850                 :            :     0,                  /* tp_call */
       14851                 :            :     0,                  /* tp_str */
       14852                 :            :     PyObject_GenericGetAttr,        /* tp_getattro */
       14853                 :            :     0,                  /* tp_setattro */
       14854                 :            :     0,                  /* tp_as_buffer */
       14855                 :            :     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,/* tp_flags */
       14856                 :            :     0,                  /* tp_doc */
       14857                 :            :     (traverseproc)unicodeiter_traverse, /* tp_traverse */
       14858                 :            :     0,                  /* tp_clear */
       14859                 :            :     0,                  /* tp_richcompare */
       14860                 :            :     0,                  /* tp_weaklistoffset */
       14861                 :            :     PyObject_SelfIter,          /* tp_iter */
       14862                 :            :     (iternextfunc)unicodeiter_next,     /* tp_iternext */
       14863                 :            :     unicodeiter_methods,            /* tp_methods */
       14864                 :            :     0,
       14865                 :            : };
       14866                 :            :
       14867                 :            : PyTypeObject _PyUnicodeASCIIIter_Type = {
       14868                 :            :     PyVarObject_HEAD_INIT(&PyType_Type, 0)
       14869                 :            :     .tp_name = "str_ascii_iterator",
       14870                 :            :     .tp_basicsize = sizeof(unicodeiterobject),
       14871                 :            :     .tp_dealloc = (destructor)unicodeiter_dealloc,
       14872                 :            :     .tp_getattro = PyObject_GenericGetAttr,
       14873                 :            :     .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,
       14874                 :            :     .tp_traverse = (traverseproc)unicodeiter_traverse,
       14875                 :            :     .tp_iter = PyObject_SelfIter,
       14876                 :            :     .tp_iternext = (iternextfunc)unicode_ascii_iter_next,
       14877                 :            :     .tp_methods = unicodeiter_methods,
       14878                 :            : };
       14879                 :            :
       14880                 :            : static PyObject *
       14881                 :       4314 : unicode_iter(PyObject *seq)
       14882                 :            : {
       14883                 :            :     unicodeiterobject *it;
       14884                 :            :
       14885         [ -  + ]:       4314 :     if (!PyUnicode_Check(seq)) {
       14886                 :          0 :         PyErr_BadInternalCall();
       14887                 :          0 :         return NULL;
       14888                 :            :     }
       14889         [ +  + ]:       4314 :     if (PyUnicode_IS_COMPACT_ASCII(seq)) {
       14890                 :       4293 :         it = PyObject_GC_New(unicodeiterobject, &_PyUnicodeASCIIIter_Type);
       14891                 :            :     }
       14892                 :            :     else {
       14893                 :         21 :         it = PyObject_GC_New(unicodeiterobject, &PyUnicodeIter_Type);
       14894                 :            :     }
       14895         [ -  + ]:       4314 :     if (it == NULL)
       14896                 :          0 :         return NULL;
       14897                 :       4314 :     it->it_index = 0;
       14898                 :       4314 :     it->it_seq = Py_NewRef(seq);
       14899                 :       4314 :     _PyObject_GC_TRACK(it);
       14900                 :       4314 :     return (PyObject *)it;
       14901                 :            : }
       14902                 :            :
       14903                 :            : static int
       14904                 :        100 : encode_wstr_utf8(wchar_t *wstr, char **str, const char *name)
       14905                 :            : {
       14906                 :            :     int res;
       14907                 :        100 :     res = _Py_EncodeUTF8Ex(wstr, str, NULL, NULL, 1, _Py_ERROR_STRICT);
       14908         [ -  + ]:        100 :     if (res == -2) {
       14909                 :          0 :         PyErr_Format(PyExc_RuntimeWarning, "cannot decode %s", name);
       14910                 :          0 :         return -1;
       14911                 :            :     }
       14912         [ -  + ]:        100 :     if (res < 0) {
       14913                 :          0 :         PyErr_NoMemory();
       14914                 :          0 :         return -1;
       14915                 :            :     }
       14916                 :        100 :     return 0;
       14917                 :            : }
       14918                 :            :
       14919                 :            :
       14920                 :            : static int
       14921                 :         50 : config_get_codec_name(wchar_t **config_encoding)
       14922                 :            : {
       14923                 :            :     char *encoding;
       14924         [ -  + ]:         50 :     if (encode_wstr_utf8(*config_encoding, &encoding, "stdio_encoding") < 0) {
       14925                 :          0 :         return -1;
       14926                 :            :     }
       14927                 :            :
       14928                 :         50 :     PyObject *name_obj = NULL;
       14929                 :         50 :     PyObject *codec = _PyCodec_Lookup(encoding);
       14930                 :         50 :     PyMem_RawFree(encoding);
       14931                 :            :
       14932         [ -  + ]:         50 :     if (!codec)
       14933                 :          0 :         goto error;
       14934                 :            :
       14935                 :         50 :     name_obj = PyObject_GetAttrString(codec, "name");
       14936         [ +  - ]:         50 :     Py_CLEAR(codec);
       14937         [ -  + ]:         50 :     if (!name_obj) {
       14938                 :          0 :         goto error;
       14939                 :            :     }
       14940                 :            :
       14941                 :         50 :     wchar_t *wname = PyUnicode_AsWideCharString(name_obj, NULL);
       14942                 :         50 :     Py_DECREF(name_obj);
       14943         [ -  + ]:         50 :     if (wname == NULL) {
       14944                 :          0 :         goto error;
       14945                 :            :     }
       14946                 :            :
       14947                 :         50 :     wchar_t *raw_wname = _PyMem_RawWcsdup(wname);
       14948         [ -  + ]:         50 :     if (raw_wname == NULL) {
       14949                 :          0 :         PyMem_Free(wname);
       14950                 :          0 :         PyErr_NoMemory();
       14951                 :          0 :         goto error;
       14952                 :            :     }
       14953                 :            :
       14954                 :         50 :     PyMem_RawFree(*config_encoding);
       14955                 :         50 :     *config_encoding = raw_wname;
       14956                 :            :
       14957                 :         50 :     PyMem_Free(wname);
       14958                 :         50 :     return 0;
       14959                 :            :
       14960                 :          0 : error:
       14961                 :          0 :     Py_XDECREF(codec);
       14962                 :          0 :     Py_XDECREF(name_obj);
       14963                 :          0 :     return -1;
       14964                 :            : }
       14965                 :            :
       14966                 :            :
       14967                 :            : static PyStatus
       14968                 :         25 : init_stdio_encoding(PyInterpreterState *interp)
       14969                 :            : {
       14970                 :            :     /* Update the stdio encoding to the normalized Python codec name. */
       14971                 :         25 :     PyConfig *config = (PyConfig*)_PyInterpreterState_GetConfig(interp);
       14972         [ -  + ]:         25 :     if (config_get_codec_name(&config->stdio_encoding) < 0) {
       14973                 :          0 :         return _PyStatus_ERR("failed to get the Python codec name "
       14974                 :            :                              "of the stdio encoding");
       14975                 :            :     }
       14976                 :         25 :     return _PyStatus_OK();
       14977                 :            : }
       14978                 :            :
       14979                 :            :
       14980                 :            : static int
       14981                 :         25 : init_fs_codec(PyInterpreterState *interp)
       14982                 :            : {
       14983                 :         25 :     const PyConfig *config = _PyInterpreterState_GetConfig(interp);
       14984                 :            :
       14985                 :            :     _Py_error_handler error_handler;
       14986                 :         25 :     error_handler = get_error_handler_wide(config->filesystem_errors);
       14987         [ -  + ]:         25 :     if (error_handler == _Py_ERROR_UNKNOWN) {
       14988                 :          0 :         PyErr_SetString(PyExc_RuntimeError, "unknown filesystem error handler");
       14989                 :          0 :         return -1;
       14990                 :            :     }
       14991                 :            :
       14992                 :            :     char *encoding, *errors;
       14993         [ -  + ]:         25 :     if (encode_wstr_utf8(config->filesystem_encoding,
       14994                 :            :                          &encoding,
       14995                 :            :                          "filesystem_encoding") < 0) {
       14996                 :          0 :         return -1;
       14997                 :            :     }
       14998                 :            :
       14999         [ -  + ]:         25 :     if (encode_wstr_utf8(config->filesystem_errors,
       15000                 :            :                          &errors,
       15001                 :            :                          "filesystem_errors") < 0) {
       15002                 :          0 :         PyMem_RawFree(encoding);
       15003                 :          0 :         return -1;
       15004                 :            :     }
       15005                 :            :
       15006                 :         25 :     struct _Py_unicode_fs_codec *fs_codec = &interp->unicode.fs_codec;
       15007                 :         25 :     PyMem_RawFree(fs_codec->encoding);
       15008                 :         25 :     fs_codec->encoding = encoding;
       15009                 :            :     /* encoding has been normalized by init_fs_encoding() */
       15010                 :         25 :     fs_codec->utf8 = (strcmp(encoding, "utf-8") == 0);
       15011                 :         25 :     PyMem_RawFree(fs_codec->errors);
       15012                 :         25 :     fs_codec->errors = errors;
       15013                 :         25 :     fs_codec->error_handler = error_handler;
       15014                 :            :
       15015                 :            : #ifdef _Py_FORCE_UTF8_FS_ENCODING
       15016                 :            :     assert(fs_codec->utf8 == 1);
       15017                 :            : #endif
       15018                 :            :
       15019                 :            :     /* At this point, PyUnicode_EncodeFSDefault() and
       15020                 :            :        PyUnicode_DecodeFSDefault() can now use the Python codec rather than
       15021                 :            :        the C implementation of the filesystem encoding. */
       15022                 :            :
       15023                 :            :     /* Set Py_FileSystemDefaultEncoding and Py_FileSystemDefaultEncodeErrors
       15024                 :            :        global configuration variables. */
       15025         [ -  + ]:         25 :     if (_Py_SetFileSystemEncoding(fs_codec->encoding,
       15026                 :         25 :                                   fs_codec->errors) < 0) {
       15027                 :          0 :         PyErr_NoMemory();
       15028                 :          0 :         return -1;
       15029                 :            :     }
       15030                 :         25 :     return 0;
       15031                 :            : }
       15032                 :            :
       15033                 :            :
       15034                 :            : static PyStatus
       15035                 :         25 : init_fs_encoding(PyThreadState *tstate)
       15036                 :            : {
       15037                 :         25 :     PyInterpreterState *interp = tstate->interp;
       15038                 :            :
       15039                 :            :     /* Update the filesystem encoding to the normalized Python codec name.
       15040                 :            :        For example, replace "ANSI_X3.4-1968" (locale encoding) with "ascii"
       15041                 :            :        (Python codec name). */
       15042                 :         25 :     PyConfig *config = (PyConfig*)_PyInterpreterState_GetConfig(interp);
       15043         [ -  + ]:         25 :     if (config_get_codec_name(&config->filesystem_encoding) < 0) {
       15044                 :          0 :         _Py_DumpPathConfig(tstate);
       15045                 :          0 :         return _PyStatus_ERR("failed to get the Python codec "
       15046                 :            :                              "of the filesystem encoding");
       15047                 :            :     }
       15048                 :            :
       15049         [ -  + ]:         25 :     if (init_fs_codec(interp) < 0) {
       15050                 :          0 :         return _PyStatus_ERR("cannot initialize filesystem codec");
       15051                 :            :     }
       15052                 :         25 :     return _PyStatus_OK();
       15053                 :            : }
       15054                 :            :
       15055                 :            :
       15056                 :            : PyStatus
       15057                 :         25 : _PyUnicode_InitEncodings(PyThreadState *tstate)
       15058                 :            : {
       15059                 :         25 :     PyStatus status = init_fs_encoding(tstate);
       15060         [ -  + ]:         25 :     if (_PyStatus_EXCEPTION(status)) {
       15061                 :          0 :         return status;
       15062                 :            :     }
       15063                 :            :
       15064                 :         25 :     return init_stdio_encoding(tstate->interp);
       15065                 :            : }
       15066                 :            :
       15067                 :            :
       15068                 :            : static void
       15069                 :         25 : _PyUnicode_FiniEncodings(struct _Py_unicode_fs_codec *fs_codec)
       15070                 :            : {
       15071                 :         25 :     PyMem_RawFree(fs_codec->encoding);
       15072                 :         25 :     fs_codec->encoding = NULL;
       15073                 :         25 :     fs_codec->utf8 = 0;
       15074                 :         25 :     PyMem_RawFree(fs_codec->errors);
       15075                 :         25 :     fs_codec->errors = NULL;
       15076                 :         25 :     fs_codec->error_handler = _Py_ERROR_UNKNOWN;
       15077                 :         25 : }
       15078                 :            :
       15079                 :            :
       15080                 :            : #ifdef MS_WINDOWS
       15081                 :            : int
       15082                 :            : _PyUnicode_EnableLegacyWindowsFSEncoding(void)
       15083                 :            : {
       15084                 :            :     PyInterpreterState *interp = _PyInterpreterState_GET();
       15085                 :            :     PyConfig *config = (PyConfig *)_PyInterpreterState_GetConfig(interp);
       15086                 :            :
       15087                 :            :     /* Set the filesystem encoding to mbcs/replace (PEP 529) */
       15088                 :            :     wchar_t *encoding = _PyMem_RawWcsdup(L"mbcs");
       15089                 :            :     wchar_t *errors = _PyMem_RawWcsdup(L"replace");
       15090                 :            :     if (encoding == NULL || errors == NULL) {
       15091                 :            :         PyMem_RawFree(encoding);
       15092                 :            :         PyMem_RawFree(errors);
       15093                 :            :         PyErr_NoMemory();
       15094                 :            :         return -1;
       15095                 :            :     }
       15096                 :            :
       15097                 :            :     PyMem_RawFree(config->filesystem_encoding);
       15098                 :            :     config->filesystem_encoding = encoding;
       15099                 :            :     PyMem_RawFree(config->filesystem_errors);
       15100                 :            :     config->filesystem_errors = errors;
       15101                 :            :
       15102                 :            :     return init_fs_codec(interp);
       15103                 :            : }
       15104                 :            : #endif
       15105                 :            :
       15106                 :            :
       15107                 :            : #ifdef Py_DEBUG
       15108                 :            : static inline int
       15109                 :            : unicode_is_finalizing(void)
       15110                 :            : {
       15111                 :            :     return (get_interned_dict() == NULL);
       15112                 :            : }
       15113                 :            : #endif
       15114                 :            :
       15115                 :            :
       15116                 :            : void
       15117                 :         25 : _PyUnicode_FiniTypes(PyInterpreterState *interp)
       15118                 :            : {
       15119         [ -  + ]:         25 :     if (!_Py_IsMainInterpreter(interp)) {
       15120                 :          0 :         return;
       15121                 :            :     }
       15122                 :            :
       15123                 :         25 :     _PyStaticType_Dealloc(&EncodingMapType);
       15124                 :         25 :     _PyStaticType_Dealloc(&PyFieldNameIter_Type);
       15125                 :         25 :     _PyStaticType_Dealloc(&PyFormatterIter_Type);
       15126                 :            : }
       15127                 :            :
       15128                 :            :
       15129                 :            : void
       15130                 :         25 : _PyUnicode_Fini(PyInterpreterState *interp)
       15131                 :            : {
       15132                 :         25 :     struct _Py_unicode_state *state = &interp->unicode;
       15133                 :            :
       15134                 :         25 :     if (_Py_IsMainInterpreter(interp)) {
       15135                 :            :         // _PyUnicode_ClearInterned() must be called before _PyUnicode_Fini()
       15136                 :            :         assert(get_interned_dict() == NULL);
       15137                 :            :         // bpo-47182: force a unicodedata CAPI capsule re-import on
       15138                 :            :         // subsequent initialization of main interpreter.
       15139                 :            :     }
       15140                 :            :
       15141                 :         25 :     _PyUnicode_FiniEncodings(&state->fs_codec);
       15142                 :         25 :     interp->unicode.ucnhash_capi = NULL;
       15143                 :            :
       15144                 :         25 :     unicode_clear_identifiers(state);
       15145                 :         25 : }
       15146                 :            :
       15147                 :            : /* A _string module, to export formatter_parser and formatter_field_name_split
       15148                 :            :    to the string.Formatter class implemented in Python. */
       15149                 :            :
       15150                 :            : static PyMethodDef _string_methods[] = {
       15151                 :            :     {"formatter_field_name_split", (PyCFunction) formatter_field_name_split,
       15152                 :            :      METH_O, PyDoc_STR("split the argument as a field name")},
       15153                 :            :     {"formatter_parser", (PyCFunction) formatter_parser,
       15154                 :            :      METH_O, PyDoc_STR("parse the argument as a format string")},
       15155                 :            :     {NULL, NULL}
       15156                 :            : };
       15157                 :            :
       15158                 :            : static struct PyModuleDef _string_module = {
       15159                 :            :     PyModuleDef_HEAD_INIT,
       15160                 :            :     .m_name = "_string",
       15161                 :            :     .m_doc = PyDoc_STR("string helper module"),
       15162                 :            :     .m_size = 0,
       15163                 :            :     .m_methods = _string_methods,
       15164                 :            : };
       15165                 :            :
       15166                 :            : PyMODINIT_FUNC
       15167                 :          3 : PyInit__string(void)
       15168                 :            : {
       15169                 :          3 :     return PyModuleDef_Init(&_string_module);
       15170                 :            : }
       15171                 :            :
       15172                 :            :
       15173                 :            : #ifdef __cplusplus
       15174                 :            : }
       15175                 :            : #endif

Generated by: LCOV version 1.14