• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* PyByteArray (bytearray) implementation */
2 
3 #include "Python.h"
4 #include "pycore_abstract.h"      // _PyIndex_Check()
5 #include "pycore_bytes_methods.h"
6 #include "pycore_bytesobject.h"
7 #include "pycore_ceval.h"         // _PyEval_GetBuiltin()
8 #include "pycore_object.h"        // _PyObject_GC_UNTRACK()
9 #include "pycore_strhex.h"        // _Py_strhex_with_sep()
10 #include "pycore_long.h"          // _PyLong_FromUnsignedChar()
11 #include "bytesobject.h"
12 
13 /*[clinic input]
14 class bytearray "PyByteArrayObject *" "&PyByteArray_Type"
15 [clinic start generated code]*/
16 /*[clinic end generated code: output=da39a3ee5e6b4b0d input=5535b77c37a119e0]*/
17 
18 /* For PyByteArray_AS_STRING(). */
19 char _PyByteArray_empty_string[] = "";
20 
21 /* Helpers */
22 
23 static int
_getbytevalue(PyObject * arg,int * value)24 _getbytevalue(PyObject* arg, int *value)
25 {
26     int overflow;
27     long face_value = PyLong_AsLongAndOverflow(arg, &overflow);
28 
29     if (face_value == -1 && PyErr_Occurred()) {
30         *value = -1;
31         return 0;
32     }
33     if (face_value < 0 || face_value >= 256) {
34         /* this includes an overflow in converting to C long */
35         PyErr_SetString(PyExc_ValueError, "byte must be in range(0, 256)");
36         *value = -1;
37         return 0;
38     }
39 
40     *value = face_value;
41     return 1;
42 }
43 
44 static int
bytearray_getbuffer(PyByteArrayObject * obj,Py_buffer * view,int flags)45 bytearray_getbuffer(PyByteArrayObject *obj, Py_buffer *view, int flags)
46 {
47     if (view == NULL) {
48         PyErr_SetString(PyExc_BufferError,
49             "bytearray_getbuffer: view==NULL argument is obsolete");
50         return -1;
51     }
52     void *ptr = (void *) PyByteArray_AS_STRING(obj);
53     if (PyBuffer_FillInfo(view, (PyObject*)obj, ptr, Py_SIZE(obj), 0, flags) < 0) {
54         return -1;
55     }
56     obj->ob_exports++;
57     return 0;
58 }
59 
60 static void
bytearray_releasebuffer(PyByteArrayObject * obj,Py_buffer * view)61 bytearray_releasebuffer(PyByteArrayObject *obj, Py_buffer *view)
62 {
63     obj->ob_exports--;
64     assert(obj->ob_exports >= 0);
65 }
66 
67 static int
_canresize(PyByteArrayObject * self)68 _canresize(PyByteArrayObject *self)
69 {
70     if (self->ob_exports > 0) {
71         PyErr_SetString(PyExc_BufferError,
72                 "Existing exports of data: object cannot be re-sized");
73         return 0;
74     }
75     return 1;
76 }
77 
78 #include "clinic/bytearrayobject.c.h"
79 
80 /* Direct API functions */
81 
82 PyObject *
PyByteArray_FromObject(PyObject * input)83 PyByteArray_FromObject(PyObject *input)
84 {
85     return PyObject_CallOneArg((PyObject *)&PyByteArray_Type, input);
86 }
87 
88 static PyObject *
_PyByteArray_FromBufferObject(PyObject * obj)89 _PyByteArray_FromBufferObject(PyObject *obj)
90 {
91     PyObject *result;
92     Py_buffer view;
93 
94     if (PyObject_GetBuffer(obj, &view, PyBUF_FULL_RO) < 0) {
95         return NULL;
96     }
97     result = PyByteArray_FromStringAndSize(NULL, view.len);
98     if (result != NULL &&
99         PyBuffer_ToContiguous(PyByteArray_AS_STRING(result),
100                               &view, view.len, 'C') < 0)
101     {
102         Py_CLEAR(result);
103     }
104     PyBuffer_Release(&view);
105     return result;
106 }
107 
108 PyObject *
PyByteArray_FromStringAndSize(const char * bytes,Py_ssize_t size)109 PyByteArray_FromStringAndSize(const char *bytes, Py_ssize_t size)
110 {
111     PyByteArrayObject *new;
112     Py_ssize_t alloc;
113 
114     if (size < 0) {
115         PyErr_SetString(PyExc_SystemError,
116             "Negative size passed to PyByteArray_FromStringAndSize");
117         return NULL;
118     }
119 
120     /* Prevent buffer overflow when setting alloc to size+1. */
121     if (size == PY_SSIZE_T_MAX) {
122         return PyErr_NoMemory();
123     }
124 
125     new = PyObject_New(PyByteArrayObject, &PyByteArray_Type);
126     if (new == NULL)
127         return NULL;
128 
129     if (size == 0) {
130         new->ob_bytes = NULL;
131         alloc = 0;
132     }
133     else {
134         alloc = size + 1;
135         new->ob_bytes = PyMem_Malloc(alloc);
136         if (new->ob_bytes == NULL) {
137             Py_DECREF(new);
138             return PyErr_NoMemory();
139         }
140         if (bytes != NULL && size > 0)
141             memcpy(new->ob_bytes, bytes, size);
142         new->ob_bytes[size] = '\0';  /* Trailing null byte */
143     }
144     Py_SET_SIZE(new, size);
145     new->ob_alloc = alloc;
146     new->ob_start = new->ob_bytes;
147     new->ob_exports = 0;
148 
149     return (PyObject *)new;
150 }
151 
152 Py_ssize_t
PyByteArray_Size(PyObject * self)153 PyByteArray_Size(PyObject *self)
154 {
155     assert(self != NULL);
156     assert(PyByteArray_Check(self));
157 
158     return PyByteArray_GET_SIZE(self);
159 }
160 
161 char  *
PyByteArray_AsString(PyObject * self)162 PyByteArray_AsString(PyObject *self)
163 {
164     assert(self != NULL);
165     assert(PyByteArray_Check(self));
166 
167     return PyByteArray_AS_STRING(self);
168 }
169 
170 int
PyByteArray_Resize(PyObject * self,Py_ssize_t requested_size)171 PyByteArray_Resize(PyObject *self, Py_ssize_t requested_size)
172 {
173     void *sval;
174     PyByteArrayObject *obj = ((PyByteArrayObject *)self);
175     /* All computations are done unsigned to avoid integer overflows
176        (see issue #22335). */
177     size_t alloc = (size_t) obj->ob_alloc;
178     size_t logical_offset = (size_t) (obj->ob_start - obj->ob_bytes);
179     size_t size = (size_t) requested_size;
180 
181     assert(self != NULL);
182     assert(PyByteArray_Check(self));
183     assert(logical_offset <= alloc);
184     assert(requested_size >= 0);
185 
186     if (requested_size == Py_SIZE(self)) {
187         return 0;
188     }
189     if (!_canresize(obj)) {
190         return -1;
191     }
192 
193     if (size + logical_offset + 1 <= alloc) {
194         /* Current buffer is large enough to host the requested size,
195            decide on a strategy. */
196         if (size < alloc / 2) {
197             /* Major downsize; resize down to exact size */
198             alloc = size + 1;
199         }
200         else {
201             /* Minor downsize; quick exit */
202             Py_SET_SIZE(self, size);
203             PyByteArray_AS_STRING(self)[size] = '\0'; /* Trailing null */
204             return 0;
205         }
206     }
207     else {
208         /* Need growing, decide on a strategy */
209         if (size <= alloc * 1.125) {
210             /* Moderate upsize; overallocate similar to list_resize() */
211             alloc = size + (size >> 3) + (size < 9 ? 3 : 6);
212         }
213         else {
214             /* Major upsize; resize up to exact size */
215             alloc = size + 1;
216         }
217     }
218     if (alloc > PY_SSIZE_T_MAX) {
219         PyErr_NoMemory();
220         return -1;
221     }
222 
223     if (logical_offset > 0) {
224         sval = PyMem_Malloc(alloc);
225         if (sval == NULL) {
226             PyErr_NoMemory();
227             return -1;
228         }
229         memcpy(sval, PyByteArray_AS_STRING(self),
230                Py_MIN((size_t)requested_size, (size_t)Py_SIZE(self)));
231         PyMem_Free(obj->ob_bytes);
232     }
233     else {
234         sval = PyMem_Realloc(obj->ob_bytes, alloc);
235         if (sval == NULL) {
236             PyErr_NoMemory();
237             return -1;
238         }
239     }
240 
241     obj->ob_bytes = obj->ob_start = sval;
242     Py_SET_SIZE(self, size);
243     obj->ob_alloc = alloc;
244     obj->ob_bytes[size] = '\0'; /* Trailing null byte */
245 
246     return 0;
247 }
248 
249 PyObject *
PyByteArray_Concat(PyObject * a,PyObject * b)250 PyByteArray_Concat(PyObject *a, PyObject *b)
251 {
252     Py_buffer va, vb;
253     PyByteArrayObject *result = NULL;
254 
255     va.len = -1;
256     vb.len = -1;
257     if (PyObject_GetBuffer(a, &va, PyBUF_SIMPLE) != 0 ||
258         PyObject_GetBuffer(b, &vb, PyBUF_SIMPLE) != 0) {
259             PyErr_Format(PyExc_TypeError, "can't concat %.100s to %.100s",
260                          Py_TYPE(b)->tp_name, Py_TYPE(a)->tp_name);
261             goto done;
262     }
263 
264     if (va.len > PY_SSIZE_T_MAX - vb.len) {
265         PyErr_NoMemory();
266         goto done;
267     }
268 
269     result = (PyByteArrayObject *) \
270         PyByteArray_FromStringAndSize(NULL, va.len + vb.len);
271     // result->ob_bytes is NULL if result is an empty bytearray:
272     // if va.len + vb.len equals zero.
273     if (result != NULL && result->ob_bytes != NULL) {
274         memcpy(result->ob_bytes, va.buf, va.len);
275         memcpy(result->ob_bytes + va.len, vb.buf, vb.len);
276     }
277 
278   done:
279     if (va.len != -1)
280         PyBuffer_Release(&va);
281     if (vb.len != -1)
282         PyBuffer_Release(&vb);
283     return (PyObject *)result;
284 }
285 
286 /* Functions stuffed into the type object */
287 
288 static Py_ssize_t
bytearray_length(PyByteArrayObject * self)289 bytearray_length(PyByteArrayObject *self)
290 {
291     return Py_SIZE(self);
292 }
293 
294 static PyObject *
bytearray_iconcat(PyByteArrayObject * self,PyObject * other)295 bytearray_iconcat(PyByteArrayObject *self, PyObject *other)
296 {
297     Py_ssize_t size;
298     Py_buffer vo;
299 
300     if (PyObject_GetBuffer(other, &vo, PyBUF_SIMPLE) != 0) {
301         PyErr_Format(PyExc_TypeError, "can't concat %.100s to %.100s",
302                      Py_TYPE(other)->tp_name, Py_TYPE(self)->tp_name);
303         return NULL;
304     }
305 
306     size = Py_SIZE(self);
307     if (size > PY_SSIZE_T_MAX - vo.len) {
308         PyBuffer_Release(&vo);
309         return PyErr_NoMemory();
310     }
311     if (PyByteArray_Resize((PyObject *)self, size + vo.len) < 0) {
312         PyBuffer_Release(&vo);
313         return NULL;
314     }
315     memcpy(PyByteArray_AS_STRING(self) + size, vo.buf, vo.len);
316     PyBuffer_Release(&vo);
317     return Py_NewRef(self);
318 }
319 
320 static PyObject *
bytearray_repeat(PyByteArrayObject * self,Py_ssize_t count)321 bytearray_repeat(PyByteArrayObject *self, Py_ssize_t count)
322 {
323     if (count < 0)
324         count = 0;
325     const Py_ssize_t mysize = Py_SIZE(self);
326     if (count > 0 && mysize > PY_SSIZE_T_MAX / count)
327         return PyErr_NoMemory();
328     Py_ssize_t size = mysize * count;
329     PyByteArrayObject* result = (PyByteArrayObject *)PyByteArray_FromStringAndSize(NULL, size);
330     const char* buf = PyByteArray_AS_STRING(self);
331     if (result != NULL && size != 0) {
332         _PyBytes_Repeat(result->ob_bytes, size, buf, mysize);
333     }
334     return (PyObject *)result;
335 }
336 
337 static PyObject *
bytearray_irepeat(PyByteArrayObject * self,Py_ssize_t count)338 bytearray_irepeat(PyByteArrayObject *self, Py_ssize_t count)
339 {
340     if (count < 0)
341         count = 0;
342     else if (count == 1) {
343         return Py_NewRef(self);
344     }
345 
346     const Py_ssize_t mysize = Py_SIZE(self);
347     if (count > 0 && mysize > PY_SSIZE_T_MAX / count)
348         return PyErr_NoMemory();
349     const Py_ssize_t size = mysize * count;
350     if (PyByteArray_Resize((PyObject *)self, size) < 0)
351         return NULL;
352 
353     char* buf = PyByteArray_AS_STRING(self);
354     _PyBytes_Repeat(buf, size, buf, mysize);
355 
356     return Py_NewRef(self);
357 }
358 
359 static PyObject *
bytearray_getitem(PyByteArrayObject * self,Py_ssize_t i)360 bytearray_getitem(PyByteArrayObject *self, Py_ssize_t i)
361 {
362     if (i < 0 || i >= Py_SIZE(self)) {
363         PyErr_SetString(PyExc_IndexError, "bytearray index out of range");
364         return NULL;
365     }
366     return _PyLong_FromUnsignedChar((unsigned char)(self->ob_start[i]));
367 }
368 
369 static PyObject *
bytearray_subscript(PyByteArrayObject * self,PyObject * index)370 bytearray_subscript(PyByteArrayObject *self, PyObject *index)
371 {
372     if (_PyIndex_Check(index)) {
373         Py_ssize_t i = PyNumber_AsSsize_t(index, PyExc_IndexError);
374 
375         if (i == -1 && PyErr_Occurred())
376             return NULL;
377 
378         if (i < 0)
379             i += PyByteArray_GET_SIZE(self);
380 
381         if (i < 0 || i >= Py_SIZE(self)) {
382             PyErr_SetString(PyExc_IndexError, "bytearray index out of range");
383             return NULL;
384         }
385         return _PyLong_FromUnsignedChar((unsigned char)(self->ob_start[i]));
386     }
387     else if (PySlice_Check(index)) {
388         Py_ssize_t start, stop, step, slicelength, i;
389         size_t cur;
390         if (PySlice_Unpack(index, &start, &stop, &step) < 0) {
391             return NULL;
392         }
393         slicelength = PySlice_AdjustIndices(PyByteArray_GET_SIZE(self),
394                                             &start, &stop, step);
395 
396         if (slicelength <= 0)
397             return PyByteArray_FromStringAndSize("", 0);
398         else if (step == 1) {
399             return PyByteArray_FromStringAndSize(
400                 PyByteArray_AS_STRING(self) + start, slicelength);
401         }
402         else {
403             char *source_buf = PyByteArray_AS_STRING(self);
404             char *result_buf;
405             PyObject *result;
406 
407             result = PyByteArray_FromStringAndSize(NULL, slicelength);
408             if (result == NULL)
409                 return NULL;
410 
411             result_buf = PyByteArray_AS_STRING(result);
412             for (cur = start, i = 0; i < slicelength;
413                  cur += step, i++) {
414                      result_buf[i] = source_buf[cur];
415             }
416             return result;
417         }
418     }
419     else {
420         PyErr_Format(PyExc_TypeError,
421                      "bytearray indices must be integers or slices, not %.200s",
422                      Py_TYPE(index)->tp_name);
423         return NULL;
424     }
425 }
426 
427 static int
bytearray_setslice_linear(PyByteArrayObject * self,Py_ssize_t lo,Py_ssize_t hi,char * bytes,Py_ssize_t bytes_len)428 bytearray_setslice_linear(PyByteArrayObject *self,
429                           Py_ssize_t lo, Py_ssize_t hi,
430                           char *bytes, Py_ssize_t bytes_len)
431 {
432     Py_ssize_t avail = hi - lo;
433     char *buf = PyByteArray_AS_STRING(self);
434     Py_ssize_t growth = bytes_len - avail;
435     int res = 0;
436     assert(avail >= 0);
437 
438     if (growth < 0) {
439         if (!_canresize(self))
440             return -1;
441 
442         if (lo == 0) {
443             /* Shrink the buffer by advancing its logical start */
444             self->ob_start -= growth;
445             /*
446               0   lo               hi             old_size
447               |   |<----avail----->|<-----tail------>|
448               |      |<-bytes_len->|<-----tail------>|
449               0    new_lo         new_hi          new_size
450             */
451         }
452         else {
453             /*
454               0   lo               hi               old_size
455               |   |<----avail----->|<-----tomove------>|
456               |   |<-bytes_len->|<-----tomove------>|
457               0   lo         new_hi              new_size
458             */
459             memmove(buf + lo + bytes_len, buf + hi,
460                     Py_SIZE(self) - hi);
461         }
462         if (PyByteArray_Resize((PyObject *)self,
463                                Py_SIZE(self) + growth) < 0) {
464             /* Issue #19578: Handling the memory allocation failure here is
465                tricky here because the bytearray object has already been
466                modified. Depending on growth and lo, the behaviour is
467                different.
468 
469                If growth < 0 and lo != 0, the operation is completed, but a
470                MemoryError is still raised and the memory block is not
471                shrunk. Otherwise, the bytearray is restored in its previous
472                state and a MemoryError is raised. */
473             if (lo == 0) {
474                 self->ob_start += growth;
475                 return -1;
476             }
477             /* memmove() removed bytes, the bytearray object cannot be
478                restored in its previous state. */
479             Py_SET_SIZE(self, Py_SIZE(self) + growth);
480             res = -1;
481         }
482         buf = PyByteArray_AS_STRING(self);
483     }
484     else if (growth > 0) {
485         if (Py_SIZE(self) > (Py_ssize_t)PY_SSIZE_T_MAX - growth) {
486             PyErr_NoMemory();
487             return -1;
488         }
489 
490         if (PyByteArray_Resize((PyObject *)self,
491                                Py_SIZE(self) + growth) < 0) {
492             return -1;
493         }
494         buf = PyByteArray_AS_STRING(self);
495         /* Make the place for the additional bytes */
496         /*
497           0   lo        hi               old_size
498           |   |<-avail->|<-----tomove------>|
499           |   |<---bytes_len-->|<-----tomove------>|
500           0   lo            new_hi              new_size
501          */
502         memmove(buf + lo + bytes_len, buf + hi,
503                 Py_SIZE(self) - lo - bytes_len);
504     }
505 
506     if (bytes_len > 0)
507         memcpy(buf + lo, bytes, bytes_len);
508     return res;
509 }
510 
511 static int
bytearray_setslice(PyByteArrayObject * self,Py_ssize_t lo,Py_ssize_t hi,PyObject * values)512 bytearray_setslice(PyByteArrayObject *self, Py_ssize_t lo, Py_ssize_t hi,
513                PyObject *values)
514 {
515     Py_ssize_t needed;
516     void *bytes;
517     Py_buffer vbytes;
518     int res = 0;
519 
520     vbytes.len = -1;
521     if (values == (PyObject *)self) {
522         /* Make a copy and call this function recursively */
523         int err;
524         values = PyByteArray_FromStringAndSize(PyByteArray_AS_STRING(values),
525                                                PyByteArray_GET_SIZE(values));
526         if (values == NULL)
527             return -1;
528         err = bytearray_setslice(self, lo, hi, values);
529         Py_DECREF(values);
530         return err;
531     }
532     if (values == NULL) {
533         /* del b[lo:hi] */
534         bytes = NULL;
535         needed = 0;
536     }
537     else {
538         if (PyObject_GetBuffer(values, &vbytes, PyBUF_SIMPLE) != 0) {
539             PyErr_Format(PyExc_TypeError,
540                          "can't set bytearray slice from %.100s",
541                          Py_TYPE(values)->tp_name);
542             return -1;
543         }
544         needed = vbytes.len;
545         bytes = vbytes.buf;
546     }
547 
548     if (lo < 0)
549         lo = 0;
550     if (hi < lo)
551         hi = lo;
552     if (hi > Py_SIZE(self))
553         hi = Py_SIZE(self);
554 
555     res = bytearray_setslice_linear(self, lo, hi, bytes, needed);
556     if (vbytes.len != -1)
557         PyBuffer_Release(&vbytes);
558     return res;
559 }
560 
561 static int
bytearray_setitem(PyByteArrayObject * self,Py_ssize_t i,PyObject * value)562 bytearray_setitem(PyByteArrayObject *self, Py_ssize_t i, PyObject *value)
563 {
564     int ival = -1;
565 
566     // GH-91153: We need to do this *before* the size check, in case value has a
567     // nasty __index__ method that changes the size of the bytearray:
568     if (value && !_getbytevalue(value, &ival)) {
569         return -1;
570     }
571 
572     if (i < 0) {
573         i += Py_SIZE(self);
574     }
575 
576     if (i < 0 || i >= Py_SIZE(self)) {
577         PyErr_SetString(PyExc_IndexError, "bytearray index out of range");
578         return -1;
579     }
580 
581     if (value == NULL) {
582         return bytearray_setslice(self, i, i+1, NULL);
583     }
584 
585     assert(0 <= ival && ival < 256);
586     PyByteArray_AS_STRING(self)[i] = ival;
587     return 0;
588 }
589 
590 static int
bytearray_ass_subscript(PyByteArrayObject * self,PyObject * index,PyObject * values)591 bytearray_ass_subscript(PyByteArrayObject *self, PyObject *index, PyObject *values)
592 {
593     Py_ssize_t start, stop, step, slicelen, needed;
594     char *buf, *bytes;
595     buf = PyByteArray_AS_STRING(self);
596 
597     if (_PyIndex_Check(index)) {
598         Py_ssize_t i = PyNumber_AsSsize_t(index, PyExc_IndexError);
599 
600         if (i == -1 && PyErr_Occurred()) {
601             return -1;
602         }
603 
604         int ival = -1;
605 
606         // GH-91153: We need to do this *before* the size check, in case values
607         // has a nasty __index__ method that changes the size of the bytearray:
608         if (values && !_getbytevalue(values, &ival)) {
609             return -1;
610         }
611 
612         if (i < 0) {
613             i += PyByteArray_GET_SIZE(self);
614         }
615 
616         if (i < 0 || i >= Py_SIZE(self)) {
617             PyErr_SetString(PyExc_IndexError, "bytearray index out of range");
618             return -1;
619         }
620 
621         if (values == NULL) {
622             /* Fall through to slice assignment */
623             start = i;
624             stop = i + 1;
625             step = 1;
626             slicelen = 1;
627         }
628         else {
629             assert(0 <= ival && ival < 256);
630             buf[i] = (char)ival;
631             return 0;
632         }
633     }
634     else if (PySlice_Check(index)) {
635         if (PySlice_Unpack(index, &start, &stop, &step) < 0) {
636             return -1;
637         }
638         slicelen = PySlice_AdjustIndices(PyByteArray_GET_SIZE(self), &start,
639                                          &stop, step);
640     }
641     else {
642         PyErr_Format(PyExc_TypeError,
643                      "bytearray indices must be integers or slices, not %.200s",
644                       Py_TYPE(index)->tp_name);
645         return -1;
646     }
647 
648     if (values == NULL) {
649         bytes = NULL;
650         needed = 0;
651     }
652     else if (values == (PyObject *)self || !PyByteArray_Check(values)) {
653         int err;
654         if (PyNumber_Check(values) || PyUnicode_Check(values)) {
655             PyErr_SetString(PyExc_TypeError,
656                             "can assign only bytes, buffers, or iterables "
657                             "of ints in range(0, 256)");
658             return -1;
659         }
660         /* Make a copy and call this function recursively */
661         values = PyByteArray_FromObject(values);
662         if (values == NULL)
663             return -1;
664         err = bytearray_ass_subscript(self, index, values);
665         Py_DECREF(values);
666         return err;
667     }
668     else {
669         assert(PyByteArray_Check(values));
670         bytes = PyByteArray_AS_STRING(values);
671         needed = Py_SIZE(values);
672     }
673     /* Make sure b[5:2] = ... inserts before 5, not before 2. */
674     if ((step < 0 && start < stop) ||
675         (step > 0 && start > stop))
676         stop = start;
677     if (step == 1) {
678         return bytearray_setslice_linear(self, start, stop, bytes, needed);
679     }
680     else {
681         if (needed == 0) {
682             /* Delete slice */
683             size_t cur;
684             Py_ssize_t i;
685 
686             if (!_canresize(self))
687                 return -1;
688 
689             if (slicelen == 0)
690                 /* Nothing to do here. */
691                 return 0;
692 
693             if (step < 0) {
694                 stop = start + 1;
695                 start = stop + step * (slicelen - 1) - 1;
696                 step = -step;
697             }
698             for (cur = start, i = 0;
699                  i < slicelen; cur += step, i++) {
700                 Py_ssize_t lim = step - 1;
701 
702                 if (cur + step >= (size_t)PyByteArray_GET_SIZE(self))
703                     lim = PyByteArray_GET_SIZE(self) - cur - 1;
704 
705                 memmove(buf + cur - i,
706                         buf + cur + 1, lim);
707             }
708             /* Move the tail of the bytes, in one chunk */
709             cur = start + (size_t)slicelen*step;
710             if (cur < (size_t)PyByteArray_GET_SIZE(self)) {
711                 memmove(buf + cur - slicelen,
712                         buf + cur,
713                         PyByteArray_GET_SIZE(self) - cur);
714             }
715             if (PyByteArray_Resize((PyObject *)self,
716                                PyByteArray_GET_SIZE(self) - slicelen) < 0)
717                 return -1;
718 
719             return 0;
720         }
721         else {
722             /* Assign slice */
723             Py_ssize_t i;
724             size_t cur;
725 
726             if (needed != slicelen) {
727                 PyErr_Format(PyExc_ValueError,
728                              "attempt to assign bytes of size %zd "
729                              "to extended slice of size %zd",
730                              needed, slicelen);
731                 return -1;
732             }
733             for (cur = start, i = 0; i < slicelen; cur += step, i++)
734                 buf[cur] = bytes[i];
735             return 0;
736         }
737     }
738 }
739 
740 /*[clinic input]
741 bytearray.__init__
742 
743     source as arg: object = NULL
744     encoding: str = NULL
745     errors: str = NULL
746 
747 [clinic start generated code]*/
748 
749 static int
bytearray___init___impl(PyByteArrayObject * self,PyObject * arg,const char * encoding,const char * errors)750 bytearray___init___impl(PyByteArrayObject *self, PyObject *arg,
751                         const char *encoding, const char *errors)
752 /*[clinic end generated code: output=4ce1304649c2f8b3 input=1141a7122eefd7b9]*/
753 {
754     Py_ssize_t count;
755     PyObject *it;
756     PyObject *(*iternext)(PyObject *);
757 
758     if (Py_SIZE(self) != 0) {
759         /* Empty previous contents (yes, do this first of all!) */
760         if (PyByteArray_Resize((PyObject *)self, 0) < 0)
761             return -1;
762     }
763 
764     /* Make a quick exit if no first argument */
765     if (arg == NULL) {
766         if (encoding != NULL || errors != NULL) {
767             PyErr_SetString(PyExc_TypeError,
768                             encoding != NULL ?
769                             "encoding without a string argument" :
770                             "errors without a string argument");
771             return -1;
772         }
773         return 0;
774     }
775 
776     if (PyUnicode_Check(arg)) {
777         /* Encode via the codec registry */
778         PyObject *encoded, *new;
779         if (encoding == NULL) {
780             PyErr_SetString(PyExc_TypeError,
781                             "string argument without an encoding");
782             return -1;
783         }
784         encoded = PyUnicode_AsEncodedString(arg, encoding, errors);
785         if (encoded == NULL)
786             return -1;
787         assert(PyBytes_Check(encoded));
788         new = bytearray_iconcat(self, encoded);
789         Py_DECREF(encoded);
790         if (new == NULL)
791             return -1;
792         Py_DECREF(new);
793         return 0;
794     }
795 
796     /* If it's not unicode, there can't be encoding or errors */
797     if (encoding != NULL || errors != NULL) {
798         PyErr_SetString(PyExc_TypeError,
799                         encoding != NULL ?
800                         "encoding without a string argument" :
801                         "errors without a string argument");
802         return -1;
803     }
804 
805     /* Is it an int? */
806     if (_PyIndex_Check(arg)) {
807         count = PyNumber_AsSsize_t(arg, PyExc_OverflowError);
808         if (count == -1 && PyErr_Occurred()) {
809             if (!PyErr_ExceptionMatches(PyExc_TypeError))
810                 return -1;
811             PyErr_Clear();  /* fall through */
812         }
813         else {
814             if (count < 0) {
815                 PyErr_SetString(PyExc_ValueError, "negative count");
816                 return -1;
817             }
818             if (count > 0) {
819                 if (PyByteArray_Resize((PyObject *)self, count))
820                     return -1;
821                 memset(PyByteArray_AS_STRING(self), 0, count);
822             }
823             return 0;
824         }
825     }
826 
827     /* Use the buffer API */
828     if (PyObject_CheckBuffer(arg)) {
829         Py_ssize_t size;
830         Py_buffer view;
831         if (PyObject_GetBuffer(arg, &view, PyBUF_FULL_RO) < 0)
832             return -1;
833         size = view.len;
834         if (PyByteArray_Resize((PyObject *)self, size) < 0) goto fail;
835         if (PyBuffer_ToContiguous(PyByteArray_AS_STRING(self),
836             &view, size, 'C') < 0)
837             goto fail;
838         PyBuffer_Release(&view);
839         return 0;
840     fail:
841         PyBuffer_Release(&view);
842         return -1;
843     }
844 
845     if (PyList_CheckExact(arg) || PyTuple_CheckExact(arg)) {
846         Py_ssize_t size = PySequence_Fast_GET_SIZE(arg);
847         if (PyByteArray_Resize((PyObject *)self, size) < 0) {
848             return -1;
849         }
850         PyObject **items = PySequence_Fast_ITEMS(arg);
851         char *s = PyByteArray_AS_STRING(self);
852         for (Py_ssize_t i = 0; i < size; i++) {
853             int value;
854             if (!PyLong_CheckExact(items[i])) {
855                 /* Resize to 0 and go through slowpath */
856                 if (Py_SIZE(self) != 0) {
857                    if (PyByteArray_Resize((PyObject *)self, 0) < 0) {
858                        return -1;
859                    }
860                 }
861                 goto slowpath;
862             }
863             int rc = _getbytevalue(items[i], &value);
864             if (!rc) {
865                 return -1;
866             }
867             s[i] = value;
868         }
869         return 0;
870     }
871 slowpath:
872     /* Get the iterator */
873     it = PyObject_GetIter(arg);
874     if (it == NULL) {
875         if (PyErr_ExceptionMatches(PyExc_TypeError)) {
876             PyErr_Format(PyExc_TypeError,
877                          "cannot convert '%.200s' object to bytearray",
878                          Py_TYPE(arg)->tp_name);
879         }
880         return -1;
881     }
882     iternext = *Py_TYPE(it)->tp_iternext;
883 
884     /* Run the iterator to exhaustion */
885     for (;;) {
886         PyObject *item;
887         int rc, value;
888 
889         /* Get the next item */
890         item = iternext(it);
891         if (item == NULL) {
892             if (PyErr_Occurred()) {
893                 if (!PyErr_ExceptionMatches(PyExc_StopIteration))
894                     goto error;
895                 PyErr_Clear();
896             }
897             break;
898         }
899 
900         /* Interpret it as an int (__index__) */
901         rc = _getbytevalue(item, &value);
902         Py_DECREF(item);
903         if (!rc)
904             goto error;
905 
906         /* Append the byte */
907         if (Py_SIZE(self) + 1 < self->ob_alloc) {
908             Py_SET_SIZE(self, Py_SIZE(self) + 1);
909             PyByteArray_AS_STRING(self)[Py_SIZE(self)] = '\0';
910         }
911         else if (PyByteArray_Resize((PyObject *)self, Py_SIZE(self)+1) < 0)
912             goto error;
913         PyByteArray_AS_STRING(self)[Py_SIZE(self)-1] = value;
914     }
915 
916     /* Clean up and return success */
917     Py_DECREF(it);
918     return 0;
919 
920  error:
921     /* Error handling when it != NULL */
922     Py_DECREF(it);
923     return -1;
924 }
925 
926 /* Mostly copied from string_repr, but without the
927    "smart quote" functionality. */
928 static PyObject *
bytearray_repr(PyByteArrayObject * self)929 bytearray_repr(PyByteArrayObject *self)
930 {
931     const char *className = _PyType_Name(Py_TYPE(self));
932     const char *quote_prefix = "(b";
933     const char *quote_postfix = ")";
934     Py_ssize_t length = Py_SIZE(self);
935     /* 6 == strlen(quote_prefix) + 2 + strlen(quote_postfix) + 1 */
936     Py_ssize_t newsize;
937     PyObject *v;
938     Py_ssize_t i;
939     char *bytes;
940     char c;
941     char *p;
942     int quote;
943     char *test, *start;
944     char *buffer;
945 
946     newsize = strlen(className);
947     if (length > (PY_SSIZE_T_MAX - 6 - newsize) / 4) {
948         PyErr_SetString(PyExc_OverflowError,
949             "bytearray object is too large to make repr");
950         return NULL;
951     }
952 
953     newsize += 6 + length * 4;
954     buffer = PyMem_Malloc(newsize);
955     if (buffer == NULL) {
956         PyErr_NoMemory();
957         return NULL;
958     }
959 
960     /* Figure out which quote to use; single is preferred */
961     quote = '\'';
962     start = PyByteArray_AS_STRING(self);
963     for (test = start; test < start+length; ++test) {
964         if (*test == '"') {
965             quote = '\''; /* back to single */
966             break;
967         }
968         else if (*test == '\'')
969             quote = '"';
970     }
971 
972     p = buffer;
973     while (*className)
974         *p++ = *className++;
975     while (*quote_prefix)
976         *p++ = *quote_prefix++;
977     *p++ = quote;
978 
979     bytes = PyByteArray_AS_STRING(self);
980     for (i = 0; i < length; i++) {
981         /* There's at least enough room for a hex escape
982            and a closing quote. */
983         assert(newsize - (p - buffer) >= 5);
984         c = bytes[i];
985         if (c == '\'' || c == '\\')
986             *p++ = '\\', *p++ = c;
987         else if (c == '\t')
988             *p++ = '\\', *p++ = 't';
989         else if (c == '\n')
990             *p++ = '\\', *p++ = 'n';
991         else if (c == '\r')
992             *p++ = '\\', *p++ = 'r';
993         else if (c == 0)
994             *p++ = '\\', *p++ = 'x', *p++ = '0', *p++ = '0';
995         else if (c < ' ' || c >= 0x7f) {
996             *p++ = '\\';
997             *p++ = 'x';
998             *p++ = Py_hexdigits[(c & 0xf0) >> 4];
999             *p++ = Py_hexdigits[c & 0xf];
1000         }
1001         else
1002             *p++ = c;
1003     }
1004     assert(newsize - (p - buffer) >= 1);
1005     *p++ = quote;
1006     while (*quote_postfix) {
1007        *p++ = *quote_postfix++;
1008     }
1009 
1010     v = PyUnicode_FromStringAndSize(buffer, p - buffer);
1011     PyMem_Free(buffer);
1012     return v;
1013 }
1014 
1015 static PyObject *
bytearray_str(PyObject * op)1016 bytearray_str(PyObject *op)
1017 {
1018     if (_Py_GetConfig()->bytes_warning) {
1019         if (PyErr_WarnEx(PyExc_BytesWarning,
1020                          "str() on a bytearray instance", 1)) {
1021                 return NULL;
1022         }
1023     }
1024     return bytearray_repr((PyByteArrayObject*)op);
1025 }
1026 
1027 static PyObject *
bytearray_richcompare(PyObject * self,PyObject * other,int op)1028 bytearray_richcompare(PyObject *self, PyObject *other, int op)
1029 {
1030     Py_ssize_t self_size, other_size;
1031     Py_buffer self_bytes, other_bytes;
1032     int cmp;
1033 
1034     if (!PyObject_CheckBuffer(self) || !PyObject_CheckBuffer(other)) {
1035         if (PyUnicode_Check(self) || PyUnicode_Check(other)) {
1036             if (_Py_GetConfig()->bytes_warning && (op == Py_EQ || op == Py_NE)) {
1037                 if (PyErr_WarnEx(PyExc_BytesWarning,
1038                                 "Comparison between bytearray and string", 1))
1039                     return NULL;
1040             }
1041         }
1042         Py_RETURN_NOTIMPLEMENTED;
1043     }
1044 
1045     /* Bytearrays can be compared to anything that supports the buffer API. */
1046     if (PyObject_GetBuffer(self, &self_bytes, PyBUF_SIMPLE) != 0) {
1047         PyErr_Clear();
1048         Py_RETURN_NOTIMPLEMENTED;
1049     }
1050     self_size = self_bytes.len;
1051 
1052     if (PyObject_GetBuffer(other, &other_bytes, PyBUF_SIMPLE) != 0) {
1053         PyErr_Clear();
1054         PyBuffer_Release(&self_bytes);
1055         Py_RETURN_NOTIMPLEMENTED;
1056     }
1057     other_size = other_bytes.len;
1058 
1059     if (self_size != other_size && (op == Py_EQ || op == Py_NE)) {
1060         /* Shortcut: if the lengths differ, the objects differ */
1061         PyBuffer_Release(&self_bytes);
1062         PyBuffer_Release(&other_bytes);
1063         return PyBool_FromLong((op == Py_NE));
1064     }
1065     else {
1066         cmp = memcmp(self_bytes.buf, other_bytes.buf,
1067                      Py_MIN(self_size, other_size));
1068         /* In ISO C, memcmp() guarantees to use unsigned bytes! */
1069 
1070         PyBuffer_Release(&self_bytes);
1071         PyBuffer_Release(&other_bytes);
1072 
1073         if (cmp != 0) {
1074             Py_RETURN_RICHCOMPARE(cmp, 0, op);
1075         }
1076 
1077         Py_RETURN_RICHCOMPARE(self_size, other_size, op);
1078     }
1079 
1080 }
1081 
1082 static void
bytearray_dealloc(PyByteArrayObject * self)1083 bytearray_dealloc(PyByteArrayObject *self)
1084 {
1085     if (self->ob_exports > 0) {
1086         PyErr_SetString(PyExc_SystemError,
1087                         "deallocated bytearray object has exported buffers");
1088         PyErr_Print();
1089     }
1090     if (self->ob_bytes != 0) {
1091         PyMem_Free(self->ob_bytes);
1092     }
1093     Py_TYPE(self)->tp_free((PyObject *)self);
1094 }
1095 
1096 
1097 /* -------------------------------------------------------------------- */
1098 /* Methods */
1099 
1100 #define STRINGLIB_IS_UNICODE 0
1101 #define FASTSEARCH fastsearch
1102 #define STRINGLIB(F) stringlib_##F
1103 #define STRINGLIB_CHAR char
1104 #define STRINGLIB_SIZEOF_CHAR 1
1105 #define STRINGLIB_LEN PyByteArray_GET_SIZE
1106 #define STRINGLIB_STR PyByteArray_AS_STRING
1107 #define STRINGLIB_NEW PyByteArray_FromStringAndSize
1108 #define STRINGLIB_ISSPACE Py_ISSPACE
1109 #define STRINGLIB_ISLINEBREAK(x) ((x == '\n') || (x == '\r'))
1110 #define STRINGLIB_CHECK_EXACT PyByteArray_CheckExact
1111 #define STRINGLIB_FAST_MEMCHR memchr
1112 #define STRINGLIB_MUTABLE 1
1113 
1114 #include "stringlib/fastsearch.h"
1115 #include "stringlib/count.h"
1116 #include "stringlib/find.h"
1117 #include "stringlib/join.h"
1118 #include "stringlib/partition.h"
1119 #include "stringlib/split.h"
1120 #include "stringlib/ctype.h"
1121 #include "stringlib/transmogrify.h"
1122 
1123 
1124 /*[clinic input]
1125 @text_signature "($self, sub[, start[, end]], /)"
1126 bytearray.find
1127 
1128     sub: object
1129     start: slice_index(accept={int, NoneType}, c_default='0') = None
1130          Optional start position. Default: start of the bytes.
1131     end: slice_index(accept={int, NoneType}, c_default='PY_SSIZE_T_MAX') = None
1132          Optional stop position. Default: end of the bytes.
1133     /
1134 
1135 Return the lowest index in B where subsection 'sub' is found, such that 'sub' is contained within B[start:end].
1136 
1137 Return -1 on failure.
1138 [clinic start generated code]*/
1139 
1140 static PyObject *
bytearray_find_impl(PyByteArrayObject * self,PyObject * sub,Py_ssize_t start,Py_ssize_t end)1141 bytearray_find_impl(PyByteArrayObject *self, PyObject *sub, Py_ssize_t start,
1142                     Py_ssize_t end)
1143 /*[clinic end generated code: output=413e1cab2ae87da0 input=793dfad803e2952f]*/
1144 {
1145     return _Py_bytes_find(PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self),
1146                           sub, start, end);
1147 }
1148 
1149 /*[clinic input]
1150 bytearray.count = bytearray.find
1151 
1152 Return the number of non-overlapping occurrences of subsection 'sub' in bytes B[start:end].
1153 [clinic start generated code]*/
1154 
1155 static PyObject *
bytearray_count_impl(PyByteArrayObject * self,PyObject * sub,Py_ssize_t start,Py_ssize_t end)1156 bytearray_count_impl(PyByteArrayObject *self, PyObject *sub,
1157                      Py_ssize_t start, Py_ssize_t end)
1158 /*[clinic end generated code: output=a21ee2692e4f1233 input=4deb529db38deda8]*/
1159 {
1160     return _Py_bytes_count(PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self),
1161                            sub, start, end);
1162 }
1163 
1164 /*[clinic input]
1165 bytearray.clear
1166 
1167 Remove all items from the bytearray.
1168 [clinic start generated code]*/
1169 
1170 static PyObject *
bytearray_clear_impl(PyByteArrayObject * self)1171 bytearray_clear_impl(PyByteArrayObject *self)
1172 /*[clinic end generated code: output=85c2fe6aede0956c input=ed6edae9de447ac4]*/
1173 {
1174     if (PyByteArray_Resize((PyObject *)self, 0) < 0)
1175         return NULL;
1176     Py_RETURN_NONE;
1177 }
1178 
1179 /*[clinic input]
1180 bytearray.copy
1181 
1182 Return a copy of B.
1183 [clinic start generated code]*/
1184 
1185 static PyObject *
bytearray_copy_impl(PyByteArrayObject * self)1186 bytearray_copy_impl(PyByteArrayObject *self)
1187 /*[clinic end generated code: output=68cfbcfed484c132 input=6597b0c01bccaa9e]*/
1188 {
1189     return PyByteArray_FromStringAndSize(PyByteArray_AS_STRING((PyObject *)self),
1190                                          PyByteArray_GET_SIZE(self));
1191 }
1192 
1193 /*[clinic input]
1194 bytearray.index = bytearray.find
1195 
1196 Return the lowest index in B where subsection 'sub' is found, such that 'sub' is contained within B[start:end].
1197 
1198 Raise ValueError if the subsection is not found.
1199 [clinic start generated code]*/
1200 
1201 static PyObject *
bytearray_index_impl(PyByteArrayObject * self,PyObject * sub,Py_ssize_t start,Py_ssize_t end)1202 bytearray_index_impl(PyByteArrayObject *self, PyObject *sub,
1203                      Py_ssize_t start, Py_ssize_t end)
1204 /*[clinic end generated code: output=067a1e78efc672a7 input=8cbaf6836dbd2a9a]*/
1205 {
1206     return _Py_bytes_index(PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self),
1207                            sub, start, end);
1208 }
1209 
1210 /*[clinic input]
1211 bytearray.rfind = bytearray.find
1212 
1213 Return the highest index in B where subsection 'sub' is found, such that 'sub' is contained within B[start:end].
1214 
1215 Return -1 on failure.
1216 [clinic start generated code]*/
1217 
1218 static PyObject *
bytearray_rfind_impl(PyByteArrayObject * self,PyObject * sub,Py_ssize_t start,Py_ssize_t end)1219 bytearray_rfind_impl(PyByteArrayObject *self, PyObject *sub,
1220                      Py_ssize_t start, Py_ssize_t end)
1221 /*[clinic end generated code: output=51bf886f932b283c input=eaa107468a158423]*/
1222 {
1223     return _Py_bytes_rfind(PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self),
1224                            sub, start, end);
1225 }
1226 
1227 /*[clinic input]
1228 bytearray.rindex = bytearray.find
1229 
1230 Return the highest index in B where subsection 'sub' is found, such that 'sub' is contained within B[start:end].
1231 
1232 Raise ValueError if the subsection is not found.
1233 [clinic start generated code]*/
1234 
1235 static PyObject *
bytearray_rindex_impl(PyByteArrayObject * self,PyObject * sub,Py_ssize_t start,Py_ssize_t end)1236 bytearray_rindex_impl(PyByteArrayObject *self, PyObject *sub,
1237                       Py_ssize_t start, Py_ssize_t end)
1238 /*[clinic end generated code: output=38e1cf66bafb08b9 input=81cf49d0af4d5bd0]*/
1239 {
1240     return _Py_bytes_rindex(PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self),
1241                             sub, start, end);
1242 }
1243 
1244 static int
bytearray_contains(PyObject * self,PyObject * arg)1245 bytearray_contains(PyObject *self, PyObject *arg)
1246 {
1247     return _Py_bytes_contains(PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self), arg);
1248 }
1249 
1250 /*[clinic input]
1251 @text_signature "($self, prefix[, start[, end]], /)"
1252 bytearray.startswith
1253 
1254     prefix as subobj: object
1255         A bytes or a tuple of bytes to try.
1256     start: slice_index(accept={int, NoneType}, c_default='0') = None
1257         Optional start position. Default: start of the bytearray.
1258     end: slice_index(accept={int, NoneType}, c_default='PY_SSIZE_T_MAX') = None
1259         Optional stop position. Default: end of the bytearray.
1260     /
1261 
1262 Return True if the bytearray starts with the specified prefix, False otherwise.
1263 [clinic start generated code]*/
1264 
1265 static PyObject *
bytearray_startswith_impl(PyByteArrayObject * self,PyObject * subobj,Py_ssize_t start,Py_ssize_t end)1266 bytearray_startswith_impl(PyByteArrayObject *self, PyObject *subobj,
1267                           Py_ssize_t start, Py_ssize_t end)
1268 /*[clinic end generated code: output=a3d9b6d44d3662a6 input=76385e0b376b45c1]*/
1269 {
1270     return _Py_bytes_startswith(PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self),
1271                                 subobj, start, end);
1272 }
1273 
1274 /*[clinic input]
1275 @text_signature "($self, suffix[, start[, end]], /)"
1276 bytearray.endswith
1277 
1278     suffix as subobj: object
1279         A bytes or a tuple of bytes to try.
1280     start: slice_index(accept={int, NoneType}, c_default='0') = None
1281          Optional start position. Default: start of the bytearray.
1282     end: slice_index(accept={int, NoneType}, c_default='PY_SSIZE_T_MAX') = None
1283          Optional stop position. Default: end of the bytearray.
1284     /
1285 
1286 Return True if the bytearray ends with the specified suffix, False otherwise.
1287 [clinic start generated code]*/
1288 
1289 static PyObject *
bytearray_endswith_impl(PyByteArrayObject * self,PyObject * subobj,Py_ssize_t start,Py_ssize_t end)1290 bytearray_endswith_impl(PyByteArrayObject *self, PyObject *subobj,
1291                         Py_ssize_t start, Py_ssize_t end)
1292 /*[clinic end generated code: output=e75ea8c227954caa input=9b8baa879aa3d74b]*/
1293 {
1294     return _Py_bytes_endswith(PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self),
1295                               subobj, start, end);
1296 }
1297 
1298 /*[clinic input]
1299 bytearray.removeprefix as bytearray_removeprefix
1300 
1301     prefix: Py_buffer
1302     /
1303 
1304 Return a bytearray with the given prefix string removed if present.
1305 
1306 If the bytearray starts with the prefix string, return
1307 bytearray[len(prefix):].  Otherwise, return a copy of the original
1308 bytearray.
1309 [clinic start generated code]*/
1310 
1311 static PyObject *
bytearray_removeprefix_impl(PyByteArrayObject * self,Py_buffer * prefix)1312 bytearray_removeprefix_impl(PyByteArrayObject *self, Py_buffer *prefix)
1313 /*[clinic end generated code: output=6cabc585e7f502e0 input=968aada38aedd262]*/
1314 {
1315     const char *self_start = PyByteArray_AS_STRING(self);
1316     Py_ssize_t self_len = PyByteArray_GET_SIZE(self);
1317     const char *prefix_start = prefix->buf;
1318     Py_ssize_t prefix_len = prefix->len;
1319 
1320     if (self_len >= prefix_len
1321         && memcmp(self_start, prefix_start, prefix_len) == 0)
1322     {
1323         return PyByteArray_FromStringAndSize(self_start + prefix_len,
1324                                              self_len - prefix_len);
1325     }
1326 
1327     return PyByteArray_FromStringAndSize(self_start, self_len);
1328 }
1329 
1330 /*[clinic input]
1331 bytearray.removesuffix as bytearray_removesuffix
1332 
1333     suffix: Py_buffer
1334     /
1335 
1336 Return a bytearray with the given suffix string removed if present.
1337 
1338 If the bytearray ends with the suffix string and that suffix is not
1339 empty, return bytearray[:-len(suffix)].  Otherwise, return a copy of
1340 the original bytearray.
1341 [clinic start generated code]*/
1342 
1343 static PyObject *
bytearray_removesuffix_impl(PyByteArrayObject * self,Py_buffer * suffix)1344 bytearray_removesuffix_impl(PyByteArrayObject *self, Py_buffer *suffix)
1345 /*[clinic end generated code: output=2bc8cfb79de793d3 input=c1827e810b2f6b99]*/
1346 {
1347     const char *self_start = PyByteArray_AS_STRING(self);
1348     Py_ssize_t self_len = PyByteArray_GET_SIZE(self);
1349     const char *suffix_start = suffix->buf;
1350     Py_ssize_t suffix_len = suffix->len;
1351 
1352     if (self_len >= suffix_len
1353         && memcmp(self_start + self_len - suffix_len,
1354                   suffix_start, suffix_len) == 0)
1355     {
1356         return PyByteArray_FromStringAndSize(self_start,
1357                                              self_len - suffix_len);
1358     }
1359 
1360     return PyByteArray_FromStringAndSize(self_start, self_len);
1361 }
1362 
1363 
1364 /*[clinic input]
1365 bytearray.translate
1366 
1367     table: object
1368         Translation table, which must be a bytes object of length 256.
1369     /
1370     delete as deletechars: object(c_default="NULL") = b''
1371 
1372 Return a copy with each character mapped by the given translation table.
1373 
1374 All characters occurring in the optional argument delete are removed.
1375 The remaining characters are mapped through the given translation table.
1376 [clinic start generated code]*/
1377 
1378 static PyObject *
bytearray_translate_impl(PyByteArrayObject * self,PyObject * table,PyObject * deletechars)1379 bytearray_translate_impl(PyByteArrayObject *self, PyObject *table,
1380                          PyObject *deletechars)
1381 /*[clinic end generated code: output=b6a8f01c2a74e446 input=cfff956d4d127a9b]*/
1382 {
1383     char *input, *output;
1384     const char *table_chars;
1385     Py_ssize_t i, c;
1386     PyObject *input_obj = (PyObject*)self;
1387     const char *output_start;
1388     Py_ssize_t inlen;
1389     PyObject *result = NULL;
1390     int trans_table[256];
1391     Py_buffer vtable, vdel;
1392 
1393     if (table == Py_None) {
1394         table_chars = NULL;
1395         table = NULL;
1396     } else if (PyObject_GetBuffer(table, &vtable, PyBUF_SIMPLE) != 0) {
1397         return NULL;
1398     } else {
1399         if (vtable.len != 256) {
1400             PyErr_SetString(PyExc_ValueError,
1401                             "translation table must be 256 characters long");
1402             PyBuffer_Release(&vtable);
1403             return NULL;
1404         }
1405         table_chars = (const char*)vtable.buf;
1406     }
1407 
1408     if (deletechars != NULL) {
1409         if (PyObject_GetBuffer(deletechars, &vdel, PyBUF_SIMPLE) != 0) {
1410             if (table != NULL)
1411                 PyBuffer_Release(&vtable);
1412             return NULL;
1413         }
1414     }
1415     else {
1416         vdel.buf = NULL;
1417         vdel.len = 0;
1418     }
1419 
1420     inlen = PyByteArray_GET_SIZE(input_obj);
1421     result = PyByteArray_FromStringAndSize((char *)NULL, inlen);
1422     if (result == NULL)
1423         goto done;
1424     output_start = output = PyByteArray_AS_STRING(result);
1425     input = PyByteArray_AS_STRING(input_obj);
1426 
1427     if (vdel.len == 0 && table_chars != NULL) {
1428         /* If no deletions are required, use faster code */
1429         for (i = inlen; --i >= 0; ) {
1430             c = Py_CHARMASK(*input++);
1431             *output++ = table_chars[c];
1432         }
1433         goto done;
1434     }
1435 
1436     if (table_chars == NULL) {
1437         for (i = 0; i < 256; i++)
1438             trans_table[i] = Py_CHARMASK(i);
1439     } else {
1440         for (i = 0; i < 256; i++)
1441             trans_table[i] = Py_CHARMASK(table_chars[i]);
1442     }
1443 
1444     for (i = 0; i < vdel.len; i++)
1445         trans_table[(int) Py_CHARMASK( ((unsigned char*)vdel.buf)[i] )] = -1;
1446 
1447     for (i = inlen; --i >= 0; ) {
1448         c = Py_CHARMASK(*input++);
1449         if (trans_table[c] != -1)
1450             *output++ = (char)trans_table[c];
1451     }
1452     /* Fix the size of the resulting bytearray */
1453     if (inlen > 0)
1454         if (PyByteArray_Resize(result, output - output_start) < 0) {
1455             Py_CLEAR(result);
1456             goto done;
1457         }
1458 
1459 done:
1460     if (table != NULL)
1461         PyBuffer_Release(&vtable);
1462     if (deletechars != NULL)
1463         PyBuffer_Release(&vdel);
1464     return result;
1465 }
1466 
1467 
1468 /*[clinic input]
1469 
1470 @staticmethod
1471 bytearray.maketrans
1472 
1473     frm: Py_buffer
1474     to: Py_buffer
1475     /
1476 
1477 Return a translation table usable for the bytes or bytearray translate method.
1478 
1479 The returned table will be one where each byte in frm is mapped to the byte at
1480 the same position in to.
1481 
1482 The bytes objects frm and to must be of the same length.
1483 [clinic start generated code]*/
1484 
1485 static PyObject *
bytearray_maketrans_impl(Py_buffer * frm,Py_buffer * to)1486 bytearray_maketrans_impl(Py_buffer *frm, Py_buffer *to)
1487 /*[clinic end generated code: output=1df267d99f56b15e input=b10de38c85950a63]*/
1488 {
1489     return _Py_bytes_maketrans(frm, to);
1490 }
1491 
1492 
1493 /*[clinic input]
1494 bytearray.replace
1495 
1496     old: Py_buffer
1497     new: Py_buffer
1498     count: Py_ssize_t = -1
1499         Maximum number of occurrences to replace.
1500         -1 (the default value) means replace all occurrences.
1501     /
1502 
1503 Return a copy with all occurrences of substring old replaced by new.
1504 
1505 If the optional argument count is given, only the first count occurrences are
1506 replaced.
1507 [clinic start generated code]*/
1508 
1509 static PyObject *
bytearray_replace_impl(PyByteArrayObject * self,Py_buffer * old,Py_buffer * new,Py_ssize_t count)1510 bytearray_replace_impl(PyByteArrayObject *self, Py_buffer *old,
1511                        Py_buffer *new, Py_ssize_t count)
1512 /*[clinic end generated code: output=d39884c4dc59412a input=aa379d988637c7fb]*/
1513 {
1514     return stringlib_replace((PyObject *)self,
1515                              (const char *)old->buf, old->len,
1516                              (const char *)new->buf, new->len, count);
1517 }
1518 
1519 /*[clinic input]
1520 bytearray.split
1521 
1522     sep: object = None
1523         The delimiter according which to split the bytearray.
1524         None (the default value) means split on ASCII whitespace characters
1525         (space, tab, return, newline, formfeed, vertical tab).
1526     maxsplit: Py_ssize_t = -1
1527         Maximum number of splits to do.
1528         -1 (the default value) means no limit.
1529 
1530 Return a list of the sections in the bytearray, using sep as the delimiter.
1531 [clinic start generated code]*/
1532 
1533 static PyObject *
bytearray_split_impl(PyByteArrayObject * self,PyObject * sep,Py_ssize_t maxsplit)1534 bytearray_split_impl(PyByteArrayObject *self, PyObject *sep,
1535                      Py_ssize_t maxsplit)
1536 /*[clinic end generated code: output=833e2cf385d9a04d input=24f82669f41bf523]*/
1537 {
1538     Py_ssize_t len = PyByteArray_GET_SIZE(self), n;
1539     const char *s = PyByteArray_AS_STRING(self), *sub;
1540     PyObject *list;
1541     Py_buffer vsub;
1542 
1543     if (maxsplit < 0)
1544         maxsplit = PY_SSIZE_T_MAX;
1545 
1546     if (sep == Py_None)
1547         return stringlib_split_whitespace((PyObject*) self, s, len, maxsplit);
1548 
1549     if (PyObject_GetBuffer(sep, &vsub, PyBUF_SIMPLE) != 0)
1550         return NULL;
1551     sub = vsub.buf;
1552     n = vsub.len;
1553 
1554     list = stringlib_split(
1555         (PyObject*) self, s, len, sub, n, maxsplit
1556         );
1557     PyBuffer_Release(&vsub);
1558     return list;
1559 }
1560 
1561 /*[clinic input]
1562 bytearray.partition
1563 
1564     sep: object
1565     /
1566 
1567 Partition the bytearray into three parts using the given separator.
1568 
1569 This will search for the separator sep in the bytearray. If the separator is
1570 found, returns a 3-tuple containing the part before the separator, the
1571 separator itself, and the part after it as new bytearray objects.
1572 
1573 If the separator is not found, returns a 3-tuple containing the copy of the
1574 original bytearray object and two empty bytearray objects.
1575 [clinic start generated code]*/
1576 
1577 static PyObject *
bytearray_partition(PyByteArrayObject * self,PyObject * sep)1578 bytearray_partition(PyByteArrayObject *self, PyObject *sep)
1579 /*[clinic end generated code: output=45d2525ddd35f957 input=8f644749ee4fc83a]*/
1580 {
1581     PyObject *bytesep, *result;
1582 
1583     bytesep = _PyByteArray_FromBufferObject(sep);
1584     if (! bytesep)
1585         return NULL;
1586 
1587     result = stringlib_partition(
1588             (PyObject*) self,
1589             PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self),
1590             bytesep,
1591             PyByteArray_AS_STRING(bytesep), PyByteArray_GET_SIZE(bytesep)
1592             );
1593 
1594     Py_DECREF(bytesep);
1595     return result;
1596 }
1597 
1598 /*[clinic input]
1599 bytearray.rpartition
1600 
1601     sep: object
1602     /
1603 
1604 Partition the bytearray into three parts using the given separator.
1605 
1606 This will search for the separator sep in the bytearray, starting at the end.
1607 If the separator is found, returns a 3-tuple containing the part before the
1608 separator, the separator itself, and the part after it as new bytearray
1609 objects.
1610 
1611 If the separator is not found, returns a 3-tuple containing two empty bytearray
1612 objects and the copy of the original bytearray object.
1613 [clinic start generated code]*/
1614 
1615 static PyObject *
bytearray_rpartition(PyByteArrayObject * self,PyObject * sep)1616 bytearray_rpartition(PyByteArrayObject *self, PyObject *sep)
1617 /*[clinic end generated code: output=440de3c9426115e8 input=7e3df3e6cb8fa0ac]*/
1618 {
1619     PyObject *bytesep, *result;
1620 
1621     bytesep = _PyByteArray_FromBufferObject(sep);
1622     if (! bytesep)
1623         return NULL;
1624 
1625     result = stringlib_rpartition(
1626             (PyObject*) self,
1627             PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self),
1628             bytesep,
1629             PyByteArray_AS_STRING(bytesep), PyByteArray_GET_SIZE(bytesep)
1630             );
1631 
1632     Py_DECREF(bytesep);
1633     return result;
1634 }
1635 
1636 /*[clinic input]
1637 bytearray.rsplit = bytearray.split
1638 
1639 Return a list of the sections in the bytearray, using sep as the delimiter.
1640 
1641 Splitting is done starting at the end of the bytearray and working to the front.
1642 [clinic start generated code]*/
1643 
1644 static PyObject *
bytearray_rsplit_impl(PyByteArrayObject * self,PyObject * sep,Py_ssize_t maxsplit)1645 bytearray_rsplit_impl(PyByteArrayObject *self, PyObject *sep,
1646                       Py_ssize_t maxsplit)
1647 /*[clinic end generated code: output=a55e0b5a03cb6190 input=a68286e4dd692ffe]*/
1648 {
1649     Py_ssize_t len = PyByteArray_GET_SIZE(self), n;
1650     const char *s = PyByteArray_AS_STRING(self), *sub;
1651     PyObject *list;
1652     Py_buffer vsub;
1653 
1654     if (maxsplit < 0)
1655         maxsplit = PY_SSIZE_T_MAX;
1656 
1657     if (sep == Py_None)
1658         return stringlib_rsplit_whitespace((PyObject*) self, s, len, maxsplit);
1659 
1660     if (PyObject_GetBuffer(sep, &vsub, PyBUF_SIMPLE) != 0)
1661         return NULL;
1662     sub = vsub.buf;
1663     n = vsub.len;
1664 
1665     list = stringlib_rsplit(
1666         (PyObject*) self, s, len, sub, n, maxsplit
1667         );
1668     PyBuffer_Release(&vsub);
1669     return list;
1670 }
1671 
1672 /*[clinic input]
1673 bytearray.reverse
1674 
1675 Reverse the order of the values in B in place.
1676 [clinic start generated code]*/
1677 
1678 static PyObject *
bytearray_reverse_impl(PyByteArrayObject * self)1679 bytearray_reverse_impl(PyByteArrayObject *self)
1680 /*[clinic end generated code: output=9f7616f29ab309d3 input=543356319fc78557]*/
1681 {
1682     char swap, *head, *tail;
1683     Py_ssize_t i, j, n = Py_SIZE(self);
1684 
1685     j = n / 2;
1686     head = PyByteArray_AS_STRING(self);
1687     tail = head + n - 1;
1688     for (i = 0; i < j; i++) {
1689         swap = *head;
1690         *head++ = *tail;
1691         *tail-- = swap;
1692     }
1693 
1694     Py_RETURN_NONE;
1695 }
1696 
1697 
1698 /*[python input]
1699 class bytesvalue_converter(CConverter):
1700     type = 'int'
1701     converter = '_getbytevalue'
1702 [python start generated code]*/
1703 /*[python end generated code: output=da39a3ee5e6b4b0d input=29c2e7c26c212812]*/
1704 
1705 
1706 /*[clinic input]
1707 bytearray.insert
1708 
1709     index: Py_ssize_t
1710         The index where the value is to be inserted.
1711     item: bytesvalue
1712         The item to be inserted.
1713     /
1714 
1715 Insert a single item into the bytearray before the given index.
1716 [clinic start generated code]*/
1717 
1718 static PyObject *
bytearray_insert_impl(PyByteArrayObject * self,Py_ssize_t index,int item)1719 bytearray_insert_impl(PyByteArrayObject *self, Py_ssize_t index, int item)
1720 /*[clinic end generated code: output=76c775a70e7b07b7 input=b2b5d07e9de6c070]*/
1721 {
1722     Py_ssize_t n = Py_SIZE(self);
1723     char *buf;
1724 
1725     if (n == PY_SSIZE_T_MAX) {
1726         PyErr_SetString(PyExc_OverflowError,
1727                         "cannot add more objects to bytearray");
1728         return NULL;
1729     }
1730     if (PyByteArray_Resize((PyObject *)self, n + 1) < 0)
1731         return NULL;
1732     buf = PyByteArray_AS_STRING(self);
1733 
1734     if (index < 0) {
1735         index += n;
1736         if (index < 0)
1737             index = 0;
1738     }
1739     if (index > n)
1740         index = n;
1741     memmove(buf + index + 1, buf + index, n - index);
1742     buf[index] = item;
1743 
1744     Py_RETURN_NONE;
1745 }
1746 
1747 /*[clinic input]
1748 bytearray.append
1749 
1750     item: bytesvalue
1751         The item to be appended.
1752     /
1753 
1754 Append a single item to the end of the bytearray.
1755 [clinic start generated code]*/
1756 
1757 static PyObject *
bytearray_append_impl(PyByteArrayObject * self,int item)1758 bytearray_append_impl(PyByteArrayObject *self, int item)
1759 /*[clinic end generated code: output=a154e19ed1886cb6 input=20d6bec3d1340593]*/
1760 {
1761     Py_ssize_t n = Py_SIZE(self);
1762 
1763     if (n == PY_SSIZE_T_MAX) {
1764         PyErr_SetString(PyExc_OverflowError,
1765                         "cannot add more objects to bytearray");
1766         return NULL;
1767     }
1768     if (PyByteArray_Resize((PyObject *)self, n + 1) < 0)
1769         return NULL;
1770 
1771     PyByteArray_AS_STRING(self)[n] = item;
1772 
1773     Py_RETURN_NONE;
1774 }
1775 
1776 /*[clinic input]
1777 bytearray.extend
1778 
1779     iterable_of_ints: object
1780         The iterable of items to append.
1781     /
1782 
1783 Append all the items from the iterator or sequence to the end of the bytearray.
1784 [clinic start generated code]*/
1785 
1786 static PyObject *
bytearray_extend(PyByteArrayObject * self,PyObject * iterable_of_ints)1787 bytearray_extend(PyByteArrayObject *self, PyObject *iterable_of_ints)
1788 /*[clinic end generated code: output=98155dbe249170b1 input=c617b3a93249ba28]*/
1789 {
1790     PyObject *it, *item, *bytearray_obj;
1791     Py_ssize_t buf_size = 0, len = 0;
1792     int value;
1793     char *buf;
1794 
1795     /* bytearray_setslice code only accepts something supporting PEP 3118. */
1796     if (PyObject_CheckBuffer(iterable_of_ints)) {
1797         if (bytearray_setslice(self, Py_SIZE(self), Py_SIZE(self), iterable_of_ints) == -1)
1798             return NULL;
1799 
1800         Py_RETURN_NONE;
1801     }
1802 
1803     it = PyObject_GetIter(iterable_of_ints);
1804     if (it == NULL) {
1805         if (PyErr_ExceptionMatches(PyExc_TypeError)) {
1806             PyErr_Format(PyExc_TypeError,
1807                          "can't extend bytearray with %.100s",
1808                          Py_TYPE(iterable_of_ints)->tp_name);
1809         }
1810         return NULL;
1811     }
1812 
1813     /* Try to determine the length of the argument. 32 is arbitrary. */
1814     buf_size = PyObject_LengthHint(iterable_of_ints, 32);
1815     if (buf_size == -1) {
1816         Py_DECREF(it);
1817         return NULL;
1818     }
1819 
1820     bytearray_obj = PyByteArray_FromStringAndSize(NULL, buf_size);
1821     if (bytearray_obj == NULL) {
1822         Py_DECREF(it);
1823         return NULL;
1824     }
1825     buf = PyByteArray_AS_STRING(bytearray_obj);
1826 
1827     while ((item = PyIter_Next(it)) != NULL) {
1828         if (! _getbytevalue(item, &value)) {
1829             if (PyErr_ExceptionMatches(PyExc_TypeError) && PyUnicode_Check(iterable_of_ints)) {
1830                 PyErr_Format(PyExc_TypeError,
1831                              "expected iterable of integers; got: 'str'");
1832             }
1833             Py_DECREF(item);
1834             Py_DECREF(it);
1835             Py_DECREF(bytearray_obj);
1836             return NULL;
1837         }
1838         buf[len++] = value;
1839         Py_DECREF(item);
1840 
1841         if (len >= buf_size) {
1842             Py_ssize_t addition;
1843             if (len == PY_SSIZE_T_MAX) {
1844                 Py_DECREF(it);
1845                 Py_DECREF(bytearray_obj);
1846                 return PyErr_NoMemory();
1847             }
1848             addition = len >> 1;
1849             if (addition > PY_SSIZE_T_MAX - len - 1)
1850                 buf_size = PY_SSIZE_T_MAX;
1851             else
1852                 buf_size = len + addition + 1;
1853             if (PyByteArray_Resize((PyObject *)bytearray_obj, buf_size) < 0) {
1854                 Py_DECREF(it);
1855                 Py_DECREF(bytearray_obj);
1856                 return NULL;
1857             }
1858             /* Recompute the `buf' pointer, since the resizing operation may
1859                have invalidated it. */
1860             buf = PyByteArray_AS_STRING(bytearray_obj);
1861         }
1862     }
1863     Py_DECREF(it);
1864 
1865     if (PyErr_Occurred()) {
1866         Py_DECREF(bytearray_obj);
1867         return NULL;
1868     }
1869 
1870     /* Resize down to exact size. */
1871     if (PyByteArray_Resize((PyObject *)bytearray_obj, len) < 0) {
1872         Py_DECREF(bytearray_obj);
1873         return NULL;
1874     }
1875 
1876     if (bytearray_setslice(self, Py_SIZE(self), Py_SIZE(self), bytearray_obj) == -1) {
1877         Py_DECREF(bytearray_obj);
1878         return NULL;
1879     }
1880     Py_DECREF(bytearray_obj);
1881 
1882     assert(!PyErr_Occurred());
1883     Py_RETURN_NONE;
1884 }
1885 
1886 /*[clinic input]
1887 bytearray.pop
1888 
1889     index: Py_ssize_t = -1
1890         The index from where to remove the item.
1891         -1 (the default value) means remove the last item.
1892     /
1893 
1894 Remove and return a single item from B.
1895 
1896 If no index argument is given, will pop the last item.
1897 [clinic start generated code]*/
1898 
1899 static PyObject *
bytearray_pop_impl(PyByteArrayObject * self,Py_ssize_t index)1900 bytearray_pop_impl(PyByteArrayObject *self, Py_ssize_t index)
1901 /*[clinic end generated code: output=e0ccd401f8021da8 input=3591df2d06c0d237]*/
1902 {
1903     int value;
1904     Py_ssize_t n = Py_SIZE(self);
1905     char *buf;
1906 
1907     if (n == 0) {
1908         PyErr_SetString(PyExc_IndexError,
1909                         "pop from empty bytearray");
1910         return NULL;
1911     }
1912     if (index < 0)
1913         index += Py_SIZE(self);
1914     if (index < 0 || index >= Py_SIZE(self)) {
1915         PyErr_SetString(PyExc_IndexError, "pop index out of range");
1916         return NULL;
1917     }
1918     if (!_canresize(self))
1919         return NULL;
1920 
1921     buf = PyByteArray_AS_STRING(self);
1922     value = buf[index];
1923     memmove(buf + index, buf + index + 1, n - index);
1924     if (PyByteArray_Resize((PyObject *)self, n - 1) < 0)
1925         return NULL;
1926 
1927     return _PyLong_FromUnsignedChar((unsigned char)value);
1928 }
1929 
1930 /*[clinic input]
1931 bytearray.remove
1932 
1933     value: bytesvalue
1934         The value to remove.
1935     /
1936 
1937 Remove the first occurrence of a value in the bytearray.
1938 [clinic start generated code]*/
1939 
1940 static PyObject *
bytearray_remove_impl(PyByteArrayObject * self,int value)1941 bytearray_remove_impl(PyByteArrayObject *self, int value)
1942 /*[clinic end generated code: output=d659e37866709c13 input=121831240cd51ddf]*/
1943 {
1944     Py_ssize_t where, n = Py_SIZE(self);
1945     char *buf = PyByteArray_AS_STRING(self);
1946 
1947     where = stringlib_find_char(buf, n, value);
1948     if (where < 0) {
1949         PyErr_SetString(PyExc_ValueError, "value not found in bytearray");
1950         return NULL;
1951     }
1952     if (!_canresize(self))
1953         return NULL;
1954 
1955     memmove(buf + where, buf + where + 1, n - where);
1956     if (PyByteArray_Resize((PyObject *)self, n - 1) < 0)
1957         return NULL;
1958 
1959     Py_RETURN_NONE;
1960 }
1961 
1962 #define LEFTSTRIP 0
1963 #define RIGHTSTRIP 1
1964 #define BOTHSTRIP 2
1965 
1966 static PyObject*
bytearray_strip_impl_helper(PyByteArrayObject * self,PyObject * bytes,int striptype)1967 bytearray_strip_impl_helper(PyByteArrayObject* self, PyObject* bytes, int striptype)
1968 {
1969     Py_ssize_t mysize, byteslen;
1970     const char* myptr;
1971     const char* bytesptr;
1972     Py_buffer vbytes;
1973 
1974     if (bytes == Py_None) {
1975         bytesptr = "\t\n\r\f\v ";
1976         byteslen = 6;
1977     }
1978     else {
1979         if (PyObject_GetBuffer(bytes, &vbytes, PyBUF_SIMPLE) != 0)
1980             return NULL;
1981         bytesptr = (const char*)vbytes.buf;
1982         byteslen = vbytes.len;
1983     }
1984     myptr = PyByteArray_AS_STRING(self);
1985     mysize = Py_SIZE(self);
1986 
1987     Py_ssize_t left = 0;
1988     if (striptype != RIGHTSTRIP) {
1989         while (left < mysize && memchr(bytesptr, (unsigned char)myptr[left], byteslen))
1990             left++;
1991     }
1992     Py_ssize_t right = mysize;
1993     if (striptype != LEFTSTRIP) {
1994         do {
1995             right--;
1996         } while (right >= left && memchr(bytesptr, (unsigned char)myptr[right], byteslen));
1997         right++;
1998     }
1999     if (bytes != Py_None)
2000         PyBuffer_Release(&vbytes);
2001     return PyByteArray_FromStringAndSize(myptr + left, right - left);
2002 }
2003 
2004 /*[clinic input]
2005 bytearray.strip
2006 
2007     bytes: object = None
2008     /
2009 
2010 Strip leading and trailing bytes contained in the argument.
2011 
2012 If the argument is omitted or None, strip leading and trailing ASCII whitespace.
2013 [clinic start generated code]*/
2014 
2015 static PyObject *
bytearray_strip_impl(PyByteArrayObject * self,PyObject * bytes)2016 bytearray_strip_impl(PyByteArrayObject *self, PyObject *bytes)
2017 /*[clinic end generated code: output=760412661a34ad5a input=ef7bb59b09c21d62]*/
2018 {
2019     return bytearray_strip_impl_helper(self, bytes, BOTHSTRIP);
2020 }
2021 
2022 /*[clinic input]
2023 bytearray.lstrip
2024 
2025     bytes: object = None
2026     /
2027 
2028 Strip leading bytes contained in the argument.
2029 
2030 If the argument is omitted or None, strip leading ASCII whitespace.
2031 [clinic start generated code]*/
2032 
2033 static PyObject *
bytearray_lstrip_impl(PyByteArrayObject * self,PyObject * bytes)2034 bytearray_lstrip_impl(PyByteArrayObject *self, PyObject *bytes)
2035 /*[clinic end generated code: output=d005c9d0ab909e66 input=80843f975dd7c480]*/
2036 {
2037     return bytearray_strip_impl_helper(self, bytes, LEFTSTRIP);
2038 }
2039 
2040 /*[clinic input]
2041 bytearray.rstrip
2042 
2043     bytes: object = None
2044     /
2045 
2046 Strip trailing bytes contained in the argument.
2047 
2048 If the argument is omitted or None, strip trailing ASCII whitespace.
2049 [clinic start generated code]*/
2050 
2051 static PyObject *
bytearray_rstrip_impl(PyByteArrayObject * self,PyObject * bytes)2052 bytearray_rstrip_impl(PyByteArrayObject *self, PyObject *bytes)
2053 /*[clinic end generated code: output=030e2fbd2f7276bd input=e728b994954cfd91]*/
2054 {
2055     return bytearray_strip_impl_helper(self, bytes, RIGHTSTRIP);
2056 }
2057 
2058 /*[clinic input]
2059 bytearray.decode
2060 
2061     encoding: str(c_default="NULL") = 'utf-8'
2062         The encoding with which to decode the bytearray.
2063     errors: str(c_default="NULL") = 'strict'
2064         The error handling scheme to use for the handling of decoding errors.
2065         The default is 'strict' meaning that decoding errors raise a
2066         UnicodeDecodeError. Other possible values are 'ignore' and 'replace'
2067         as well as any other name registered with codecs.register_error that
2068         can handle UnicodeDecodeErrors.
2069 
2070 Decode the bytearray using the codec registered for encoding.
2071 [clinic start generated code]*/
2072 
2073 static PyObject *
bytearray_decode_impl(PyByteArrayObject * self,const char * encoding,const char * errors)2074 bytearray_decode_impl(PyByteArrayObject *self, const char *encoding,
2075                       const char *errors)
2076 /*[clinic end generated code: output=f57d43f4a00b42c5 input=f28d8f903020257b]*/
2077 {
2078     if (encoding == NULL)
2079         encoding = PyUnicode_GetDefaultEncoding();
2080     return PyUnicode_FromEncodedObject((PyObject*)self, encoding, errors);
2081 }
2082 
2083 PyDoc_STRVAR(alloc_doc,
2084 "B.__alloc__() -> int\n\
2085 \n\
2086 Return the number of bytes actually allocated.");
2087 
2088 static PyObject *
bytearray_alloc(PyByteArrayObject * self,PyObject * Py_UNUSED (ignored))2089 bytearray_alloc(PyByteArrayObject *self, PyObject *Py_UNUSED(ignored))
2090 {
2091     return PyLong_FromSsize_t(self->ob_alloc);
2092 }
2093 
2094 /*[clinic input]
2095 bytearray.join
2096 
2097     iterable_of_bytes: object
2098     /
2099 
2100 Concatenate any number of bytes/bytearray objects.
2101 
2102 The bytearray whose method is called is inserted in between each pair.
2103 
2104 The result is returned as a new bytearray object.
2105 [clinic start generated code]*/
2106 
2107 static PyObject *
bytearray_join(PyByteArrayObject * self,PyObject * iterable_of_bytes)2108 bytearray_join(PyByteArrayObject *self, PyObject *iterable_of_bytes)
2109 /*[clinic end generated code: output=a8516370bf68ae08 input=aba6b1f9b30fcb8e]*/
2110 {
2111     self->ob_exports++; // this protects `self` from being cleared/resized if `iterable_of_bytes` is a custom iterator
2112     PyObject* ret = stringlib_bytes_join((PyObject*)self, iterable_of_bytes);
2113     self->ob_exports--; // unexport `self`
2114     return ret;
2115 }
2116 
2117 /*[clinic input]
2118 bytearray.splitlines
2119 
2120     keepends: bool = False
2121 
2122 Return a list of the lines in the bytearray, breaking at line boundaries.
2123 
2124 Line breaks are not included in the resulting list unless keepends is given and
2125 true.
2126 [clinic start generated code]*/
2127 
2128 static PyObject *
bytearray_splitlines_impl(PyByteArrayObject * self,int keepends)2129 bytearray_splitlines_impl(PyByteArrayObject *self, int keepends)
2130 /*[clinic end generated code: output=4223c94b895f6ad9 input=66b2dcdea8d093bf]*/
2131 {
2132     return stringlib_splitlines(
2133         (PyObject*) self, PyByteArray_AS_STRING(self),
2134         PyByteArray_GET_SIZE(self), keepends
2135         );
2136 }
2137 
2138 /*[clinic input]
2139 @classmethod
2140 bytearray.fromhex
2141 
2142     string: unicode
2143     /
2144 
2145 Create a bytearray object from a string of hexadecimal numbers.
2146 
2147 Spaces between two numbers are accepted.
2148 Example: bytearray.fromhex('B9 01EF') -> bytearray(b'\\xb9\\x01\\xef')
2149 [clinic start generated code]*/
2150 
2151 static PyObject *
bytearray_fromhex_impl(PyTypeObject * type,PyObject * string)2152 bytearray_fromhex_impl(PyTypeObject *type, PyObject *string)
2153 /*[clinic end generated code: output=8f0f0b6d30fb3ba0 input=f033a16d1fb21f48]*/
2154 {
2155     PyObject *result = _PyBytes_FromHex(string, type == &PyByteArray_Type);
2156     if (type != &PyByteArray_Type && result != NULL) {
2157         Py_SETREF(result, PyObject_CallOneArg((PyObject *)type, result));
2158     }
2159     return result;
2160 }
2161 
2162 /*[clinic input]
2163 bytearray.hex
2164 
2165     sep: object = NULL
2166         An optional single character or byte to separate hex bytes.
2167     bytes_per_sep: int = 1
2168         How many bytes between separators.  Positive values count from the
2169         right, negative values count from the left.
2170 
2171 Create a string of hexadecimal numbers from a bytearray object.
2172 
2173 Example:
2174 >>> value = bytearray([0xb9, 0x01, 0xef])
2175 >>> value.hex()
2176 'b901ef'
2177 >>> value.hex(':')
2178 'b9:01:ef'
2179 >>> value.hex(':', 2)
2180 'b9:01ef'
2181 >>> value.hex(':', -2)
2182 'b901:ef'
2183 [clinic start generated code]*/
2184 
2185 static PyObject *
bytearray_hex_impl(PyByteArrayObject * self,PyObject * sep,int bytes_per_sep)2186 bytearray_hex_impl(PyByteArrayObject *self, PyObject *sep, int bytes_per_sep)
2187 /*[clinic end generated code: output=29c4e5ef72c565a0 input=808667e49bcccb54]*/
2188 {
2189     char* argbuf = PyByteArray_AS_STRING(self);
2190     Py_ssize_t arglen = PyByteArray_GET_SIZE(self);
2191     return _Py_strhex_with_sep(argbuf, arglen, sep, bytes_per_sep);
2192 }
2193 
2194 static PyObject *
_common_reduce(PyByteArrayObject * self,int proto)2195 _common_reduce(PyByteArrayObject *self, int proto)
2196 {
2197     PyObject *state;
2198     const char *buf;
2199 
2200     state = _PyObject_GetState((PyObject *)self);
2201     if (state == NULL) {
2202         return NULL;
2203     }
2204 
2205     if (!Py_SIZE(self)) {
2206         return Py_BuildValue("(O()N)", Py_TYPE(self), state);
2207     }
2208     buf = PyByteArray_AS_STRING(self);
2209     if (proto < 3) {
2210         /* use str based reduction for backwards compatibility with Python 2.x */
2211         PyObject *latin1 = PyUnicode_DecodeLatin1(buf, Py_SIZE(self), NULL);
2212         return Py_BuildValue("(O(Ns)N)", Py_TYPE(self), latin1, "latin-1", state);
2213     }
2214     else {
2215         /* use more efficient byte based reduction */
2216         return Py_BuildValue("(O(y#)N)", Py_TYPE(self), buf, Py_SIZE(self), state);
2217     }
2218 }
2219 
2220 /*[clinic input]
2221 bytearray.__reduce__ as bytearray_reduce
2222 
2223 Return state information for pickling.
2224 [clinic start generated code]*/
2225 
2226 static PyObject *
bytearray_reduce_impl(PyByteArrayObject * self)2227 bytearray_reduce_impl(PyByteArrayObject *self)
2228 /*[clinic end generated code: output=52bf304086464cab input=44b5737ada62dd3f]*/
2229 {
2230     return _common_reduce(self, 2);
2231 }
2232 
2233 /*[clinic input]
2234 bytearray.__reduce_ex__ as bytearray_reduce_ex
2235 
2236     proto: int = 0
2237     /
2238 
2239 Return state information for pickling.
2240 [clinic start generated code]*/
2241 
2242 static PyObject *
bytearray_reduce_ex_impl(PyByteArrayObject * self,int proto)2243 bytearray_reduce_ex_impl(PyByteArrayObject *self, int proto)
2244 /*[clinic end generated code: output=52eac33377197520 input=f129bc1a1aa151ee]*/
2245 {
2246     return _common_reduce(self, proto);
2247 }
2248 
2249 /*[clinic input]
2250 bytearray.__sizeof__ as bytearray_sizeof
2251 
2252 Returns the size of the bytearray object in memory, in bytes.
2253 [clinic start generated code]*/
2254 
2255 static PyObject *
bytearray_sizeof_impl(PyByteArrayObject * self)2256 bytearray_sizeof_impl(PyByteArrayObject *self)
2257 /*[clinic end generated code: output=738abdd17951c427 input=e27320fd98a4bc5a]*/
2258 {
2259     size_t res = _PyObject_SIZE(Py_TYPE(self));
2260     res += (size_t)self->ob_alloc * sizeof(char);
2261     return PyLong_FromSize_t(res);
2262 }
2263 
2264 static PySequenceMethods bytearray_as_sequence = {
2265     (lenfunc)bytearray_length,              /* sq_length */
2266     (binaryfunc)PyByteArray_Concat,         /* sq_concat */
2267     (ssizeargfunc)bytearray_repeat,         /* sq_repeat */
2268     (ssizeargfunc)bytearray_getitem,        /* sq_item */
2269     0,                                      /* sq_slice */
2270     (ssizeobjargproc)bytearray_setitem,     /* sq_ass_item */
2271     0,                                      /* sq_ass_slice */
2272     (objobjproc)bytearray_contains,         /* sq_contains */
2273     (binaryfunc)bytearray_iconcat,          /* sq_inplace_concat */
2274     (ssizeargfunc)bytearray_irepeat,        /* sq_inplace_repeat */
2275 };
2276 
2277 static PyMappingMethods bytearray_as_mapping = {
2278     (lenfunc)bytearray_length,
2279     (binaryfunc)bytearray_subscript,
2280     (objobjargproc)bytearray_ass_subscript,
2281 };
2282 
2283 static PyBufferProcs bytearray_as_buffer = {
2284     (getbufferproc)bytearray_getbuffer,
2285     (releasebufferproc)bytearray_releasebuffer,
2286 };
2287 
2288 static PyMethodDef
2289 bytearray_methods[] = {
2290     {"__alloc__", (PyCFunction)bytearray_alloc, METH_NOARGS, alloc_doc},
2291     BYTEARRAY_REDUCE_METHODDEF
2292     BYTEARRAY_REDUCE_EX_METHODDEF
2293     BYTEARRAY_SIZEOF_METHODDEF
2294     BYTEARRAY_APPEND_METHODDEF
2295     {"capitalize", stringlib_capitalize, METH_NOARGS,
2296      _Py_capitalize__doc__},
2297     STRINGLIB_CENTER_METHODDEF
2298     BYTEARRAY_CLEAR_METHODDEF
2299     BYTEARRAY_COPY_METHODDEF
2300     BYTEARRAY_COUNT_METHODDEF
2301     BYTEARRAY_DECODE_METHODDEF
2302     BYTEARRAY_ENDSWITH_METHODDEF
2303     STRINGLIB_EXPANDTABS_METHODDEF
2304     BYTEARRAY_EXTEND_METHODDEF
2305     BYTEARRAY_FIND_METHODDEF
2306     BYTEARRAY_FROMHEX_METHODDEF
2307     BYTEARRAY_HEX_METHODDEF
2308     BYTEARRAY_INDEX_METHODDEF
2309     BYTEARRAY_INSERT_METHODDEF
2310     {"isalnum", stringlib_isalnum, METH_NOARGS,
2311      _Py_isalnum__doc__},
2312     {"isalpha", stringlib_isalpha, METH_NOARGS,
2313      _Py_isalpha__doc__},
2314     {"isascii", stringlib_isascii, METH_NOARGS,
2315      _Py_isascii__doc__},
2316     {"isdigit", stringlib_isdigit, METH_NOARGS,
2317      _Py_isdigit__doc__},
2318     {"islower", stringlib_islower, METH_NOARGS,
2319      _Py_islower__doc__},
2320     {"isspace", stringlib_isspace, METH_NOARGS,
2321      _Py_isspace__doc__},
2322     {"istitle", stringlib_istitle, METH_NOARGS,
2323      _Py_istitle__doc__},
2324     {"isupper", stringlib_isupper, METH_NOARGS,
2325      _Py_isupper__doc__},
2326     BYTEARRAY_JOIN_METHODDEF
2327     STRINGLIB_LJUST_METHODDEF
2328     {"lower", stringlib_lower, METH_NOARGS, _Py_lower__doc__},
2329     BYTEARRAY_LSTRIP_METHODDEF
2330     BYTEARRAY_MAKETRANS_METHODDEF
2331     BYTEARRAY_PARTITION_METHODDEF
2332     BYTEARRAY_POP_METHODDEF
2333     BYTEARRAY_REMOVE_METHODDEF
2334     BYTEARRAY_REPLACE_METHODDEF
2335     BYTEARRAY_REMOVEPREFIX_METHODDEF
2336     BYTEARRAY_REMOVESUFFIX_METHODDEF
2337     BYTEARRAY_REVERSE_METHODDEF
2338     BYTEARRAY_RFIND_METHODDEF
2339     BYTEARRAY_RINDEX_METHODDEF
2340     STRINGLIB_RJUST_METHODDEF
2341     BYTEARRAY_RPARTITION_METHODDEF
2342     BYTEARRAY_RSPLIT_METHODDEF
2343     BYTEARRAY_RSTRIP_METHODDEF
2344     BYTEARRAY_SPLIT_METHODDEF
2345     BYTEARRAY_SPLITLINES_METHODDEF
2346     BYTEARRAY_STARTSWITH_METHODDEF
2347     BYTEARRAY_STRIP_METHODDEF
2348     {"swapcase", stringlib_swapcase, METH_NOARGS,
2349      _Py_swapcase__doc__},
2350     {"title", stringlib_title, METH_NOARGS, _Py_title__doc__},
2351     BYTEARRAY_TRANSLATE_METHODDEF
2352     {"upper", stringlib_upper, METH_NOARGS, _Py_upper__doc__},
2353     STRINGLIB_ZFILL_METHODDEF
2354     {NULL}
2355 };
2356 
2357 static PyObject *
bytearray_mod(PyObject * v,PyObject * w)2358 bytearray_mod(PyObject *v, PyObject *w)
2359 {
2360     if (!PyByteArray_Check(v))
2361         Py_RETURN_NOTIMPLEMENTED;
2362     return _PyBytes_FormatEx(PyByteArray_AS_STRING(v), PyByteArray_GET_SIZE(v), w, 1);
2363 }
2364 
2365 static PyNumberMethods bytearray_as_number = {
2366     0,              /*nb_add*/
2367     0,              /*nb_subtract*/
2368     0,              /*nb_multiply*/
2369     bytearray_mod,  /*nb_remainder*/
2370 };
2371 
2372 PyDoc_STRVAR(bytearray_doc,
2373 "bytearray(iterable_of_ints) -> bytearray\n\
2374 bytearray(string, encoding[, errors]) -> bytearray\n\
2375 bytearray(bytes_or_buffer) -> mutable copy of bytes_or_buffer\n\
2376 bytearray(int) -> bytes array of size given by the parameter initialized with null bytes\n\
2377 bytearray() -> empty bytes array\n\
2378 \n\
2379 Construct a mutable bytearray object from:\n\
2380   - an iterable yielding integers in range(256)\n\
2381   - a text string encoded using the specified encoding\n\
2382   - a bytes or a buffer object\n\
2383   - any object implementing the buffer API.\n\
2384   - an integer");
2385 
2386 
2387 static PyObject *bytearray_iter(PyObject *seq);
2388 
2389 PyTypeObject PyByteArray_Type = {
2390     PyVarObject_HEAD_INIT(&PyType_Type, 0)
2391     "bytearray",
2392     sizeof(PyByteArrayObject),
2393     0,
2394     (destructor)bytearray_dealloc,       /* tp_dealloc */
2395     0,                                  /* tp_vectorcall_offset */
2396     0,                                  /* tp_getattr */
2397     0,                                  /* tp_setattr */
2398     0,                                  /* tp_as_async */
2399     (reprfunc)bytearray_repr,           /* tp_repr */
2400     &bytearray_as_number,               /* tp_as_number */
2401     &bytearray_as_sequence,             /* tp_as_sequence */
2402     &bytearray_as_mapping,              /* tp_as_mapping */
2403     0,                                  /* tp_hash */
2404     0,                                  /* tp_call */
2405     bytearray_str,                      /* tp_str */
2406     PyObject_GenericGetAttr,            /* tp_getattro */
2407     0,                                  /* tp_setattro */
2408     &bytearray_as_buffer,               /* tp_as_buffer */
2409     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE |
2410         _Py_TPFLAGS_MATCH_SELF,       /* tp_flags */
2411     bytearray_doc,                      /* tp_doc */
2412     0,                                  /* tp_traverse */
2413     0,                                  /* tp_clear */
2414     (richcmpfunc)bytearray_richcompare, /* tp_richcompare */
2415     0,                                  /* tp_weaklistoffset */
2416     bytearray_iter,                     /* tp_iter */
2417     0,                                  /* tp_iternext */
2418     bytearray_methods,                  /* tp_methods */
2419     0,                                  /* tp_members */
2420     0,                                  /* tp_getset */
2421     0,                                  /* tp_base */
2422     0,                                  /* tp_dict */
2423     0,                                  /* tp_descr_get */
2424     0,                                  /* tp_descr_set */
2425     0,                                  /* tp_dictoffset */
2426     (initproc)bytearray___init__,       /* tp_init */
2427     PyType_GenericAlloc,                /* tp_alloc */
2428     PyType_GenericNew,                  /* tp_new */
2429     PyObject_Del,                       /* tp_free */
2430 };
2431 
2432 /*********************** Bytearray Iterator ****************************/
2433 
2434 typedef struct {
2435     PyObject_HEAD
2436     Py_ssize_t it_index;
2437     PyByteArrayObject *it_seq; /* Set to NULL when iterator is exhausted */
2438 } bytesiterobject;
2439 
2440 static void
bytearrayiter_dealloc(bytesiterobject * it)2441 bytearrayiter_dealloc(bytesiterobject *it)
2442 {
2443     _PyObject_GC_UNTRACK(it);
2444     Py_XDECREF(it->it_seq);
2445     PyObject_GC_Del(it);
2446 }
2447 
2448 static int
bytearrayiter_traverse(bytesiterobject * it,visitproc visit,void * arg)2449 bytearrayiter_traverse(bytesiterobject *it, visitproc visit, void *arg)
2450 {
2451     Py_VISIT(it->it_seq);
2452     return 0;
2453 }
2454 
2455 static PyObject *
bytearrayiter_next(bytesiterobject * it)2456 bytearrayiter_next(bytesiterobject *it)
2457 {
2458     PyByteArrayObject *seq;
2459 
2460     assert(it != NULL);
2461     seq = it->it_seq;
2462     if (seq == NULL)
2463         return NULL;
2464     assert(PyByteArray_Check(seq));
2465 
2466     if (it->it_index < PyByteArray_GET_SIZE(seq)) {
2467         return _PyLong_FromUnsignedChar(
2468             (unsigned char)PyByteArray_AS_STRING(seq)[it->it_index++]);
2469     }
2470 
2471     it->it_seq = NULL;
2472     Py_DECREF(seq);
2473     return NULL;
2474 }
2475 
2476 static PyObject *
bytearrayiter_length_hint(bytesiterobject * it,PyObject * Py_UNUSED (ignored))2477 bytearrayiter_length_hint(bytesiterobject *it, PyObject *Py_UNUSED(ignored))
2478 {
2479     Py_ssize_t len = 0;
2480     if (it->it_seq) {
2481         len = PyByteArray_GET_SIZE(it->it_seq) - it->it_index;
2482         if (len < 0) {
2483             len = 0;
2484         }
2485     }
2486     return PyLong_FromSsize_t(len);
2487 }
2488 
2489 PyDoc_STRVAR(length_hint_doc,
2490     "Private method returning an estimate of len(list(it)).");
2491 
2492 static PyObject *
bytearrayiter_reduce(bytesiterobject * it,PyObject * Py_UNUSED (ignored))2493 bytearrayiter_reduce(bytesiterobject *it, PyObject *Py_UNUSED(ignored))
2494 {
2495     PyObject *iter = _PyEval_GetBuiltin(&_Py_ID(iter));
2496 
2497     /* _PyEval_GetBuiltin can invoke arbitrary code,
2498      * call must be before access of iterator pointers.
2499      * see issue #101765 */
2500 
2501     if (it->it_seq != NULL) {
2502         return Py_BuildValue("N(O)n", iter, it->it_seq, it->it_index);
2503     } else {
2504         return Py_BuildValue("N(())", iter);
2505     }
2506 }
2507 
2508 static PyObject *
bytearrayiter_setstate(bytesiterobject * it,PyObject * state)2509 bytearrayiter_setstate(bytesiterobject *it, PyObject *state)
2510 {
2511     Py_ssize_t index = PyLong_AsSsize_t(state);
2512     if (index == -1 && PyErr_Occurred())
2513         return NULL;
2514     if (it->it_seq != NULL) {
2515         if (index < 0)
2516             index = 0;
2517         else if (index > PyByteArray_GET_SIZE(it->it_seq))
2518             index = PyByteArray_GET_SIZE(it->it_seq); /* iterator exhausted */
2519         it->it_index = index;
2520     }
2521     Py_RETURN_NONE;
2522 }
2523 
2524 PyDoc_STRVAR(setstate_doc, "Set state information for unpickling.");
2525 
2526 static PyMethodDef bytearrayiter_methods[] = {
2527     {"__length_hint__", (PyCFunction)bytearrayiter_length_hint, METH_NOARGS,
2528      length_hint_doc},
2529      {"__reduce__",      (PyCFunction)bytearrayiter_reduce, METH_NOARGS,
2530      bytearray_reduce__doc__},
2531     {"__setstate__",    (PyCFunction)bytearrayiter_setstate, METH_O,
2532      setstate_doc},
2533     {NULL, NULL} /* sentinel */
2534 };
2535 
2536 PyTypeObject PyByteArrayIter_Type = {
2537     PyVarObject_HEAD_INIT(&PyType_Type, 0)
2538     "bytearray_iterator",              /* tp_name */
2539     sizeof(bytesiterobject),           /* tp_basicsize */
2540     0,                                 /* tp_itemsize */
2541     /* methods */
2542     (destructor)bytearrayiter_dealloc, /* tp_dealloc */
2543     0,                                 /* tp_vectorcall_offset */
2544     0,                                 /* tp_getattr */
2545     0,                                 /* tp_setattr */
2546     0,                                 /* tp_as_async */
2547     0,                                 /* tp_repr */
2548     0,                                 /* tp_as_number */
2549     0,                                 /* tp_as_sequence */
2550     0,                                 /* tp_as_mapping */
2551     0,                                 /* tp_hash */
2552     0,                                 /* tp_call */
2553     0,                                 /* tp_str */
2554     PyObject_GenericGetAttr,           /* tp_getattro */
2555     0,                                 /* tp_setattro */
2556     0,                                 /* tp_as_buffer */
2557     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
2558     0,                                 /* tp_doc */
2559     (traverseproc)bytearrayiter_traverse,  /* tp_traverse */
2560     0,                                 /* tp_clear */
2561     0,                                 /* tp_richcompare */
2562     0,                                 /* tp_weaklistoffset */
2563     PyObject_SelfIter,                 /* tp_iter */
2564     (iternextfunc)bytearrayiter_next,  /* tp_iternext */
2565     bytearrayiter_methods,             /* tp_methods */
2566     0,
2567 };
2568 
2569 static PyObject *
bytearray_iter(PyObject * seq)2570 bytearray_iter(PyObject *seq)
2571 {
2572     bytesiterobject *it;
2573 
2574     if (!PyByteArray_Check(seq)) {
2575         PyErr_BadInternalCall();
2576         return NULL;
2577     }
2578     it = PyObject_GC_New(bytesiterobject, &PyByteArrayIter_Type);
2579     if (it == NULL)
2580         return NULL;
2581     it->it_index = 0;
2582     it->it_seq = (PyByteArrayObject *)Py_NewRef(seq);
2583     _PyObject_GC_TRACK(it);
2584     return (PyObject *)it;
2585 }
2586