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