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