Coverage Report

Created: 2026-10-15 06:54

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/cpython3/Objects/bytearrayobject.c
Line
Count
Source
1
/* PyByteArray (bytearray) implementation */
2
3
#include "Python.h"
4
#include "pycore_abstract.h"      // _PyIndex_Check()
5
#include "pycore_bytes_methods.h"
6
#include "pycore_bytesobject.h"
7
#include "pycore_ceval.h"         // _PyEval_GetBuiltin()
8
#include "pycore_critical_section.h"
9
#include "pycore_object.h"        // _PyObject_GC_UNTRACK()
10
#include "pycore_strhex.h"        // _Py_strhex_with_sep()
11
#include "pycore_long.h"          // _PyLong_FromUnsignedChar()
12
#include "pycore_pyatomic_ft_wrappers.h"
13
#include "bytesobject.h"
14
15
/*[clinic input]
16
class bytearray "PyByteArrayObject *" "&PyByteArray_Type"
17
[clinic start generated code]*/
18
/*[clinic end generated code: output=da39a3ee5e6b4b0d input=5535b77c37a119e0]*/
19
20
/* Max number of bytes a bytearray can contain */
21
735k
#define PyByteArray_SIZE_MAX ((Py_ssize_t)(PY_SSIZE_T_MAX - _PyBytesObject_SIZE))
22
23
/* Helpers */
24
25
static int
26
_getbytevalue(PyObject* arg, int *value)
27
11.8M
{
28
11.8M
    int overflow;
29
11.8M
    long face_value = PyLong_AsLongAndOverflow(arg, &overflow);
30
31
11.8M
    if (face_value == -1 && PyErr_Occurred()) {
32
0
        *value = -1;
33
0
        return 0;
34
0
    }
35
11.8M
    if (face_value < 0 || face_value >= 256) {
36
        /* this includes an overflow in converting to C long */
37
0
        PyErr_SetString(PyExc_ValueError, "byte must be in range(0, 256)");
38
0
        *value = -1;
39
0
        return 0;
40
0
    }
41
42
11.8M
    *value = face_value;
43
11.8M
    return 1;
44
11.8M
}
45
46
static inline void
47
bytearray_write_trailing_null_byte(PyByteArrayObject *self)
48
142k
{
49
142k
    char *data = PyByteArray_AS_STRING(self);
50
142k
    Py_ssize_t size = PyByteArray_GET_SIZE(self);
51
142k
    data[size] = '\0';
52
142k
}
53
54
55
static void
56
bytearray_reinit_from_bytes(PyByteArrayObject *self, Py_ssize_t size)
57
1.69M
{
58
1.69M
    Py_ssize_t alloc = PyBytes_GET_SIZE(self->ob_bytes_object);
59
1.69M
    assert(0 <= size && size <= alloc);
60
61
1.69M
    if (alloc != 0) {
62
1.10M
        assert(_PyBytes_IsMutable(self->ob_bytes_object));
63
1.10M
    }
64
589k
    else {
65
        // Use the empty bytes string singleton for an empty bytearray
66
589k
        assert(_Py_IsImmortal(self->ob_bytes_object));
67
589k
    }
68
69
1.69M
    self->ob_bytes = self->ob_start = PyBytes_AS_STRING(self->ob_bytes_object);
70
1.69M
    Py_SET_SIZE(self, size);
71
1.69M
    FT_ATOMIC_STORE_SSIZE_RELAXED(self->ob_alloc, alloc);
72
1.69M
}
73
74
static int
75
bytearray_getbuffer_lock_held(PyObject *self, Py_buffer *view, int flags)
76
2
{
77
2
    _Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED(self);
78
2
    PyByteArrayObject *obj = _PyByteArray_CAST(self);
79
2
    if (view == NULL) {
80
0
        PyErr_SetString(PyExc_BufferError,
81
0
            "bytearray_getbuffer: view==NULL argument is obsolete");
82
0
        return -1;
83
0
    }
84
85
2
    void *ptr = (void *) PyByteArray_AS_STRING(obj);
86
2
    if (PyBuffer_FillInfo(view, (PyObject*)obj, ptr, Py_SIZE(obj), 0, flags) < 0) {
87
0
        return -1;
88
0
    }
89
2
    obj->ob_exports++;
90
2
    return 0;
91
2
}
92
93
static int
94
bytearray_getbuffer(PyObject *self, Py_buffer *view, int flags)
95
2
{
96
2
    int ret;
97
2
    Py_BEGIN_CRITICAL_SECTION(self);
98
2
    ret = bytearray_getbuffer_lock_held(self, view, flags);
99
2
    Py_END_CRITICAL_SECTION();
100
2
    return ret;
101
2
}
102
103
static void
104
bytearray_releasebuffer(PyObject *self, Py_buffer *view)
105
2
{
106
2
    Py_BEGIN_CRITICAL_SECTION(self);
107
2
    PyByteArrayObject *obj = _PyByteArray_CAST(self);
108
0
    obj->ob_exports--;
109
2
    assert(obj->ob_exports >= 0);
110
2
    Py_END_CRITICAL_SECTION();
111
2
}
112
113
typedef PyObject* (*_ba_bytes_op)(const char *buf, Py_ssize_t len,
114
                                  PyObject *sub, Py_ssize_t start,
115
                                  Py_ssize_t end);
116
117
static PyObject *
118
_bytearray_with_buffer(PyByteArrayObject *self, _ba_bytes_op op, PyObject *sub,
119
                       Py_ssize_t start, Py_ssize_t end)
120
636k
{
121
636k
    PyObject *res;
122
123
636k
    _Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED(self);
124
125
    /* Increase exports to prevent bytearray storage from changing during op. */
126
636k
    self->ob_exports++;
127
636k
    res = op(PyByteArray_AS_STRING(self), Py_SIZE(self), sub, start, end);
128
636k
    self->ob_exports--;
129
636k
    return res;
130
636k
}
131
132
static int
133
_canresize(PyByteArrayObject *self)
134
1.26M
{
135
1.26M
    if (self->ob_exports > 0) {
136
0
        PyErr_SetString(PyExc_BufferError,
137
0
                "Existing exports of data: object cannot be re-sized");
138
0
        return 0;
139
0
    }
140
1.26M
    return 1;
141
1.26M
}
142
143
#include "clinic/bytearrayobject.c.h"
144
145
/* Direct API functions */
146
147
PyObject *
148
PyByteArray_FromObject(PyObject *input)
149
0
{
150
0
    return PyObject_CallOneArg((PyObject *)&PyByteArray_Type, input);
151
0
}
152
153
static PyObject *
154
_PyByteArray_FromBufferObject(PyObject *obj)
155
0
{
156
0
    PyObject *result;
157
0
    Py_buffer view;
158
159
0
    if (PyObject_GetBuffer(obj, &view, PyBUF_FULL_RO) < 0) {
160
0
        return NULL;
161
0
    }
162
0
    result = PyByteArray_FromStringAndSize(NULL, view.len);
163
0
    if (result != NULL &&
164
0
        PyBuffer_ToContiguous(PyByteArray_AS_STRING(result),
165
0
                              &view, view.len, 'C') < 0)
166
0
    {
167
0
        Py_CLEAR(result);
168
0
    }
169
0
    PyBuffer_Release(&view);
170
0
    return result;
171
0
}
172
173
PyObject *
174
PyByteArray_FromStringAndSize(const char *bytes, Py_ssize_t size)
175
571k
{
176
571k
    PyByteArrayObject *new;
177
178
571k
    if (size < 0) {
179
0
        PyErr_SetString(PyExc_SystemError,
180
0
            "Negative size passed to PyByteArray_FromStringAndSize");
181
0
        return NULL;
182
0
    }
183
184
571k
    new = PyObject_New(PyByteArrayObject, &PyByteArray_Type);
185
571k
    if (new == NULL) {
186
0
        return NULL;
187
0
    }
188
189
    /* Fill values used in bytearray_dealloc.
190
191
       In an optimized build the memory isn't zeroed and ob_exports would be
192
       uninitialized when when PyBytes_FromStringAndSize errored leading to
193
       intermittent test failures. */
194
571k
    new->ob_exports = 0;
195
196
    /* Optimization: size=0 bytearray should not allocate space
197
198
       PyBytes_FromStringAndSize returns the empty bytes global when size=0 so
199
       no allocation occurs. */
200
571k
    new->ob_bytes_object = PyBytes_FromStringAndSize(NULL, size);
201
571k
    if (new->ob_bytes_object == NULL) {
202
0
        Py_DECREF(new);
203
0
        return NULL;
204
0
    }
205
571k
    bytearray_reinit_from_bytes(new, size);
206
571k
    if (bytes != NULL && size > 0) {
207
455k
        memcpy(new->ob_bytes, bytes, size);
208
455k
    }
209
210
571k
    return (PyObject *)new;
211
571k
}
212
213
Py_ssize_t
214
PyByteArray_Size(PyObject *self)
215
0
{
216
0
    assert(self != NULL);
217
0
    assert(PyByteArray_Check(self));
218
219
0
    return PyByteArray_GET_SIZE(self);
220
0
}
221
222
char  *
223
PyByteArray_AsString(PyObject *self)
224
0
{
225
0
    assert(self != NULL);
226
0
    assert(PyByteArray_Check(self));
227
228
0
    return PyByteArray_AS_STRING(self);
229
0
}
230
231
232
static int
233
bytearray_resize_storage(PyByteArrayObject *self,
234
                         Py_ssize_t new_size, Py_ssize_t alloc)
235
761k
{
236
761k
    _Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED(self);
237
761k
    assert(1 <= new_size && new_size <= alloc);
238
239
761k
    Py_ssize_t size = Py_SIZE(self);
240
241
    /* Re-align data to the start of the allocation. */
242
761k
    char *old_start = self->ob_start;
243
761k
    if (self->ob_start != self->ob_bytes) {
244
        /* optimization tradeoff: This is faster than a new allocation when
245
           the number of bytes being removed in a resize is small; for
246
           large size changes it may be better to just make a new bytes
247
           object as _PyBytes_Resize will do a malloc + memcpy internally.
248
           */
249
0
        Py_ssize_t move = Py_MIN(new_size, size);
250
0
        memmove(self->ob_bytes, self->ob_start, move);
251
0
        self->ob_start = self->ob_bytes;
252
0
    }
253
254
761k
    if (_PyBytes_ResizeKeepOnError(&self->ob_bytes_object, alloc) < 0) {
255
0
        if (old_start != self->ob_bytes && new_size < size) {
256
            // Move remaining bytes
257
0
            Py_ssize_t moved = new_size;
258
0
            Py_ssize_t remaining = size - moved;
259
0
            memmove(self->ob_bytes + moved, old_start + moved, remaining);
260
0
        }
261
0
        bytearray_write_trailing_null_byte(self);
262
0
        return -1;
263
0
    }
264
761k
    assert(_PyBytes_IsMutable(self->ob_bytes_object));
265
761k
    return 0;
266
761k
}
267
268
269
static int
270
bytearray_resize_lock_held(PyObject *self, Py_ssize_t requested_size)
271
1.02M
{
272
1.02M
    _Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED(self);
273
1.02M
    PyByteArrayObject *obj = ((PyByteArrayObject *)self);
274
275
1.02M
    assert(obj->ob_bytes_object != NULL);
276
277
    /* All computations are done unsigned to avoid integer overflows
278
       (see issue #22335). */
279
1.02M
    size_t alloc = (size_t) obj->ob_alloc;
280
1.02M
    size_t logical_offset = (size_t) (obj->ob_start - obj->ob_bytes);
281
1.02M
    size_t size = (size_t) requested_size;
282
283
1.02M
    assert(self != NULL);
284
1.02M
    assert(PyByteArray_Check(self));
285
1.02M
    assert(logical_offset <= alloc);
286
287
1.02M
    if (requested_size < 0) {
288
0
        PyErr_Format(PyExc_ValueError,
289
0
            "Can only resize to positive sizes, got %zd", requested_size);
290
0
        return -1;
291
0
    }
292
293
1.02M
    if (requested_size == Py_SIZE(self)) {
294
366k
        return 0;
295
366k
    }
296
657k
    if (!_canresize(obj)) {
297
0
        return -1;
298
0
    }
299
300
    /* Resize to 0 resets to empty bytes (see issue #153419). */
301
657k
    if (requested_size == 0) {
302
0
        Py_SETREF(obj->ob_bytes_object,
303
0
                   Py_GetConstant(Py_CONSTANT_EMPTY_BYTES));
304
0
        bytearray_reinit_from_bytes(obj, 0);
305
0
        return 0;
306
0
    }
307
308
657k
    if (size + logical_offset <= alloc) {
309
        /* Current buffer is large enough to host the requested size,
310
           decide on a strategy. */
311
119k
        if (size < alloc / 2) {
312
            /* Major downsize; resize down to exact size */
313
0
            alloc = size;
314
0
        }
315
119k
        else {
316
            /* Minor downsize; quick exit */
317
119k
            Py_SET_SIZE(self, size);
318
            /* Add mid-buffer null; end provided by bytes. */
319
119k
            bytearray_write_trailing_null_byte(_PyByteArray_CAST(self));
320
0
            return 0;
321
119k
        }
322
119k
    }
323
537k
    else {
324
        /* Need growing, decide on a strategy */
325
537k
        if (size <= alloc * 1.125) {
326
            /* Moderate upsize; overallocate similar to list_resize() */
327
23.1k
            alloc = size + (size >> 3) + (size < 9 ? 3 : 6);
328
23.1k
        }
329
514k
        else {
330
            /* Major upsize; resize up to exact size */
331
514k
            alloc = size;
332
514k
        }
333
537k
    }
334
537k
    if (alloc > PyByteArray_SIZE_MAX) {
335
0
        PyErr_NoMemory();
336
0
        return -1;
337
0
    }
338
339
537k
    if (bytearray_resize_storage(obj, requested_size, (Py_ssize_t)alloc) < 0) {
340
0
        return -1;
341
0
    }
342
343
537k
    bytearray_reinit_from_bytes(obj, size);
344
537k
    if (alloc != size) {
345
        /* Add mid-buffer null; end provided by bytes. */
346
23.1k
        bytearray_write_trailing_null_byte(obj);
347
23.1k
    }
348
537k
    return 0;
349
537k
}
350
351
int
352
PyByteArray_Resize(PyObject *self, Py_ssize_t requested_size)
353
496k
{
354
496k
    int ret;
355
496k
    Py_BEGIN_CRITICAL_SECTION(self);
356
496k
    ret = bytearray_resize_lock_held(self, requested_size);
357
496k
    Py_END_CRITICAL_SECTION();
358
496k
    return ret;
359
496k
}
360
361
PyObject *
362
PyByteArray_Concat(PyObject *a, PyObject *b)
363
0
{
364
0
    Py_buffer va, vb;
365
0
    PyByteArrayObject *result = NULL;
366
367
0
    va.len = -1;
368
0
    vb.len = -1;
369
0
    if (PyObject_GetBuffer(a, &va, PyBUF_SIMPLE) != 0 ||
370
0
        PyObject_GetBuffer(b, &vb, PyBUF_SIMPLE) != 0) {
371
0
            PyErr_Format(PyExc_TypeError, "can't concat %.100s to %.100s",
372
0
                         Py_TYPE(b)->tp_name, Py_TYPE(a)->tp_name);
373
0
            goto done;
374
0
    }
375
376
0
    if (va.len > PyByteArray_SIZE_MAX - vb.len) {
377
0
        PyErr_NoMemory();
378
0
        goto done;
379
0
    }
380
381
0
    result = (PyByteArrayObject *) \
382
0
        PyByteArray_FromStringAndSize(NULL, va.len + vb.len);
383
    // result->ob_bytes is NULL if result is an empty bytearray:
384
    // if va.len + vb.len equals zero.
385
0
    if (result != NULL && result->ob_bytes != NULL) {
386
0
        memcpy(result->ob_bytes, va.buf, va.len);
387
0
        memcpy(result->ob_bytes + va.len, vb.buf, vb.len);
388
0
    }
389
390
0
  done:
391
0
    if (va.len != -1)
392
0
        PyBuffer_Release(&va);
393
0
    if (vb.len != -1)
394
0
        PyBuffer_Release(&vb);
395
0
    return (PyObject *)result;
396
0
}
397
398
/* Functions stuffed into the type object */
399
400
static Py_ssize_t
401
bytearray_length(PyObject *op)
402
114k
{
403
114k
    return PyByteArray_GET_SIZE(op);
404
114k
}
405
406
static PyObject *
407
bytearray_iconcat_lock_held(PyObject *op, PyObject *other)
408
10
{
409
10
    _Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED(op);
410
10
    PyByteArrayObject *self = _PyByteArray_CAST(op);
411
412
0
    Py_buffer vo;
413
10
    if (PyObject_GetBuffer(other, &vo, PyBUF_SIMPLE) != 0) {
414
0
        PyErr_Format(PyExc_TypeError, "can't concat %.100s to %.100s",
415
0
                     Py_TYPE(other)->tp_name, Py_TYPE(self)->tp_name);
416
0
        return NULL;
417
0
    }
418
419
10
    Py_ssize_t size = Py_SIZE(self);
420
10
    if (size > PyByteArray_SIZE_MAX - vo.len) {
421
0
        PyBuffer_Release(&vo);
422
0
        return PyErr_NoMemory();
423
0
    }
424
425
10
    if (bytearray_resize_lock_held((PyObject *)self, size + vo.len) < 0) {
426
0
        PyBuffer_Release(&vo);
427
0
        return NULL;
428
0
    }
429
430
10
    memcpy(PyByteArray_AS_STRING(self) + size, vo.buf, vo.len);
431
10
    PyBuffer_Release(&vo);
432
10
    return Py_NewRef(self);
433
10
}
434
435
static PyObject *
436
bytearray_iconcat(PyObject *op, PyObject *other)
437
10
{
438
10
    PyObject *ret;
439
10
    Py_BEGIN_CRITICAL_SECTION(op);
440
10
    ret = bytearray_iconcat_lock_held(op, other);
441
10
    Py_END_CRITICAL_SECTION();
442
10
    return ret;
443
10
}
444
445
static PyObject *
446
bytearray_repeat_lock_held(PyObject *op, Py_ssize_t count)
447
0
{
448
0
    _Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED(op);
449
0
    PyByteArrayObject *self = _PyByteArray_CAST(op);
450
0
    if (count < 0) {
451
0
        count = 0;
452
0
    }
453
0
    const Py_ssize_t mysize = Py_SIZE(self);
454
0
    if (count > 0 && mysize > PyByteArray_SIZE_MAX / count) {
455
0
        return PyErr_NoMemory();
456
0
    }
457
0
    Py_ssize_t size = mysize * count;
458
459
0
    PyByteArrayObject* result = (PyByteArrayObject *)PyByteArray_FromStringAndSize(NULL, size);
460
0
    const char* buf = PyByteArray_AS_STRING(self);
461
0
    if (result != NULL && size != 0) {
462
0
        _PyBytes_RepeatBuffer(result->ob_bytes, size, buf, mysize);
463
0
    }
464
0
    return (PyObject *)result;
465
0
}
466
467
static PyObject *
468
bytearray_repeat(PyObject *op, Py_ssize_t count)
469
0
{
470
0
    PyObject *ret;
471
0
    Py_BEGIN_CRITICAL_SECTION(op);
472
0
    ret = bytearray_repeat_lock_held(op, count);
473
0
    Py_END_CRITICAL_SECTION();
474
0
    return ret;
475
0
}
476
477
static PyObject *
478
bytearray_irepeat_lock_held(PyObject *op, Py_ssize_t count)
479
0
{
480
0
    _Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED(op);
481
0
    PyByteArrayObject *self = _PyByteArray_CAST(op);
482
0
    if (count < 0) {
483
0
        count = 0;
484
0
    }
485
0
    else if (count == 1) {
486
0
        return Py_NewRef(self);
487
0
    }
488
489
0
    const Py_ssize_t mysize = Py_SIZE(self);
490
0
    if (count > 0 && mysize > PyByteArray_SIZE_MAX / count) {
491
0
        return PyErr_NoMemory();
492
0
    }
493
0
    const Py_ssize_t size = mysize * count;
494
0
    if (bytearray_resize_lock_held((PyObject *)self, size) < 0) {
495
0
        return NULL;
496
0
    }
497
498
0
    char* buf = PyByteArray_AS_STRING(self);
499
0
    _PyBytes_RepeatBuffer(buf, size, buf, mysize);
500
501
0
    return Py_NewRef(self);
502
0
}
503
504
static PyObject *
505
bytearray_irepeat(PyObject *op, Py_ssize_t count)
506
0
{
507
0
    PyObject *ret;
508
0
    Py_BEGIN_CRITICAL_SECTION(op);
509
0
    ret = bytearray_irepeat_lock_held(op, count);
510
0
    Py_END_CRITICAL_SECTION();
511
0
    return ret;
512
0
}
513
514
static PyObject *
515
bytearray_getitem_lock_held(PyObject *op, Py_ssize_t i)
516
0
{
517
0
    _Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED(op);
518
0
    PyByteArrayObject *self = _PyByteArray_CAST(op);
519
0
    if (i < 0 || i >= Py_SIZE(self)) {
520
0
        PyErr_SetString(PyExc_IndexError, "bytearray index out of range");
521
0
        return NULL;
522
0
    }
523
0
    return _PyLong_FromUnsignedChar((unsigned char)(self->ob_start[i]));
524
0
}
525
526
static PyObject *
527
bytearray_getitem(PyObject *op, Py_ssize_t i)
528
0
{
529
0
    PyObject *ret;
530
0
    Py_BEGIN_CRITICAL_SECTION(op);
531
0
    ret = bytearray_getitem_lock_held(op, i);
532
0
    Py_END_CRITICAL_SECTION();
533
0
    return ret;
534
0
}
535
536
static PyObject *
537
bytearray_subscript_lock_held(PyObject *op, PyObject *index)
538
512k
{
539
512k
    _Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED(op);
540
512k
    PyByteArrayObject *self = _PyByteArray_CAST(op);
541
512k
    if (_PyIndex_Check(index)) {
542
0
        Py_ssize_t i = PyNumber_AsSsize_t(index, PyExc_IndexError);
543
544
0
        if (i == -1 && PyErr_Occurred())
545
0
            return NULL;
546
547
0
        if (i < 0)
548
0
            i += PyByteArray_GET_SIZE(self);
549
550
0
        if (i < 0 || i >= Py_SIZE(self)) {
551
0
            PyErr_SetString(PyExc_IndexError, "bytearray index out of range");
552
0
            return NULL;
553
0
        }
554
0
        return _PyLong_FromUnsignedChar((unsigned char)(self->ob_start[i]));
555
0
    }
556
512k
    else if (PySlice_Check(index)) {
557
512k
        Py_ssize_t start, stop, step, slicelength, i;
558
512k
        size_t cur;
559
512k
        if (PySlice_Unpack(index, &start, &stop, &step) < 0) {
560
0
            return NULL;
561
0
        }
562
512k
        slicelength = PySlice_AdjustIndices(PyByteArray_GET_SIZE(self),
563
512k
                                            &start, &stop, step);
564
565
512k
        if (slicelength <= 0)
566
0
            return PyByteArray_FromStringAndSize("", 0);
567
512k
        else if (step == 1) {
568
455k
            return PyByteArray_FromStringAndSize(
569
455k
                PyByteArray_AS_STRING(self) + start, slicelength);
570
455k
        }
571
56.9k
        else {
572
56.9k
            char *source_buf = PyByteArray_AS_STRING(self);
573
56.9k
            char *result_buf;
574
56.9k
            PyObject *result;
575
576
56.9k
            result = PyByteArray_FromStringAndSize(NULL, slicelength);
577
56.9k
            if (result == NULL)
578
0
                return NULL;
579
580
56.9k
            result_buf = PyByteArray_AS_STRING(result);
581
14.6M
            for (cur = start, i = 0; i < slicelength;
582
14.5M
                 cur += step, i++) {
583
14.5M
                     result_buf[i] = source_buf[cur];
584
14.5M
            }
585
56.9k
            return result;
586
56.9k
        }
587
512k
    }
588
0
    else {
589
0
        PyErr_Format(PyExc_TypeError,
590
0
                     "bytearray indices must be integers or slices, not %.200s",
591
0
                     Py_TYPE(index)->tp_name);
592
0
        return NULL;
593
0
    }
594
512k
}
595
596
static PyObject *
597
bytearray_subscript(PyObject *op, PyObject *index)
598
512k
{
599
512k
    PyObject *ret;
600
512k
    Py_BEGIN_CRITICAL_SECTION(op);
601
512k
    ret = bytearray_subscript_lock_held(op, index);
602
512k
    Py_END_CRITICAL_SECTION();
603
512k
    return ret;
604
605
512k
}
606
607
static int
608
bytearray_setslice_linear(PyByteArrayObject *self,
609
                          Py_ssize_t lo, Py_ssize_t hi,
610
                          char *bytes, Py_ssize_t bytes_len)
611
197k
{
612
197k
    _Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED(self);
613
197k
    Py_ssize_t avail = hi - lo;
614
197k
    char *buf = PyByteArray_AS_STRING(self);
615
197k
    Py_ssize_t growth = bytes_len - avail;
616
197k
    int res = 0;
617
197k
    assert(avail >= 0);
618
619
197k
    if (growth < 0) {
620
0
        if (!_canresize(self))
621
0
            return -1;
622
623
0
        if (lo == 0) {
624
            /* Shrink the buffer by advancing its logical start */
625
0
            self->ob_start -= growth;
626
            /*
627
              0   lo               hi             old_size
628
              |   |<----avail----->|<-----tail------>|
629
              |      |<-bytes_len->|<-----tail------>|
630
              0    new_lo         new_hi          new_size
631
            */
632
0
        }
633
0
        else {
634
            /*
635
              0   lo               hi               old_size
636
              |   |<----avail----->|<-----tomove------>|
637
              |   |<-bytes_len->|<-----tomove------>|
638
              0   lo         new_hi              new_size
639
            */
640
0
            memmove(buf + lo + bytes_len, buf + hi,
641
0
                    Py_SIZE(self) - hi);
642
0
        }
643
0
        if (bytearray_resize_lock_held((PyObject *)self,
644
0
                               Py_SIZE(self) + growth) < 0) {
645
            /* Issue #19578: Handling the memory allocation failure here is
646
               tricky here because the bytearray object has already been
647
               modified. Depending on growth and lo, the behaviour is
648
               different.
649
650
               If growth < 0 and lo != 0, the operation is completed, but a
651
               MemoryError is still raised and the memory block is not
652
               shrunk. Otherwise, the bytearray is restored in its previous
653
               state and a MemoryError is raised. */
654
0
            if (lo == 0) {
655
0
                self->ob_start += growth;
656
0
                return -1;
657
0
            }
658
            /* memmove() removed bytes, the bytearray object cannot be
659
               restored in its previous state. */
660
0
            Py_SET_SIZE(self, Py_SIZE(self) + growth);
661
0
            res = -1;
662
0
        }
663
0
        buf = PyByteArray_AS_STRING(self);
664
0
    }
665
197k
    else if (growth > 0) {
666
197k
        if (Py_SIZE(self) > PyByteArray_SIZE_MAX - growth) {
667
0
            PyErr_NoMemory();
668
0
            return -1;
669
0
        }
670
671
197k
        if (bytearray_resize_lock_held((PyObject *)self,
672
197k
                               Py_SIZE(self) + growth) < 0) {
673
0
            return -1;
674
0
        }
675
197k
        buf = PyByteArray_AS_STRING(self);
676
        /* Make the place for the additional bytes */
677
        /*
678
          0   lo        hi               old_size
679
          |   |<-avail->|<-----tomove------>|
680
          |   |<---bytes_len-->|<-----tomove------>|
681
          0   lo            new_hi              new_size
682
         */
683
197k
        memmove(buf + lo + bytes_len, buf + hi,
684
197k
                Py_SIZE(self) - lo - bytes_len);
685
197k
    }
686
687
197k
    if (bytes_len > 0)
688
197k
        memcpy(buf + lo, bytes, bytes_len);
689
197k
    return res;
690
197k
}
691
692
static int
693
bytearray_setslice(PyByteArrayObject *self, Py_ssize_t lo, Py_ssize_t hi,
694
               PyObject *values)
695
197k
{
696
197k
    _Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED(self);
697
197k
    Py_ssize_t needed;
698
197k
    void *bytes;
699
197k
    Py_buffer vbytes;
700
197k
    int res = 0;
701
702
197k
    vbytes.len = -1;
703
197k
    if (values == (PyObject *)self) {
704
        /* Make a copy and call this function recursively */
705
0
        int err;
706
0
        values = PyByteArray_FromStringAndSize(PyByteArray_AS_STRING(values),
707
0
                                               PyByteArray_GET_SIZE(values));
708
0
        if (values == NULL)
709
0
            return -1;
710
0
        err = bytearray_setslice(self, lo, hi, values);
711
0
        Py_DECREF(values);
712
0
        return err;
713
0
    }
714
197k
    if (values == NULL) {
715
        /* del b[lo:hi] */
716
0
        bytes = NULL;
717
0
        needed = 0;
718
0
    }
719
197k
    else {
720
197k
        if (PyObject_GetBuffer(values, &vbytes, PyBUF_SIMPLE) != 0) {
721
0
            PyErr_Format(PyExc_TypeError,
722
0
                         "can't set bytearray slice from %.100s",
723
0
                         Py_TYPE(values)->tp_name);
724
0
            return -1;
725
0
        }
726
197k
        needed = vbytes.len;
727
197k
        bytes = vbytes.buf;
728
197k
    }
729
730
    // gh-153578: __buffer__() may have resized self; re-clamp both bounds.
731
197k
    if (lo < 0)
732
0
        lo = 0;
733
197k
    else if (lo > Py_SIZE(self))
734
0
        lo = Py_SIZE(self);
735
197k
    if (hi < lo)
736
0
        hi = lo;
737
197k
    if (hi > Py_SIZE(self))
738
0
        hi = Py_SIZE(self);
739
740
197k
    res = bytearray_setslice_linear(self, lo, hi, bytes, needed);
741
197k
    if (vbytes.len != -1)
742
197k
        PyBuffer_Release(&vbytes);
743
197k
    return res;
744
197k
}
745
746
static int
747
bytearray_setitem_lock_held(PyObject *op, Py_ssize_t i, PyObject *value)
748
0
{
749
0
    _Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED(op);
750
0
    PyByteArrayObject *self = _PyByteArray_CAST(op);
751
752
    // GH-91153: We need to do this *before* the size check, in case value has a
753
    // nasty __index__ method that changes the size of the bytearray:
754
0
    int ival = -1;
755
0
    if (value && !_getbytevalue(value, &ival)) {
756
0
        return -1;
757
0
    }
758
759
0
    if (i < 0) {
760
0
        i += Py_SIZE(self);
761
0
    }
762
763
0
    if (i < 0 || i >= Py_SIZE(self)) {
764
0
        PyErr_SetString(PyExc_IndexError, "bytearray index out of range");
765
0
        return -1;
766
0
    }
767
768
0
    if (value == NULL) {
769
0
        return bytearray_setslice(self, i, i+1, NULL);
770
0
    }
771
772
0
    assert(0 <= ival && ival < 256);
773
0
    PyByteArray_AS_STRING(self)[i] = ival;
774
0
    return 0;
775
0
}
776
777
static int
778
bytearray_setitem(PyObject *op, Py_ssize_t i, PyObject *value)
779
0
{
780
0
    int ret;
781
0
    Py_BEGIN_CRITICAL_SECTION(op);
782
0
    ret = bytearray_setitem_lock_held(op, i, value);
783
0
    Py_END_CRITICAL_SECTION();
784
0
    return ret;
785
0
}
786
787
static int
788
bytearray_ass_subscript_lock_held(PyObject *op, PyObject *index, PyObject *values)
789
11.4M
{
790
11.4M
    _Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED(op);
791
11.4M
    PyByteArrayObject *self = _PyByteArray_CAST(op);
792
0
    Py_ssize_t start, stop, step, slicelen;
793
    // Do not store a reference to the internal buffer since
794
    // index.__index__() or _getbytevalue() may alter 'self'.
795
    // See https://github.com/python/cpython/issues/91153.
796
797
11.4M
    if (_PyIndex_Check(index)) {
798
11.4M
        Py_ssize_t i = PyNumber_AsSsize_t(index, PyExc_IndexError);
799
800
11.4M
        if (i == -1 && PyErr_Occurred()) {
801
0
            return -1;
802
0
        }
803
804
11.4M
        int ival = -1;
805
806
        // GH-91153: We need to do this *before* the size check, in case values
807
        // has a nasty __index__ method that changes the size of the bytearray:
808
11.4M
        if (values && !_getbytevalue(values, &ival)) {
809
0
            return -1;
810
0
        }
811
812
11.4M
        if (i < 0) {
813
0
            i += PyByteArray_GET_SIZE(self);
814
0
        }
815
816
11.4M
        if (i < 0 || i >= Py_SIZE(self)) {
817
2
            PyErr_SetString(PyExc_IndexError, "bytearray index out of range");
818
2
            return -1;
819
2
        }
820
821
11.4M
        if (values == NULL) {
822
            /* Fall through to slice assignment */
823
0
            start = i;
824
0
            stop = i + 1;
825
0
            step = 1;
826
0
            slicelen = 1;
827
0
        }
828
11.4M
        else {
829
11.4M
            assert(0 <= ival && ival < 256);
830
11.4M
            PyByteArray_AS_STRING(self)[i] = (char)ival;
831
11.4M
            return 0;
832
11.4M
        }
833
11.4M
    }
834
0
    else if (PySlice_Check(index)) {
835
0
        if (PySlice_Unpack(index, &start, &stop, &step) < 0) {
836
0
            return -1;
837
0
        }
838
0
        slicelen = PySlice_AdjustIndices(PyByteArray_GET_SIZE(self), &start,
839
0
                                         &stop, step);
840
0
    }
841
0
    else {
842
0
        PyErr_Format(PyExc_TypeError,
843
0
                     "bytearray indices must be integers or slices, not %.200s",
844
0
                      Py_TYPE(index)->tp_name);
845
0
        return -1;
846
0
    }
847
848
0
    char *bytes;
849
0
    Py_ssize_t needed;
850
0
    if (values == NULL) {
851
0
        bytes = NULL;
852
0
        needed = 0;
853
0
    }
854
0
    else if (values == (PyObject *)self || !PyByteArray_Check(values)) {
855
0
        int err;
856
0
        if (PyNumber_Check(values) || PyUnicode_Check(values)) {
857
0
            PyErr_SetString(PyExc_TypeError,
858
0
                            "can assign only bytes, buffers, or iterables "
859
0
                            "of ints in range(0, 256)");
860
0
            return -1;
861
0
        }
862
        /* Make a copy and call this function recursively */
863
0
        values = PyByteArray_FromObject(values);
864
0
        if (values == NULL)
865
0
            return -1;
866
0
        err = bytearray_ass_subscript_lock_held((PyObject*)self, index, values);
867
0
        Py_DECREF(values);
868
0
        return err;
869
0
    }
870
0
    else {
871
0
        assert(PyByteArray_Check(values));
872
0
        bytes = PyByteArray_AS_STRING(values);
873
0
        needed = Py_SIZE(values);
874
0
    }
875
876
    /* Make sure b[5:2] = ... inserts before 5, not before 2. */
877
0
    if ((step < 0 && start < stop) ||
878
0
        (step > 0 && start > stop))
879
0
    {
880
0
        stop = start;
881
0
    }
882
883
0
    if (step == 1) {
884
0
        return bytearray_setslice_linear(self, start, stop, bytes, needed);
885
0
    }
886
0
    else {
887
0
        if (needed == 0) {
888
            /* Delete slice */
889
0
            size_t cur;
890
0
            Py_ssize_t i;
891
0
            char *buf = PyByteArray_AS_STRING(self);
892
893
0
            if (!_canresize(self))
894
0
                return -1;
895
896
0
            if (slicelen == 0)
897
                /* Nothing to do here. */
898
0
                return 0;
899
900
0
            if (step < 0) {
901
0
                stop = start + 1;
902
0
                start = stop + step * (slicelen - 1) - 1;
903
0
                step = -step;
904
0
            }
905
0
            for (cur = start, i = 0;
906
0
                 i < slicelen; cur += step, i++) {
907
0
                Py_ssize_t lim = step - 1;
908
909
0
                if (cur + step >= (size_t)PyByteArray_GET_SIZE(self))
910
0
                    lim = PyByteArray_GET_SIZE(self) - cur - 1;
911
912
0
                memmove(buf + cur - i,
913
0
                        buf + cur + 1, lim);
914
0
            }
915
            /* Move the tail of the bytes, in one chunk */
916
0
            cur = start + (size_t)slicelen*step;
917
0
            if (cur < (size_t)PyByteArray_GET_SIZE(self)) {
918
0
                memmove(buf + cur - slicelen,
919
0
                        buf + cur,
920
0
                        PyByteArray_GET_SIZE(self) - cur);
921
0
            }
922
0
            if (bytearray_resize_lock_held((PyObject *)self,
923
0
                               PyByteArray_GET_SIZE(self) - slicelen) < 0)
924
0
                return -1;
925
926
0
            return 0;
927
0
        }
928
0
        else {
929
            /* Assign slice */
930
0
            Py_ssize_t i;
931
0
            size_t cur;
932
0
            char *buf = PyByteArray_AS_STRING(self);
933
934
0
            if (needed != slicelen) {
935
0
                PyErr_Format(PyExc_ValueError,
936
0
                             "attempt to assign bytes of size %zd "
937
0
                             "to extended slice of size %zd",
938
0
                             needed, slicelen);
939
0
                return -1;
940
0
            }
941
0
            for (cur = start, i = 0; i < slicelen; cur += step, i++)
942
0
                buf[cur] = bytes[i];
943
0
            return 0;
944
0
        }
945
0
    }
946
0
}
947
948
static int
949
bytearray_ass_subscript(PyObject *op, PyObject *index, PyObject *values)
950
11.4M
{
951
11.4M
    int ret;
952
11.4M
    if (values != NULL && PyByteArray_Check(values)) {
953
0
        Py_BEGIN_CRITICAL_SECTION2(op, values);
954
0
        ret = bytearray_ass_subscript_lock_held(op, index, values);
955
0
        Py_END_CRITICAL_SECTION2();
956
0
    }
957
11.4M
    else {
958
11.4M
        Py_BEGIN_CRITICAL_SECTION(op);
959
11.4M
        ret = bytearray_ass_subscript_lock_held(op, index, values);
960
11.4M
        Py_END_CRITICAL_SECTION();
961
11.4M
    }
962
11.4M
    return ret;
963
11.4M
}
964
965
static PyObject *
966
bytearray_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
967
366k
{
968
366k
    PyObject *op = PyType_GenericNew(type, args, kwds);
969
366k
    if (op == NULL) {
970
0
        return NULL;
971
0
    }
972
366k
    PyByteArrayObject *self = _PyByteArray_CAST(op);
973
366k
    self->ob_bytes_object = Py_GetConstant(Py_CONSTANT_EMPTY_BYTES);
974
366k
    bytearray_reinit_from_bytes(self, 0);
975
366k
    self->ob_exports = 0;
976
366k
    return op;
977
366k
}
978
979
/*[clinic input]
980
bytearray.__init__
981
982
    source as arg: object = NULL
983
    encoding: str = NULL
984
    errors: str = NULL
985
986
[clinic start generated code]*/
987
988
static int
989
bytearray___init___impl(PyByteArrayObject *self, PyObject *arg,
990
                        const char *encoding, const char *errors)
991
/*[clinic end generated code: output=4ce1304649c2f8b3 input=1141a7122eefd7b9]*/
992
366k
{
993
366k
    Py_ssize_t count;
994
366k
    PyObject *it;
995
366k
    PyObject *(*iternext)(PyObject *);
996
997
    /* Disallow any __init__ call if the object is not resizable (has exports)
998
       to make the handling of non-null `source` init values simpler. */
999
366k
    if (!_canresize(self)) {
1000
0
        return -1;
1001
0
    }
1002
1003
    /* Empty any previous contents (do this first of all!). */
1004
366k
    if (PyByteArray_Resize((PyObject *)self, 0) < 0) {
1005
0
        return -1;
1006
0
    }
1007
366k
    assert(self->ob_bytes_object == Py_GetConstantBorrowed(Py_CONSTANT_EMPTY_BYTES));
1008
366k
    assert(self->ob_exports == 0);
1009
1010
    /* Make a quick exit if no first argument */
1011
366k
    if (arg == NULL) {
1012
237k
        if (encoding != NULL || errors != NULL) {
1013
0
            PyErr_SetString(PyExc_TypeError,
1014
0
                            encoding != NULL ?
1015
0
                            "encoding without a string argument" :
1016
0
                            "errors without a string argument");
1017
0
            return -1;
1018
0
        }
1019
237k
        return 0;
1020
237k
    }
1021
1022
129k
    if (PyUnicode_Check(arg)) {
1023
        /* Encode via the codec registry */
1024
0
        PyObject *encoded, *new;
1025
0
        if (encoding == NULL) {
1026
0
            PyErr_SetString(PyExc_TypeError,
1027
0
                            "string argument without an encoding");
1028
0
            return -1;
1029
0
        }
1030
0
        encoded = PyUnicode_AsEncodedString(arg, encoding, errors);
1031
0
        if (encoded == NULL) {
1032
0
            return -1;
1033
0
        }
1034
0
        assert(PyBytes_Check(encoded));
1035
1036
        /* Most encodes return a new unique bytes, just use it as buffer. */
1037
0
        if (_PyObject_IsUniquelyReferenced(encoded)
1038
0
            && PyBytes_CheckExact(encoded)
1039
0
            && _PyBytes_GET_CACHED_HASH((PyBytesObject*)encoded) == -1)
1040
0
        {
1041
0
            Py_ssize_t size = PyBytes_GET_SIZE(encoded);
1042
0
            self->ob_bytes_object = encoded;
1043
0
            bytearray_reinit_from_bytes(self, size);
1044
0
            return 0;
1045
0
        }
1046
0
        new = bytearray_iconcat((PyObject*)self, encoded);
1047
0
        Py_DECREF(encoded);
1048
0
        if (new == NULL)
1049
0
            return -1;
1050
0
        Py_DECREF(new);
1051
0
        return 0;
1052
0
    }
1053
1054
    /* If it's not unicode, there can't be encoding or errors */
1055
129k
    if (encoding != NULL || errors != NULL) {
1056
0
        PyErr_SetString(PyExc_TypeError,
1057
0
                        encoding != NULL ?
1058
0
                        "encoding without a string argument" :
1059
0
                        "errors without a string argument");
1060
0
        return -1;
1061
0
    }
1062
1063
    /* Is it an int? */
1064
129k
    if (_PyIndex_Check(arg)) {
1065
129k
        count = PyNumber_AsSsize_t(arg, PyExc_OverflowError);
1066
129k
        if (count == -1 && PyErr_Occurred()) {
1067
0
            if (!PyErr_ExceptionMatches(PyExc_TypeError))
1068
0
                return -1;
1069
0
            PyErr_Clear();  /* fall through */
1070
0
        }
1071
129k
        else {
1072
129k
            if (count < 0) {
1073
0
                PyErr_SetString(PyExc_ValueError, "negative count");
1074
0
                return -1;
1075
0
            }
1076
129k
            if (count > 0) {
1077
129k
                if (PyByteArray_Resize((PyObject *)self, count))
1078
0
                    return -1;
1079
129k
                memset(PyByteArray_AS_STRING(self), 0, count);
1080
129k
            }
1081
129k
            return 0;
1082
129k
        }
1083
129k
    }
1084
1085
    /* Use the buffer API */
1086
0
    if (PyObject_CheckBuffer(arg)) {
1087
0
        Py_ssize_t size;
1088
0
        Py_buffer view;
1089
0
        if (PyObject_GetBuffer(arg, &view, PyBUF_FULL_RO) < 0)
1090
0
            return -1;
1091
0
        size = view.len;
1092
0
        if (PyByteArray_Resize((PyObject *)self, size) < 0) goto fail;
1093
0
        if (PyBuffer_ToContiguous(PyByteArray_AS_STRING(self),
1094
0
            &view, size, 'C') < 0)
1095
0
            goto fail;
1096
0
        PyBuffer_Release(&view);
1097
0
        return 0;
1098
0
    fail:
1099
0
        PyBuffer_Release(&view);
1100
0
        return -1;
1101
0
    }
1102
1103
0
    if (PyList_CheckExact(arg) || PyTuple_CheckExact(arg)) {
1104
0
        Py_ssize_t size = PySequence_Fast_GET_SIZE(arg);
1105
0
        if (PyByteArray_Resize((PyObject *)self, size) < 0) {
1106
0
            return -1;
1107
0
        }
1108
0
        PyObject **items = PySequence_Fast_ITEMS(arg);
1109
0
        char *s = PyByteArray_AS_STRING(self);
1110
0
        for (Py_ssize_t i = 0; i < size; i++) {
1111
0
            int value;
1112
0
            if (!PyLong_CheckExact(items[i])) {
1113
                /* Resize to 0 and go through slowpath */
1114
0
                if (Py_SIZE(self) != 0) {
1115
0
                   if (PyByteArray_Resize((PyObject *)self, 0) < 0) {
1116
0
                       return -1;
1117
0
                   }
1118
0
                }
1119
0
                goto slowpath;
1120
0
            }
1121
0
            int rc = _getbytevalue(items[i], &value);
1122
0
            if (!rc) {
1123
0
                return -1;
1124
0
            }
1125
0
            s[i] = value;
1126
0
        }
1127
0
        return 0;
1128
0
    }
1129
0
slowpath:
1130
    /* Get the iterator */
1131
0
    it = PyObject_GetIter(arg);
1132
0
    if (it == NULL) {
1133
0
        if (PyErr_ExceptionMatches(PyExc_TypeError)) {
1134
0
            PyErr_Format(PyExc_TypeError,
1135
0
                         "cannot convert '%.200s' object to bytearray",
1136
0
                         Py_TYPE(arg)->tp_name);
1137
0
        }
1138
0
        return -1;
1139
0
    }
1140
0
    iternext = *Py_TYPE(it)->tp_iternext;
1141
1142
    /* Run the iterator to exhaustion */
1143
0
    for (;;) {
1144
0
        PyObject *item;
1145
0
        int rc, value;
1146
1147
        /* Get the next item */
1148
0
        item = iternext(it);
1149
0
        if (item == NULL) {
1150
0
            if (PyErr_Occurred()) {
1151
0
                if (!PyErr_ExceptionMatches(PyExc_StopIteration))
1152
0
                    goto error;
1153
0
                PyErr_Clear();
1154
0
            }
1155
0
            break;
1156
0
        }
1157
1158
        /* Interpret it as an int (__index__) */
1159
0
        rc = _getbytevalue(item, &value);
1160
0
        Py_DECREF(item);
1161
0
        if (!rc)
1162
0
            goto error;
1163
1164
        /* Append the byte */
1165
0
        if (Py_SIZE(self) + 1 < self->ob_alloc) {
1166
0
            Py_SET_SIZE(self, Py_SIZE(self) + 1);
1167
0
            bytearray_write_trailing_null_byte(self);
1168
0
        }
1169
0
        else if (PyByteArray_Resize((PyObject *)self, Py_SIZE(self)+1) < 0)
1170
0
            goto error;
1171
0
        PyByteArray_AS_STRING(self)[Py_SIZE(self)-1] = value;
1172
0
    }
1173
1174
    /* Clean up and return success */
1175
0
    Py_DECREF(it);
1176
0
    return 0;
1177
1178
0
 error:
1179
    /* Error handling when it != NULL */
1180
0
    Py_DECREF(it);
1181
0
    return -1;
1182
0
}
1183
1184
static PyObject *
1185
bytearray_repr_lock_held(PyObject *op)
1186
0
{
1187
0
    _Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED(op);
1188
0
    const char *className = _PyType_Name(Py_TYPE(op));
1189
0
    PyObject *bytes_repr = _Py_bytes_repr(PyByteArray_AS_STRING(op),
1190
0
                                          PyByteArray_GET_SIZE(op), 1,
1191
0
                                          "bytearray");
1192
0
    if (bytes_repr == NULL) {
1193
0
        return NULL;
1194
0
    }
1195
0
    PyObject *res = PyUnicode_FromFormat("%s(%U)", className, bytes_repr);
1196
0
    Py_DECREF(bytes_repr);
1197
0
    return res;
1198
0
}
1199
1200
static PyObject *
1201
bytearray_repr(PyObject *op)
1202
0
{
1203
0
    PyObject *ret;
1204
0
    Py_BEGIN_CRITICAL_SECTION(op);
1205
0
    ret = bytearray_repr_lock_held(op);
1206
0
    Py_END_CRITICAL_SECTION();
1207
0
    return ret;
1208
0
}
1209
1210
static PyObject *
1211
bytearray_str(PyObject *op)
1212
0
{
1213
0
    if (_Py_GetConfig()->bytes_warning) {
1214
0
        if (PyErr_WarnEx(PyExc_BytesWarning,
1215
0
                         "str() on a bytearray instance", 1)) {
1216
0
                return NULL;
1217
0
        }
1218
0
    }
1219
0
    return bytearray_repr(op);
1220
0
}
1221
1222
static PyObject *
1223
bytearray_richcompare(PyObject *self, PyObject *other, int op)
1224
0
{
1225
0
    Py_ssize_t self_size, other_size;
1226
0
    Py_buffer self_bytes, other_bytes;
1227
0
    int cmp;
1228
1229
0
    if (!PyObject_CheckBuffer(self) || !PyObject_CheckBuffer(other)) {
1230
0
        if (PyUnicode_Check(self) || PyUnicode_Check(other)) {
1231
0
            if (_Py_GetConfig()->bytes_warning && (op == Py_EQ || op == Py_NE)) {
1232
0
                if (PyErr_WarnEx(PyExc_BytesWarning,
1233
0
                                "Comparison between bytearray and string", 1))
1234
0
                    return NULL;
1235
0
            }
1236
0
        }
1237
0
        Py_RETURN_NOTIMPLEMENTED;
1238
0
    }
1239
1240
    /* Bytearrays can be compared to anything that supports the buffer API. */
1241
0
    if (PyObject_GetBuffer(self, &self_bytes, PyBUF_SIMPLE) != 0) {
1242
0
        PyErr_Clear();
1243
0
        Py_RETURN_NOTIMPLEMENTED;
1244
0
    }
1245
0
    self_size = self_bytes.len;
1246
1247
0
    if (PyObject_GetBuffer(other, &other_bytes, PyBUF_SIMPLE) != 0) {
1248
0
        PyErr_Clear();
1249
0
        PyBuffer_Release(&self_bytes);
1250
0
        Py_RETURN_NOTIMPLEMENTED;
1251
0
    }
1252
0
    other_size = other_bytes.len;
1253
1254
0
    if (self_size != other_size && (op == Py_EQ || op == Py_NE)) {
1255
        /* Shortcut: if the lengths differ, the objects differ */
1256
0
        PyBuffer_Release(&self_bytes);
1257
0
        PyBuffer_Release(&other_bytes);
1258
0
        return PyBool_FromLong((op == Py_NE));
1259
0
    }
1260
0
    else {
1261
0
        cmp = memcmp(self_bytes.buf, other_bytes.buf,
1262
0
                     Py_MIN(self_size, other_size));
1263
        /* In ISO C, memcmp() guarantees to use unsigned bytes! */
1264
1265
0
        PyBuffer_Release(&self_bytes);
1266
0
        PyBuffer_Release(&other_bytes);
1267
1268
0
        if (cmp != 0) {
1269
0
            Py_RETURN_RICHCOMPARE(cmp, 0, op);
1270
0
        }
1271
1272
0
        Py_RETURN_RICHCOMPARE(self_size, other_size, op);
1273
0
    }
1274
1275
0
}
1276
1277
static void
1278
bytearray_dealloc(PyObject *op)
1279
938k
{
1280
938k
    PyByteArrayObject *self = _PyByteArray_CAST(op);
1281
#ifdef Py_DEBUG
1282
    if (self->ob_bytes_object != NULL) {
1283
        _PyBytes_CheckOverflow(self->ob_bytes_object, op, "bytearray");
1284
    }
1285
#endif
1286
1287
938k
    if (self->ob_exports > 0) {
1288
0
        PyErr_SetString(PyExc_SystemError,
1289
0
                        "deallocated bytearray object has exported buffers");
1290
0
        PyErr_Print();
1291
0
    }
1292
938k
    Py_XDECREF(self->ob_bytes_object);
1293
938k
    Py_TYPE(self)->tp_free((PyObject *)self);
1294
938k
}
1295
1296
1297
/* -------------------------------------------------------------------- */
1298
/* Methods */
1299
1300
#define STRINGLIB_IS_UNICODE 0
1301
0
#define FASTSEARCH fastsearch
1302
0
#define STRINGLIB(F) stringlib_##F
1303
0
#define STRINGLIB_CHAR char
1304
0
#define STRINGLIB_SIZEOF_CHAR 1
1305
0
#define STRINGLIB_LEN PyByteArray_GET_SIZE
1306
0
#define STRINGLIB_STR PyByteArray_AS_STRING
1307
0
#define STRINGLIB_NEW PyByteArray_FromStringAndSize
1308
0
#define STRINGLIB_ISSPACE Py_ISSPACE
1309
0
#define STRINGLIB_ISLINEBREAK(x) ((x == '\n') || (x == '\r'))
1310
#define STRINGLIB_CHECK_EXACT PyByteArray_CheckExact
1311
0
#define STRINGLIB_FAST_MEMCHR memchr
1312
#define STRINGLIB_MUTABLE 1
1313
1314
#include "stringlib/fastsearch.h"
1315
#include "stringlib/count.h"
1316
#include "stringlib/find.h"
1317
#include "stringlib/join.h"
1318
#include "stringlib/partition.h"
1319
#include "stringlib/split.h"
1320
#include "stringlib/ctype.h"
1321
#include "stringlib/transmogrify.h"
1322
1323
1324
/*[clinic input]
1325
@permit_long_summary
1326
@critical_section
1327
@text_signature "($self, sub[, start[, end]], /)"
1328
bytearray.find
1329
1330
    sub: object
1331
    start: slice_index(accept={int, NoneType}, c_default='0') = None
1332
         Optional start position. Default: start of the bytes.
1333
    end: slice_index(accept={int, NoneType}, c_default='PY_SSIZE_T_MAX') = None
1334
         Optional stop position. Default: end of the bytes.
1335
    /
1336
1337
Return the lowest index in B where subsection 'sub' is found, such that 'sub' is contained within B[start:end].
1338
1339
Return -1 on failure.
1340
[clinic start generated code]*/
1341
1342
static PyObject *
1343
bytearray_find_impl(PyByteArrayObject *self, PyObject *sub, Py_ssize_t start,
1344
                    Py_ssize_t end)
1345
/*[clinic end generated code: output=413e1cab2ae87da0 input=df3aa94840d893a7]*/
1346
636k
{
1347
636k
    return _bytearray_with_buffer(self, _Py_bytes_find, sub, start, end);
1348
636k
}
1349
1350
/*[clinic input]
1351
@permit_long_summary
1352
@critical_section
1353
bytearray.count = bytearray.find
1354
1355
Return the number of non-overlapping occurrences of subsection 'sub' in bytes B[start:end].
1356
[clinic start generated code]*/
1357
1358
static PyObject *
1359
bytearray_count_impl(PyByteArrayObject *self, PyObject *sub,
1360
                     Py_ssize_t start, Py_ssize_t end)
1361
/*[clinic end generated code: output=a21ee2692e4f1233 input=e8fcdca8272857e0]*/
1362
0
{
1363
0
    return _bytearray_with_buffer(self, _Py_bytes_count, sub, start, end);
1364
0
}
1365
1366
/*[clinic input]
1367
bytearray.clear
1368
1369
Remove all items from the bytearray.
1370
[clinic start generated code]*/
1371
1372
static PyObject *
1373
bytearray_clear_impl(PyByteArrayObject *self)
1374
/*[clinic end generated code: output=85c2fe6aede0956c input=ed6edae9de447ac4]*/
1375
0
{
1376
0
    if (PyByteArray_Resize((PyObject *)self, 0) < 0)
1377
0
        return NULL;
1378
0
    Py_RETURN_NONE;
1379
0
}
1380
1381
/*[clinic input]
1382
@critical_section
1383
bytearray.copy
1384
1385
Return a copy of B.
1386
[clinic start generated code]*/
1387
1388
static PyObject *
1389
bytearray_copy_impl(PyByteArrayObject *self)
1390
/*[clinic end generated code: output=68cfbcfed484c132 input=b96f8b01f73851ad]*/
1391
0
{
1392
0
    return PyByteArray_FromStringAndSize(PyByteArray_AS_STRING((PyObject *)self),
1393
0
                                         PyByteArray_GET_SIZE(self));
1394
0
}
1395
1396
/*[clinic input]
1397
@permit_long_summary
1398
@critical_section
1399
bytearray.index = bytearray.find
1400
1401
Return the lowest index in B where subsection 'sub' is found, such that 'sub' is contained within B[start:end].
1402
1403
Raise ValueError if the subsection is not found.
1404
[clinic start generated code]*/
1405
1406
static PyObject *
1407
bytearray_index_impl(PyByteArrayObject *self, PyObject *sub,
1408
                     Py_ssize_t start, Py_ssize_t end)
1409
/*[clinic end generated code: output=067a1e78efc672a7 input=c37f177cfee19fe4]*/
1410
0
{
1411
0
    return _bytearray_with_buffer(self, _Py_bytes_index, sub, start, end);
1412
0
}
1413
1414
/*[clinic input]
1415
@permit_long_summary
1416
@critical_section
1417
bytearray.rfind = bytearray.find
1418
1419
Return the highest index in B where subsection 'sub' is found, such that 'sub' is contained within B[start:end].
1420
1421
Return -1 on failure.
1422
[clinic start generated code]*/
1423
1424
static PyObject *
1425
bytearray_rfind_impl(PyByteArrayObject *self, PyObject *sub,
1426
                     Py_ssize_t start, Py_ssize_t end)
1427
/*[clinic end generated code: output=51bf886f932b283c input=1265b11c437d2750]*/
1428
0
{
1429
0
    return _bytearray_with_buffer(self, _Py_bytes_rfind, sub, start, end);
1430
0
}
1431
1432
/*[clinic input]
1433
@permit_long_summary
1434
@critical_section
1435
bytearray.rindex = bytearray.find
1436
1437
Return the highest index in B where subsection 'sub' is found, such that 'sub' is contained within B[start:end].
1438
1439
Raise ValueError if the subsection is not found.
1440
[clinic start generated code]*/
1441
1442
static PyObject *
1443
bytearray_rindex_impl(PyByteArrayObject *self, PyObject *sub,
1444
                      Py_ssize_t start, Py_ssize_t end)
1445
/*[clinic end generated code: output=38e1cf66bafb08b9 input=7d198b3d6b0a62ce]*/
1446
0
{
1447
0
    return _bytearray_with_buffer(self, _Py_bytes_rindex, sub, start, end);
1448
0
}
1449
1450
static int
1451
bytearray_contains(PyObject *self, PyObject *arg)
1452
0
{
1453
0
    int ret = -1;
1454
0
    Py_BEGIN_CRITICAL_SECTION(self);
1455
0
    PyByteArrayObject *ba = _PyByteArray_CAST(self);
1456
1457
    /* Increase exports to prevent bytearray storage from changing during _Py_bytes_contains(). */
1458
0
    ba->ob_exports++;
1459
0
    ret = _Py_bytes_contains(PyByteArray_AS_STRING(ba),
1460
0
                             PyByteArray_GET_SIZE(self),
1461
0
                             arg);
1462
0
    ba->ob_exports--;
1463
0
    Py_END_CRITICAL_SECTION();
1464
0
    return ret;
1465
0
}
1466
1467
/*[clinic input]
1468
@permit_long_summary
1469
@critical_section
1470
@text_signature "($self, prefix[, start[, end]], /)"
1471
bytearray.startswith
1472
1473
    prefix as subobj: object
1474
        A bytes or a tuple of bytes to try.
1475
    start: slice_index(accept={int, NoneType}, c_default='0') = None
1476
        Optional start position. Default: start of the bytearray.
1477
    end: slice_index(accept={int, NoneType}, c_default='PY_SSIZE_T_MAX') = None
1478
        Optional stop position. Default: end of the bytearray.
1479
    /
1480
1481
Return True if the bytearray starts with the specified prefix, False otherwise.
1482
[clinic start generated code]*/
1483
1484
static PyObject *
1485
bytearray_startswith_impl(PyByteArrayObject *self, PyObject *subobj,
1486
                          Py_ssize_t start, Py_ssize_t end)
1487
/*[clinic end generated code: output=a3d9b6d44d3662a6 input=93f9ffee684f109a]*/
1488
0
{
1489
0
    return _bytearray_with_buffer(self, _Py_bytes_startswith, subobj, start, end);
1490
0
}
1491
1492
/*[clinic input]
1493
@permit_long_summary
1494
@critical_section
1495
@text_signature "($self, suffix[, start[, end]], /)"
1496
bytearray.endswith
1497
1498
    suffix as subobj: object
1499
        A bytes or a tuple of bytes to try.
1500
    start: slice_index(accept={int, NoneType}, c_default='0') = None
1501
         Optional start position. Default: start of the bytearray.
1502
    end: slice_index(accept={int, NoneType}, c_default='PY_SSIZE_T_MAX') = None
1503
         Optional stop position. Default: end of the bytearray.
1504
    /
1505
1506
Return True if the bytearray ends with the specified suffix, False otherwise.
1507
[clinic start generated code]*/
1508
1509
static PyObject *
1510
bytearray_endswith_impl(PyByteArrayObject *self, PyObject *subobj,
1511
                        Py_ssize_t start, Py_ssize_t end)
1512
/*[clinic end generated code: output=e75ea8c227954caa input=d158b030a11d0b06]*/
1513
0
{
1514
0
    return _bytearray_with_buffer(self, _Py_bytes_endswith, subobj, start, end);
1515
0
}
1516
1517
/*[clinic input]
1518
@critical_section
1519
bytearray.removeprefix as bytearray_removeprefix
1520
1521
    prefix: Py_buffer
1522
    /
1523
1524
Return a bytearray with the given prefix string removed if present.
1525
1526
If the bytearray starts with the prefix string, return
1527
bytearray[len(prefix):].  Otherwise, return a copy of the original
1528
bytearray.
1529
[clinic start generated code]*/
1530
1531
static PyObject *
1532
bytearray_removeprefix_impl(PyByteArrayObject *self, Py_buffer *prefix)
1533
/*[clinic end generated code: output=6cabc585e7f502e0 input=4323ba6d275fe7a8]*/
1534
0
{
1535
0
    const char *self_start = PyByteArray_AS_STRING(self);
1536
0
    Py_ssize_t self_len = PyByteArray_GET_SIZE(self);
1537
0
    const char *prefix_start = prefix->buf;
1538
0
    Py_ssize_t prefix_len = prefix->len;
1539
1540
0
    if (self_len >= prefix_len
1541
0
        && memcmp(self_start, prefix_start, prefix_len) == 0)
1542
0
    {
1543
0
        return PyByteArray_FromStringAndSize(self_start + prefix_len,
1544
0
                                             self_len - prefix_len);
1545
0
    }
1546
1547
0
    return PyByteArray_FromStringAndSize(self_start, self_len);
1548
0
}
1549
1550
/*[clinic input]
1551
@critical_section
1552
bytearray.removesuffix as bytearray_removesuffix
1553
1554
    suffix: Py_buffer
1555
    /
1556
1557
Return a bytearray with the given suffix string removed if present.
1558
1559
If the bytearray ends with the suffix string and that suffix is not
1560
empty, return bytearray[:-len(suffix)].  Otherwise, return a copy of
1561
the original bytearray.
1562
[clinic start generated code]*/
1563
1564
static PyObject *
1565
bytearray_removesuffix_impl(PyByteArrayObject *self, Py_buffer *suffix)
1566
/*[clinic end generated code: output=2bc8cfb79de793d3 input=f71ba2e1a40c47dd]*/
1567
0
{
1568
0
    const char *self_start = PyByteArray_AS_STRING(self);
1569
0
    Py_ssize_t self_len = PyByteArray_GET_SIZE(self);
1570
0
    const char *suffix_start = suffix->buf;
1571
0
    Py_ssize_t suffix_len = suffix->len;
1572
1573
0
    if (self_len >= suffix_len
1574
0
        && memcmp(self_start + self_len - suffix_len,
1575
0
                  suffix_start, suffix_len) == 0)
1576
0
    {
1577
0
        return PyByteArray_FromStringAndSize(self_start,
1578
0
                                             self_len - suffix_len);
1579
0
    }
1580
1581
0
    return PyByteArray_FromStringAndSize(self_start, self_len);
1582
0
}
1583
1584
1585
/*[clinic input]
1586
@critical_section
1587
bytearray.resize
1588
    size: Py_ssize_t
1589
        New size to resize to.
1590
    /
1591
Resize the internal buffer of bytearray to len.
1592
[clinic start generated code]*/
1593
1594
static PyObject *
1595
bytearray_resize_impl(PyByteArrayObject *self, Py_ssize_t size)
1596
/*[clinic end generated code: output=f73524922990b2d9 input=116046316a2b5cfc]*/
1597
0
{
1598
0
    Py_ssize_t start_size = PyByteArray_GET_SIZE(self);
1599
0
    int result = bytearray_resize_lock_held((PyObject *)self, size);
1600
0
    if (result < 0) {
1601
0
        return NULL;
1602
0
    }
1603
    // Set new bytes to null bytes
1604
0
    if (size > start_size) {
1605
0
        memset(PyByteArray_AS_STRING(self) + start_size, 0, size - start_size);
1606
0
    }
1607
0
    Py_RETURN_NONE;
1608
0
}
1609
1610
1611
/*[clinic input]
1612
@critical_section
1613
bytearray.take_bytes
1614
    n: object = None
1615
        Bytes to take, negative indexes from end. None indicates all bytes.
1616
    /
1617
Take *n* bytes from the bytearray and return them as a bytes object.
1618
[clinic start generated code]*/
1619
1620
static PyObject *
1621
bytearray_take_bytes_impl(PyByteArrayObject *self, PyObject *n)
1622
/*[clinic end generated code: output=3147fbc0bbbe8d94 input=b15b5172cdc6deda]*/
1623
237k
{
1624
237k
    Py_ssize_t to_take;
1625
237k
    Py_ssize_t size = Py_SIZE(self);
1626
237k
    if (Py_IsNone(n)) {
1627
237k
        to_take = size;
1628
237k
    }
1629
    // Integer index, from start (zero, positive) or end (negative).
1630
0
    else if (_PyIndex_Check(n)) {
1631
0
        to_take = PyNumber_AsSsize_t(n, PyExc_IndexError);
1632
0
        if (to_take == -1 && PyErr_Occurred()) {
1633
0
            return NULL;
1634
0
        }
1635
        // n.__index__() may have resized self; use the current size.
1636
0
        size = Py_SIZE(self);
1637
0
        if (to_take < 0) {
1638
0
            to_take += size;
1639
0
        }
1640
0
    }
1641
0
    else {
1642
0
        PyErr_SetString(PyExc_TypeError, "n must be an integer or None");
1643
0
        return NULL;
1644
0
    }
1645
1646
237k
    if (to_take < 0 || to_take > size) {
1647
0
        PyErr_Format(PyExc_IndexError,
1648
0
            "can't take %zd bytes outside size %zd",
1649
0
            to_take, size);
1650
0
        return NULL;
1651
0
    }
1652
1653
    // Exports may change the contents. No mutable bytes allowed.
1654
237k
    if (!_canresize(self)) {
1655
0
        return NULL;
1656
0
    }
1657
1658
237k
    if (to_take == 0 || size == 0) {
1659
14.2k
        return Py_GetConstant(Py_CONSTANT_EMPTY_BYTES);
1660
14.2k
    }
1661
1662
223k
    Py_ssize_t remaining_length = size - to_take;
1663
1664
    // optimization: If taking less than leaving, just copy the small to_take
1665
    // portion out and move ob_start.
1666
223k
    if (to_take < remaining_length) {
1667
0
        PyObject *ret = PyBytes_FromStringAndSize(self->ob_start, to_take);
1668
0
        if (ret == NULL) {
1669
0
            return NULL;
1670
0
        }
1671
0
        self->ob_start += to_take;
1672
0
        Py_SET_SIZE(self, remaining_length);
1673
0
        return ret;
1674
0
    }
1675
1676
    // Copy remaining bytes to a new bytes. Allocate and then copy
1677
    // so we don't get a shared immortal one-character singleton!
1678
223k
    PyObject *remaining = PyBytes_FromStringAndSize(NULL, remaining_length);
1679
223k
    if (remaining == NULL) {
1680
0
        return NULL;
1681
0
    }
1682
223k
    memcpy(PyBytes_AS_STRING(remaining), self->ob_start + to_take,
1683
223k
           remaining_length);
1684
1685
223k
    if (bytearray_resize_storage(self, to_take, to_take) < 0) {
1686
0
        Py_DECREF(remaining);
1687
0
        return NULL;
1688
0
    }
1689
1690
    // Point the bytearray towards the buffer with the remaining data.
1691
223k
    PyObject *result = self->ob_bytes_object;
1692
223k
    self->ob_bytes_object = remaining;
1693
223k
    bytearray_reinit_from_bytes(self, remaining_length);
1694
223k
    return result;
1695
223k
}
1696
1697
1698
/*[clinic input]
1699
@permit_long_summary
1700
@critical_section
1701
bytearray.translate
1702
1703
    table: object
1704
        Translation table, which must be a bytes object of length 256.
1705
    /
1706
    delete as deletechars: object(c_default="NULL") = b''
1707
1708
Return a copy with each character mapped by the given translation table.
1709
1710
All characters occurring in the optional argument delete are
1711
removed.  The remaining characters are mapped through the given
1712
translation table.
1713
[clinic start generated code]*/
1714
1715
static PyObject *
1716
bytearray_translate_impl(PyByteArrayObject *self, PyObject *table,
1717
                         PyObject *deletechars)
1718
/*[clinic end generated code: output=b6a8f01c2a74e446 input=e30d2ae004365ed9]*/
1719
56.9k
{
1720
56.9k
    char *input, *output;
1721
56.9k
    const char *table_chars;
1722
56.9k
    Py_ssize_t i, c;
1723
56.9k
    PyObject *input_obj = (PyObject*)self;
1724
56.9k
    const char *output_start;
1725
56.9k
    Py_ssize_t inlen;
1726
56.9k
    PyObject *result = NULL;
1727
56.9k
    int trans_table[256];
1728
56.9k
    Py_buffer vtable, vdel;
1729
1730
56.9k
    if (table == Py_None) {
1731
0
        table_chars = NULL;
1732
0
        table = NULL;
1733
56.9k
    } else if (PyObject_GetBuffer(table, &vtable, PyBUF_SIMPLE) != 0) {
1734
0
        return NULL;
1735
56.9k
    } else {
1736
56.9k
        if (vtable.len != 256) {
1737
0
            PyErr_SetString(PyExc_ValueError,
1738
0
                            "translation table must be 256 characters long");
1739
0
            PyBuffer_Release(&vtable);
1740
0
            return NULL;
1741
0
        }
1742
56.9k
        table_chars = (const char*)vtable.buf;
1743
56.9k
    }
1744
1745
56.9k
    if (deletechars != NULL) {
1746
0
        if (PyObject_GetBuffer(deletechars, &vdel, PyBUF_SIMPLE) != 0) {
1747
0
            if (table != NULL)
1748
0
                PyBuffer_Release(&vtable);
1749
0
            return NULL;
1750
0
        }
1751
0
    }
1752
56.9k
    else {
1753
56.9k
        vdel.buf = NULL;
1754
56.9k
        vdel.len = 0;
1755
56.9k
    }
1756
1757
56.9k
    inlen = PyByteArray_GET_SIZE(input_obj);
1758
56.9k
    result = PyByteArray_FromStringAndSize((char *)NULL, inlen);
1759
56.9k
    if (result == NULL)
1760
0
        goto done;
1761
56.9k
    output_start = output = PyByteArray_AS_STRING(result);
1762
56.9k
    input = PyByteArray_AS_STRING(input_obj);
1763
1764
56.9k
    if (vdel.len == 0 && table_chars != NULL) {
1765
        /* If no deletions are required, use faster code */
1766
14.6M
        for (i = inlen; --i >= 0; ) {
1767
14.5M
            c = Py_CHARMASK(*input++);
1768
14.5M
            *output++ = table_chars[c];
1769
14.5M
        }
1770
56.9k
        goto done;
1771
56.9k
    }
1772
1773
0
    if (table_chars == NULL) {
1774
0
        for (i = 0; i < 256; i++)
1775
0
            trans_table[i] = Py_CHARMASK(i);
1776
0
    } else {
1777
0
        for (i = 0; i < 256; i++)
1778
0
            trans_table[i] = Py_CHARMASK(table_chars[i]);
1779
0
    }
1780
1781
0
    for (i = 0; i < vdel.len; i++)
1782
0
        trans_table[(int) Py_CHARMASK( ((unsigned char*)vdel.buf)[i] )] = -1;
1783
1784
0
    for (i = inlen; --i >= 0; ) {
1785
0
        c = Py_CHARMASK(*input++);
1786
0
        if (trans_table[c] != -1)
1787
0
            *output++ = (char)trans_table[c];
1788
0
    }
1789
    /* Fix the size of the resulting bytearray */
1790
0
    if (inlen > 0)
1791
0
        if (PyByteArray_Resize(result, output - output_start) < 0) {
1792
0
            Py_CLEAR(result);
1793
0
            goto done;
1794
0
        }
1795
1796
56.9k
done:
1797
56.9k
    if (table != NULL)
1798
56.9k
        PyBuffer_Release(&vtable);
1799
56.9k
    if (deletechars != NULL)
1800
0
        PyBuffer_Release(&vdel);
1801
56.9k
    return result;
1802
0
}
1803
1804
1805
/*[clinic input]
1806
1807
@permit_long_summary
1808
@staticmethod
1809
bytearray.maketrans
1810
1811
    frm: Py_buffer
1812
    to: Py_buffer
1813
    /
1814
1815
Return a translation table usable for the bytes or bytearray translate method.
1816
1817
The returned table will be one where each byte in frm is mapped to
1818
the byte at the same position in to.
1819
1820
The bytes objects frm and to must be of the same length.
1821
[clinic start generated code]*/
1822
1823
static PyObject *
1824
bytearray_maketrans_impl(Py_buffer *frm, Py_buffer *to)
1825
/*[clinic end generated code: output=1df267d99f56b15e input=c2f5f6e7e6b0221d]*/
1826
0
{
1827
0
    return _Py_bytes_maketrans(frm, to);
1828
0
}
1829
1830
1831
/*[clinic input]
1832
@critical_section
1833
bytearray.replace
1834
1835
    old: Py_buffer
1836
    new: Py_buffer
1837
    /
1838
    count: Py_ssize_t = -1
1839
        Maximum number of occurrences to replace.
1840
        -1 (the default value) means replace all occurrences.
1841
1842
Return a copy with all occurrences of substring old replaced by new.
1843
1844
If count is given, only the first count occurrences are replaced.
1845
If count is not specified or -1, then all occurrences are replaced.
1846
[clinic start generated code]*/
1847
1848
static PyObject *
1849
bytearray_replace_impl(PyByteArrayObject *self, Py_buffer *old,
1850
                       Py_buffer *new, Py_ssize_t count)
1851
/*[clinic end generated code: output=d39884c4dc59412a input=e2591806f954aec3]*/
1852
0
{
1853
0
    return stringlib_replace((PyObject *)self,
1854
0
                             (const char *)old->buf, old->len,
1855
0
                             (const char *)new->buf, new->len, count);
1856
0
}
1857
1858
/*[clinic input]
1859
@permit_long_summary
1860
@critical_section
1861
bytearray.split
1862
1863
    sep: object = None
1864
        The delimiter according which to split the bytearray.
1865
        None (the default value) means split on ASCII whitespace
1866
        characters (space, tab, return, newline, formfeed, vertical tab).
1867
    maxsplit: Py_ssize_t = -1
1868
        Maximum number of splits to do.
1869
        -1 (the default value) means no limit.
1870
1871
Return a list of the sections in the bytearray, using sep as the delimiter.
1872
[clinic start generated code]*/
1873
1874
static PyObject *
1875
bytearray_split_impl(PyByteArrayObject *self, PyObject *sep,
1876
                     Py_ssize_t maxsplit)
1877
/*[clinic end generated code: output=833e2cf385d9a04d input=45605178023b52ac]*/
1878
0
{
1879
0
    PyObject *list = NULL;
1880
1881
    /* Increase exports to prevent bytearray storage from changing during _Py_bytes_contains(). */
1882
0
    self->ob_exports++;
1883
0
    const char *sbuf = PyByteArray_AS_STRING(self);
1884
0
    Py_ssize_t slen = PyByteArray_GET_SIZE((PyObject *)self);
1885
1886
0
    if (maxsplit < 0)
1887
0
        maxsplit = PY_SSIZE_T_MAX;
1888
1889
0
    if (sep == Py_None) {
1890
0
        list = stringlib_split_whitespace((PyObject*)self, sbuf, slen, maxsplit);
1891
0
        goto done;
1892
0
    }
1893
1894
0
    Py_buffer vsub;
1895
0
    if (PyObject_GetBuffer(sep, &vsub, PyBUF_SIMPLE) != 0) {
1896
0
        goto done;
1897
0
    }
1898
1899
0
    list = stringlib_split((PyObject*)self, sbuf, slen,
1900
0
                           (const char *)vsub.buf, vsub.len, maxsplit);
1901
0
    PyBuffer_Release(&vsub);
1902
1903
0
done:
1904
0
    self->ob_exports--;
1905
0
    return list;
1906
0
}
1907
1908
/*[clinic input]
1909
@critical_section
1910
bytearray.partition
1911
1912
    sep: object
1913
    /
1914
1915
Partition the bytearray into three parts using the given separator.
1916
1917
This will search for the separator sep in the bytearray.  If the
1918
separator is found, returns a 3-tuple containing the part before the
1919
separator, the separator itself, and the part after it as new
1920
bytearray objects.
1921
1922
If the separator is not found, returns a 3-tuple containing the copy
1923
of the original bytearray object and two empty bytearray objects.
1924
[clinic start generated code]*/
1925
1926
static PyObject *
1927
bytearray_partition_impl(PyByteArrayObject *self, PyObject *sep)
1928
/*[clinic end generated code: output=b5fa1e03f10cfccb input=d76673ed03acf5dd]*/
1929
0
{
1930
0
    PyObject *bytesep, *result;
1931
1932
0
    bytesep = _PyByteArray_FromBufferObject(sep);
1933
0
    if (! bytesep)
1934
0
        return NULL;
1935
1936
0
    result = stringlib_partition(
1937
0
            (PyObject*) self,
1938
0
            PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self),
1939
0
            bytesep,
1940
0
            PyByteArray_AS_STRING(bytesep), PyByteArray_GET_SIZE(bytesep)
1941
0
            );
1942
1943
0
    Py_DECREF(bytesep);
1944
0
    return result;
1945
0
}
1946
1947
/*[clinic input]
1948
@critical_section
1949
bytearray.rpartition
1950
1951
    sep: object
1952
    /
1953
1954
Partition the bytearray into three parts using the given separator.
1955
1956
This will search for the separator sep in the bytearray, starting at
1957
the end.  If the separator is found, returns a 3-tuple containing
1958
the part before the separator, the separator itself, and the part
1959
after it as new bytearray objects.
1960
1961
If the separator is not found, returns a 3-tuple containing two
1962
empty bytearray objects and the copy of the original bytearray
1963
object.
1964
[clinic start generated code]*/
1965
1966
static PyObject *
1967
bytearray_rpartition_impl(PyByteArrayObject *self, PyObject *sep)
1968
/*[clinic end generated code: output=0186ce7b1ef61289 input=b9216a2074174a36]*/
1969
0
{
1970
0
    PyObject *bytesep, *result;
1971
1972
0
    bytesep = _PyByteArray_FromBufferObject(sep);
1973
0
    if (! bytesep)
1974
0
        return NULL;
1975
1976
0
    result = stringlib_rpartition(
1977
0
            (PyObject*) self,
1978
0
            PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self),
1979
0
            bytesep,
1980
0
            PyByteArray_AS_STRING(bytesep), PyByteArray_GET_SIZE(bytesep)
1981
0
            );
1982
1983
0
    Py_DECREF(bytesep);
1984
0
    return result;
1985
0
}
1986
1987
/*[clinic input]
1988
@permit_long_summary
1989
@critical_section
1990
bytearray.rsplit = bytearray.split
1991
1992
Return a list of the sections in the bytearray, using sep as the delimiter.
1993
1994
Splitting is done starting at the end of the bytearray and working
1995
to the front.
1996
[clinic start generated code]*/
1997
1998
static PyObject *
1999
bytearray_rsplit_impl(PyByteArrayObject *self, PyObject *sep,
2000
                      Py_ssize_t maxsplit)
2001
/*[clinic end generated code: output=a55e0b5a03cb6190 input=e201671c9a0c19ee]*/
2002
0
{
2003
0
    PyObject *list = NULL;
2004
2005
    /* Increase exports to prevent bytearray storage from changing during _Py_bytes_contains(). */
2006
0
    self->ob_exports++;
2007
0
    const char *sbuf = PyByteArray_AS_STRING(self);
2008
0
    Py_ssize_t slen = PyByteArray_GET_SIZE((PyObject *)self);
2009
2010
0
    if (maxsplit < 0)
2011
0
        maxsplit = PY_SSIZE_T_MAX;
2012
2013
0
    if (sep == Py_None) {
2014
0
        list = stringlib_rsplit_whitespace((PyObject*)self, sbuf, slen, maxsplit);
2015
0
        goto done;
2016
0
    }
2017
2018
0
    Py_buffer vsub;
2019
0
    if (PyObject_GetBuffer(sep, &vsub, PyBUF_SIMPLE) != 0) {
2020
0
        goto done;
2021
0
    }
2022
2023
0
    list = stringlib_rsplit((PyObject*)self, sbuf, slen,
2024
0
                            (const char *)vsub.buf, vsub.len, maxsplit);
2025
0
    PyBuffer_Release(&vsub);
2026
2027
0
done:
2028
0
    self->ob_exports--;
2029
0
    return list;
2030
0
}
2031
2032
/*[clinic input]
2033
@critical_section
2034
bytearray.reverse
2035
2036
Reverse the order of the values in B in place.
2037
[clinic start generated code]*/
2038
2039
static PyObject *
2040
bytearray_reverse_impl(PyByteArrayObject *self)
2041
/*[clinic end generated code: output=9f7616f29ab309d3 input=2f3d5ce3180ffc53]*/
2042
0
{
2043
0
    char swap, *head, *tail;
2044
0
    Py_ssize_t i, j, n = Py_SIZE(self);
2045
2046
0
    j = n / 2;
2047
0
    head = PyByteArray_AS_STRING(self);
2048
0
    tail = head + n - 1;
2049
0
    for (i = 0; i < j; i++) {
2050
0
        swap = *head;
2051
0
        *head++ = *tail;
2052
0
        *tail-- = swap;
2053
0
    }
2054
2055
0
    Py_RETURN_NONE;
2056
0
}
2057
2058
2059
/*[python input]
2060
class bytesvalue_converter(CConverter):
2061
    type = 'int'
2062
    converter = '_getbytevalue'
2063
[python start generated code]*/
2064
/*[python end generated code: output=da39a3ee5e6b4b0d input=29c2e7c26c212812]*/
2065
2066
2067
/*[clinic input]
2068
@critical_section
2069
bytearray.insert
2070
2071
    index: Py_ssize_t
2072
        The index where the value is to be inserted.
2073
    item: bytesvalue
2074
        The item to be inserted.
2075
    /
2076
2077
Insert a single item into the bytearray before the given index.
2078
[clinic start generated code]*/
2079
2080
static PyObject *
2081
bytearray_insert_impl(PyByteArrayObject *self, Py_ssize_t index, int item)
2082
/*[clinic end generated code: output=76c775a70e7b07b7 input=b3e14ede546dd8cc]*/
2083
0
{
2084
0
    Py_ssize_t n = Py_SIZE(self);
2085
0
    char *buf;
2086
2087
0
    if (bytearray_resize_lock_held((PyObject *)self, n + 1) < 0)
2088
0
        return NULL;
2089
0
    buf = PyByteArray_AS_STRING(self);
2090
2091
0
    if (index < 0) {
2092
0
        index += n;
2093
0
        if (index < 0)
2094
0
            index = 0;
2095
0
    }
2096
0
    if (index > n)
2097
0
        index = n;
2098
0
    memmove(buf + index + 1, buf + index, n - index);
2099
0
    buf[index] = item;
2100
2101
0
    Py_RETURN_NONE;
2102
0
}
2103
2104
static PyObject *
2105
bytearray_isalnum(PyObject *self, PyObject *Py_UNUSED(ignored))
2106
0
{
2107
0
    PyObject *ret;
2108
0
    Py_BEGIN_CRITICAL_SECTION(self);
2109
0
    ret = stringlib_isalnum(self, NULL);
2110
0
    Py_END_CRITICAL_SECTION();
2111
0
    return ret;
2112
0
}
2113
2114
static PyObject *
2115
bytearray_isalpha(PyObject *self, PyObject *Py_UNUSED(ignored))
2116
0
{
2117
0
    PyObject *ret;
2118
0
    Py_BEGIN_CRITICAL_SECTION(self);
2119
0
    ret = stringlib_isalpha(self, NULL);
2120
0
    Py_END_CRITICAL_SECTION();
2121
0
    return ret;
2122
0
}
2123
2124
static PyObject *
2125
bytearray_isascii(PyObject *self, PyObject *Py_UNUSED(ignored))
2126
0
{
2127
0
    PyObject *ret;
2128
0
    Py_BEGIN_CRITICAL_SECTION(self);
2129
0
    ret = stringlib_isascii(self, NULL);
2130
0
    Py_END_CRITICAL_SECTION();
2131
0
    return ret;
2132
0
}
2133
2134
static PyObject *
2135
bytearray_isdigit(PyObject *self, PyObject *Py_UNUSED(ignored))
2136
0
{
2137
0
    PyObject *ret;
2138
0
    Py_BEGIN_CRITICAL_SECTION(self);
2139
0
    ret = stringlib_isdigit(self, NULL);
2140
0
    Py_END_CRITICAL_SECTION();
2141
0
    return ret;
2142
0
}
2143
2144
static PyObject *
2145
bytearray_islower(PyObject *self, PyObject *Py_UNUSED(ignored))
2146
0
{
2147
0
    PyObject *ret;
2148
0
    Py_BEGIN_CRITICAL_SECTION(self);
2149
0
    ret = stringlib_islower(self, NULL);
2150
0
    Py_END_CRITICAL_SECTION();
2151
0
    return ret;
2152
0
}
2153
2154
static PyObject *
2155
bytearray_isspace(PyObject *self, PyObject *Py_UNUSED(ignored))
2156
0
{
2157
0
    PyObject *ret;
2158
0
    Py_BEGIN_CRITICAL_SECTION(self);
2159
0
    ret = stringlib_isspace(self, NULL);
2160
0
    Py_END_CRITICAL_SECTION();
2161
0
    return ret;
2162
0
}
2163
2164
static PyObject *
2165
bytearray_istitle(PyObject *self, PyObject *Py_UNUSED(ignored))
2166
0
{
2167
0
    PyObject *ret;
2168
0
    Py_BEGIN_CRITICAL_SECTION(self);
2169
0
    ret = stringlib_istitle(self, NULL);
2170
0
    Py_END_CRITICAL_SECTION();
2171
0
    return ret;
2172
0
}
2173
2174
static PyObject *
2175
bytearray_isupper(PyObject *self, PyObject *Py_UNUSED(ignored))
2176
0
{
2177
0
    PyObject *ret;
2178
0
    Py_BEGIN_CRITICAL_SECTION(self);
2179
0
    ret = stringlib_isupper(self, NULL);
2180
0
    Py_END_CRITICAL_SECTION();
2181
0
    return ret;
2182
0
}
2183
2184
/*[clinic input]
2185
@critical_section
2186
bytearray.append
2187
2188
    item: bytesvalue
2189
        The item to be appended.
2190
    /
2191
2192
Append a single item to the end of the bytearray.
2193
[clinic start generated code]*/
2194
2195
static PyObject *
2196
bytearray_append_impl(PyByteArrayObject *self, int item)
2197
/*[clinic end generated code: output=a154e19ed1886cb6 input=a874689bac8bd352]*/
2198
330k
{
2199
330k
    Py_ssize_t n = Py_SIZE(self);
2200
2201
330k
    if (bytearray_resize_lock_held((PyObject *)self, n + 1) < 0)
2202
0
        return NULL;
2203
2204
330k
    PyByteArray_AS_STRING(self)[n] = item;
2205
2206
330k
    Py_RETURN_NONE;
2207
330k
}
2208
2209
static PyObject *
2210
bytearray_capitalize(PyObject *self, PyObject *Py_UNUSED(ignored))
2211
0
{
2212
0
    PyObject *ret;
2213
0
    Py_BEGIN_CRITICAL_SECTION(self);
2214
0
    ret = stringlib_capitalize(self, NULL);
2215
0
    Py_END_CRITICAL_SECTION();
2216
0
    return ret;
2217
0
}
2218
2219
static PyObject *
2220
bytearray_center(PyObject *self, PyObject *const *args, Py_ssize_t nargs)
2221
0
{
2222
0
    PyObject *ret;
2223
0
    Py_BEGIN_CRITICAL_SECTION(self);
2224
0
    ret = stringlib_center(self, args, nargs);
2225
0
    Py_END_CRITICAL_SECTION();
2226
0
    return ret;
2227
0
}
2228
2229
static PyObject *
2230
bytearray_expandtabs(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
2231
0
{
2232
0
    PyObject *ret;
2233
0
    Py_BEGIN_CRITICAL_SECTION(self);
2234
0
    ret = stringlib_expandtabs(self, args, nargs, kwnames);
2235
0
    Py_END_CRITICAL_SECTION();
2236
0
    return ret;
2237
0
}
2238
2239
/*[clinic input]
2240
@permit_long_summary
2241
@critical_section
2242
bytearray.extend
2243
2244
    iterable_of_ints: object
2245
        The iterable of items to append.
2246
    /
2247
2248
Append all the items from the iterator or sequence to the end of the bytearray.
2249
[clinic start generated code]*/
2250
2251
static PyObject *
2252
bytearray_extend_impl(PyByteArrayObject *self, PyObject *iterable_of_ints)
2253
/*[clinic end generated code: output=2f25e0ce72b98748 input=aeed44b025146632]*/
2254
197k
{
2255
197k
    PyObject *it, *item, *bytearray_obj;
2256
197k
    Py_ssize_t buf_size = 0, len = 0;
2257
197k
    int value;
2258
197k
    char *buf;
2259
2260
    /* bytearray_setslice code only accepts something supporting PEP 3118. */
2261
197k
    if (PyObject_CheckBuffer(iterable_of_ints)) {
2262
197k
        if (bytearray_setslice(self, Py_SIZE(self), Py_SIZE(self), iterable_of_ints) == -1)
2263
0
            return NULL;
2264
2265
197k
        Py_RETURN_NONE;
2266
197k
    }
2267
2268
0
    it = PyObject_GetIter(iterable_of_ints);
2269
0
    if (it == NULL) {
2270
0
        if (PyErr_ExceptionMatches(PyExc_TypeError)) {
2271
0
            PyErr_Format(PyExc_TypeError,
2272
0
                         "can't extend bytearray with %.100s",
2273
0
                         Py_TYPE(iterable_of_ints)->tp_name);
2274
0
        }
2275
0
        return NULL;
2276
0
    }
2277
2278
    /* Try to determine the length of the argument. 32 is arbitrary. */
2279
0
    buf_size = PyObject_LengthHint(iterable_of_ints, 32);
2280
0
    if (buf_size == -1) {
2281
0
        Py_DECREF(it);
2282
0
        return NULL;
2283
0
    }
2284
2285
0
    bytearray_obj = PyByteArray_FromStringAndSize(NULL, buf_size);
2286
0
    if (bytearray_obj == NULL) {
2287
0
        Py_DECREF(it);
2288
0
        return NULL;
2289
0
    }
2290
0
    buf = PyByteArray_AS_STRING(bytearray_obj);
2291
2292
0
    while ((item = PyIter_Next(it)) != NULL) {
2293
0
        if (! _getbytevalue(item, &value)) {
2294
0
            if (PyErr_ExceptionMatches(PyExc_TypeError) && PyUnicode_Check(iterable_of_ints)) {
2295
0
                PyErr_Format(PyExc_TypeError,
2296
0
                             "expected iterable of integers; got: 'str'");
2297
0
            }
2298
0
            Py_DECREF(item);
2299
0
            Py_DECREF(it);
2300
0
            Py_DECREF(bytearray_obj);
2301
0
            return NULL;
2302
0
        }
2303
0
        Py_DECREF(item);
2304
2305
0
        if (len >= buf_size) {
2306
0
            Py_ssize_t addition;
2307
0
            if (len == PyByteArray_SIZE_MAX) {
2308
0
                Py_DECREF(it);
2309
0
                Py_DECREF(bytearray_obj);
2310
0
                return PyErr_NoMemory();
2311
0
            }
2312
0
            addition = len ? len >> 1 : 1;
2313
0
            if (addition > PyByteArray_SIZE_MAX - len)
2314
0
                buf_size = PyByteArray_SIZE_MAX;
2315
0
            else
2316
0
                buf_size = len + addition;
2317
0
            if (bytearray_resize_lock_held((PyObject *)bytearray_obj, buf_size) < 0) {
2318
0
                Py_DECREF(it);
2319
0
                Py_DECREF(bytearray_obj);
2320
0
                return NULL;
2321
0
            }
2322
            /* Recompute the `buf' pointer, since the resizing operation may
2323
               have invalidated it. */
2324
0
            buf = PyByteArray_AS_STRING(bytearray_obj);
2325
0
        }
2326
0
        buf[len++] = value;
2327
0
    }
2328
0
    Py_DECREF(it);
2329
2330
0
    if (PyErr_Occurred()) {
2331
0
        Py_DECREF(bytearray_obj);
2332
0
        return NULL;
2333
0
    }
2334
2335
    /* Resize down to exact size. */
2336
0
    if (bytearray_resize_lock_held((PyObject *)bytearray_obj, len) < 0) {
2337
0
        Py_DECREF(bytearray_obj);
2338
0
        return NULL;
2339
0
    }
2340
2341
0
    if (bytearray_setslice(self, Py_SIZE(self), Py_SIZE(self), bytearray_obj) == -1) {
2342
0
        Py_DECREF(bytearray_obj);
2343
0
        return NULL;
2344
0
    }
2345
0
    Py_DECREF(bytearray_obj);
2346
2347
0
    assert(!PyErr_Occurred());
2348
0
    Py_RETURN_NONE;
2349
0
}
2350
2351
/*[clinic input]
2352
@critical_section
2353
bytearray.pop
2354
2355
    index: Py_ssize_t = -1
2356
        The index from where to remove the item.
2357
        -1 (the default value) means remove the last item.
2358
    /
2359
2360
Remove and return a single item from B.
2361
2362
If no index argument is given, will pop the last item.
2363
[clinic start generated code]*/
2364
2365
static PyObject *
2366
bytearray_pop_impl(PyByteArrayObject *self, Py_ssize_t index)
2367
/*[clinic end generated code: output=e0ccd401f8021da8 input=fc0fd8de4f97661c]*/
2368
0
{
2369
0
    int value;
2370
0
    Py_ssize_t n = Py_SIZE(self);
2371
0
    char *buf;
2372
2373
0
    if (n == 0) {
2374
0
        PyErr_SetString(PyExc_IndexError,
2375
0
                        "pop from empty bytearray");
2376
0
        return NULL;
2377
0
    }
2378
0
    if (index < 0)
2379
0
        index += Py_SIZE(self);
2380
0
    if (index < 0 || index >= Py_SIZE(self)) {
2381
0
        PyErr_SetString(PyExc_IndexError, "pop index out of range");
2382
0
        return NULL;
2383
0
    }
2384
0
    if (!_canresize(self))
2385
0
        return NULL;
2386
2387
0
    buf = PyByteArray_AS_STRING(self);
2388
0
    value = buf[index];
2389
0
    memmove(buf + index, buf + index + 1, n - index);
2390
0
    if (bytearray_resize_lock_held((PyObject *)self, n - 1) < 0)
2391
0
        return NULL;
2392
2393
0
    return _PyLong_FromUnsignedChar((unsigned char)value);
2394
0
}
2395
2396
/*[clinic input]
2397
@critical_section
2398
bytearray.remove
2399
2400
    value: bytesvalue
2401
        The value to remove.
2402
    /
2403
2404
Remove the first occurrence of a value in the bytearray.
2405
[clinic start generated code]*/
2406
2407
static PyObject *
2408
bytearray_remove_impl(PyByteArrayObject *self, int value)
2409
/*[clinic end generated code: output=d659e37866709c13 input=797588bc77f86afb]*/
2410
0
{
2411
0
    Py_ssize_t where, n = Py_SIZE(self);
2412
0
    char *buf = PyByteArray_AS_STRING(self);
2413
2414
0
    where = stringlib_find_char(buf, n, value);
2415
0
    if (where < 0) {
2416
0
        PyErr_SetString(PyExc_ValueError, "value not found in bytearray");
2417
0
        return NULL;
2418
0
    }
2419
0
    if (!_canresize(self))
2420
0
        return NULL;
2421
2422
0
    memmove(buf + where, buf + where + 1, n - where);
2423
0
    if (bytearray_resize_lock_held((PyObject *)self, n - 1) < 0)
2424
0
        return NULL;
2425
2426
0
    Py_RETURN_NONE;
2427
0
}
2428
2429
0
#define LEFTSTRIP 0
2430
0
#define RIGHTSTRIP 1
2431
0
#define BOTHSTRIP 2
2432
2433
static PyObject*
2434
bytearray_strip_impl_helper(PyByteArrayObject* self, PyObject* bytes, int striptype)
2435
0
{
2436
0
    Py_ssize_t mysize, byteslen;
2437
0
    const char* myptr;
2438
0
    const char* bytesptr;
2439
0
    Py_buffer vbytes;
2440
2441
0
    if (bytes == Py_None) {
2442
0
        bytesptr = "\t\n\r\f\v ";
2443
0
        byteslen = 6;
2444
0
    }
2445
0
    else {
2446
0
        if (PyObject_GetBuffer(bytes, &vbytes, PyBUF_SIMPLE) != 0)
2447
0
            return NULL;
2448
0
        bytesptr = (const char*)vbytes.buf;
2449
0
        byteslen = vbytes.len;
2450
0
    }
2451
0
    myptr = PyByteArray_AS_STRING(self);
2452
0
    mysize = Py_SIZE(self);
2453
2454
0
    Py_ssize_t left = 0;
2455
0
    if (striptype != RIGHTSTRIP) {
2456
0
        while (left < mysize && memchr(bytesptr, (unsigned char)myptr[left], byteslen))
2457
0
            left++;
2458
0
    }
2459
0
    Py_ssize_t right = mysize;
2460
0
    if (striptype != LEFTSTRIP) {
2461
0
        do {
2462
0
            right--;
2463
0
        } while (right >= left && memchr(bytesptr, (unsigned char)myptr[right], byteslen));
2464
0
        right++;
2465
0
    }
2466
0
    if (bytes != Py_None)
2467
0
        PyBuffer_Release(&vbytes);
2468
0
    return PyByteArray_FromStringAndSize(myptr + left, right - left);
2469
0
}
2470
2471
/*[clinic input]
2472
@critical_section
2473
bytearray.strip
2474
2475
    bytes: object = None
2476
    /
2477
2478
Strip leading and trailing bytes contained in the argument.
2479
2480
If the argument is omitted or None, strip leading and trailing ASCII
2481
whitespace.
2482
[clinic start generated code]*/
2483
2484
static PyObject *
2485
bytearray_strip_impl(PyByteArrayObject *self, PyObject *bytes)
2486
/*[clinic end generated code: output=760412661a34ad5a input=f4ec5fa609df7d14]*/
2487
0
{
2488
0
    return bytearray_strip_impl_helper(self, bytes, BOTHSTRIP);
2489
0
}
2490
2491
static PyObject *
2492
bytearray_swapcase(PyObject *self, PyObject *Py_UNUSED(ignored))
2493
0
{
2494
0
    PyObject *ret;
2495
0
    Py_BEGIN_CRITICAL_SECTION(self);
2496
0
    ret = stringlib_swapcase(self, NULL);
2497
0
    Py_END_CRITICAL_SECTION();
2498
0
    return ret;
2499
0
}
2500
2501
static PyObject *
2502
bytearray_title(PyObject *self, PyObject *Py_UNUSED(ignored))
2503
0
{
2504
0
    PyObject *ret;
2505
0
    Py_BEGIN_CRITICAL_SECTION(self);
2506
0
    ret = stringlib_title(self, NULL);
2507
0
    Py_END_CRITICAL_SECTION();
2508
0
    return ret;
2509
0
}
2510
2511
static PyObject *
2512
bytearray_upper(PyObject *self, PyObject *Py_UNUSED(ignored))
2513
0
{
2514
0
    PyObject *ret;
2515
0
    Py_BEGIN_CRITICAL_SECTION(self);
2516
0
    ret = stringlib_upper(self, NULL);
2517
0
    Py_END_CRITICAL_SECTION();
2518
0
    return ret;
2519
0
}
2520
2521
static PyObject *
2522
bytearray_lower(PyObject *self, PyObject *Py_UNUSED(ignored))
2523
0
{
2524
0
    PyObject *ret;
2525
0
    Py_BEGIN_CRITICAL_SECTION(self);
2526
0
    ret = stringlib_lower(self, NULL);
2527
0
    Py_END_CRITICAL_SECTION();
2528
0
    return ret;
2529
0
}
2530
2531
static PyObject *
2532
bytearray_zfill(PyObject *self, PyObject *arg)
2533
0
{
2534
0
    PyObject *ret;
2535
0
    Py_BEGIN_CRITICAL_SECTION(self);
2536
0
    ret = stringlib_zfill(self, arg);
2537
0
    Py_END_CRITICAL_SECTION();
2538
0
    return ret;
2539
0
}
2540
2541
/*[clinic input]
2542
@critical_section
2543
bytearray.lstrip
2544
2545
    bytes: object = None
2546
    /
2547
2548
Strip leading bytes contained in the argument.
2549
2550
If the argument is omitted or None, strip leading ASCII whitespace.
2551
[clinic start generated code]*/
2552
2553
static PyObject *
2554
bytearray_lstrip_impl(PyByteArrayObject *self, PyObject *bytes)
2555
/*[clinic end generated code: output=d005c9d0ab909e66 input=ed86e00eb2023625]*/
2556
0
{
2557
0
    return bytearray_strip_impl_helper(self, bytes, LEFTSTRIP);
2558
0
}
2559
2560
/*[clinic input]
2561
@critical_section
2562
bytearray.rstrip
2563
2564
    bytes: object = None
2565
    /
2566
2567
Strip trailing bytes contained in the argument.
2568
2569
If the argument is omitted or None, strip trailing ASCII whitespace.
2570
[clinic start generated code]*/
2571
2572
static PyObject *
2573
bytearray_rstrip_impl(PyByteArrayObject *self, PyObject *bytes)
2574
/*[clinic end generated code: output=030e2fbd2f7276bd input=d9ca66cf20fe7649]*/
2575
0
{
2576
0
    return bytearray_strip_impl_helper(self, bytes, RIGHTSTRIP);
2577
0
}
2578
2579
/*[clinic input]
2580
@critical_section
2581
bytearray.decode
2582
2583
    encoding: str(c_default="NULL") = 'utf-8'
2584
        The encoding with which to decode the bytearray.
2585
    errors: str(c_default="NULL") = 'strict'
2586
        The error handling scheme to use for the handling of decoding
2587
        errors.  The default is 'strict' meaning that decoding errors
2588
        raise a UnicodeDecodeError.  Other possible values are 'ignore'
2589
        and 'replace' as well as any other name registered with
2590
        codecs.register_error that can handle UnicodeDecodeErrors.
2591
2592
Decode the bytearray using the codec registered for encoding.
2593
[clinic start generated code]*/
2594
2595
static PyObject *
2596
bytearray_decode_impl(PyByteArrayObject *self, const char *encoding,
2597
                      const char *errors)
2598
/*[clinic end generated code: output=f57d43f4a00b42c5 input=e51ce9b82b51e2ca]*/
2599
0
{
2600
0
    if (encoding == NULL)
2601
0
        encoding = PyUnicode_GetDefaultEncoding();
2602
0
    if (Py_TYPE(self)->tp_as_buffer->bf_getbuffer != bytearray_getbuffer) {
2603
        /* A subclass may export a different buffer. */
2604
0
        return PyUnicode_FromEncodedObject((PyObject*)self, encoding, errors);
2605
0
    }
2606
2607
    /* Decode the storage directly instead of exporting a buffer, which
2608
       would re-acquire the critical section we already hold.  Increase
2609
       exports to prevent the storage from changing during the decode. */
2610
0
    self->ob_exports++;
2611
0
    PyObject *res = PyUnicode_Decode(PyByteArray_AS_STRING(self),
2612
0
                                     Py_SIZE(self), encoding, errors);
2613
0
    self->ob_exports--;
2614
0
    return res;
2615
0
}
2616
2617
PyDoc_STRVAR(alloc_doc,
2618
"B.__alloc__() -> int\n\
2619
\n\
2620
Return the number of bytes actually allocated.");
2621
2622
static PyObject *
2623
bytearray_alloc(PyObject *op, PyObject *Py_UNUSED(ignored))
2624
0
{
2625
0
    PyByteArrayObject *self = _PyByteArray_CAST(op);
2626
0
    Py_ssize_t alloc = FT_ATOMIC_LOAD_SSIZE_RELAXED(self->ob_alloc);
2627
0
    if (alloc > 0) {
2628
0
        alloc += _PyBytesObject_SIZE;
2629
0
    }
2630
0
    return PyLong_FromSsize_t(alloc);
2631
0
}
2632
2633
/*[clinic input]
2634
@critical_section
2635
bytearray.join
2636
2637
    iterable_of_bytes: object
2638
    /
2639
2640
Concatenate any number of bytes/bytearray objects.
2641
2642
The bytearray whose method is called is inserted in between each
2643
pair.
2644
2645
The result is returned as a new bytearray object.
2646
[clinic start generated code]*/
2647
2648
static PyObject *
2649
bytearray_join_impl(PyByteArrayObject *self, PyObject *iterable_of_bytes)
2650
/*[clinic end generated code: output=0ced382b5846a7ee input=0a31db349efcd7fa]*/
2651
0
{
2652
0
    PyObject *ret;
2653
0
    self->ob_exports++; // this protects `self` from being cleared/resized if `iterable_of_bytes` is a custom iterator
2654
0
    ret = stringlib_bytes_join((PyObject*)self, iterable_of_bytes);
2655
0
    self->ob_exports--; // unexport `self`
2656
0
    return ret;
2657
0
}
2658
2659
static PyObject *
2660
bytearray_ljust(PyObject *self, PyObject *const *args, Py_ssize_t nargs)
2661
0
{
2662
0
    PyObject *ret;
2663
0
    Py_BEGIN_CRITICAL_SECTION(self);
2664
0
    ret = stringlib_ljust(self, args, nargs);
2665
0
    Py_END_CRITICAL_SECTION();
2666
0
    return ret;
2667
0
}
2668
2669
static PyObject *
2670
bytearray_rjust(PyObject *self, PyObject *const *args, Py_ssize_t nargs)
2671
0
{
2672
0
    PyObject *ret;
2673
0
    Py_BEGIN_CRITICAL_SECTION(self);
2674
0
    ret = stringlib_rjust(self, args, nargs);
2675
0
    Py_END_CRITICAL_SECTION();
2676
0
    return ret;
2677
0
}
2678
2679
/*[clinic input]
2680
@permit_long_summary
2681
@critical_section
2682
bytearray.splitlines
2683
2684
    keepends: bool = False
2685
2686
Return a list of the lines in the bytearray, breaking at line boundaries.
2687
2688
Line breaks are not included in the resulting list unless keepends
2689
is given and true.
2690
[clinic start generated code]*/
2691
2692
static PyObject *
2693
bytearray_splitlines_impl(PyByteArrayObject *self, int keepends)
2694
/*[clinic end generated code: output=4223c94b895f6ad9 input=cc2bb740eed19f27]*/
2695
0
{
2696
0
    return stringlib_splitlines(
2697
0
        (PyObject*) self, PyByteArray_AS_STRING(self),
2698
0
        PyByteArray_GET_SIZE(self), keepends
2699
0
        );
2700
0
}
2701
2702
/*[clinic input]
2703
@classmethod
2704
bytearray.fromhex
2705
2706
    string: object
2707
    /
2708
2709
Create a bytearray object from a string of hexadecimal numbers.
2710
2711
Spaces between two numbers are accepted.
2712
Example:
2713
    bytearray.fromhex('B9 01EF') -> bytearray(b'\\xb9\\x01\\xef')
2714
[clinic start generated code]*/
2715
2716
static PyObject *
2717
bytearray_fromhex_impl(PyTypeObject *type, PyObject *string)
2718
/*[clinic end generated code: output=8f0f0b6d30fb3ba0 input=2243a8b0b9e66cd5]*/
2719
0
{
2720
0
    PyObject *result = _PyBytes_FromHex(string, type == &PyByteArray_Type);
2721
0
    if (type != &PyByteArray_Type && result != NULL) {
2722
0
        Py_SETREF(result, PyObject_CallOneArg((PyObject *)type, result));
2723
0
    }
2724
0
    return result;
2725
0
}
2726
2727
/*[clinic input]
2728
@critical_section
2729
bytearray.hex
2730
2731
    sep: object = NULL
2732
        An optional single character or byte to separate hex bytes.
2733
    bytes_per_sep: Py_ssize_t = 1
2734
        How many bytes between separators.  Positive values count from
2735
        the right, negative values count from the left.
2736
2737
Create a string of hexadecimal numbers from a bytearray object.
2738
2739
Example:
2740
>>> value = bytearray([0xb9, 0x01, 0xef])
2741
>>> value.hex()
2742
'b901ef'
2743
>>> value.hex(':')
2744
'b9:01:ef'
2745
>>> value.hex(':', 2)
2746
'b9:01ef'
2747
>>> value.hex(':', -2)
2748
'b901:ef'
2749
[clinic start generated code]*/
2750
2751
static PyObject *
2752
bytearray_hex_impl(PyByteArrayObject *self, PyObject *sep,
2753
                   Py_ssize_t bytes_per_sep)
2754
/*[clinic end generated code: output=c9563921aff1262b input=9ed746203691e894]*/
2755
0
{
2756
0
    char* argbuf = PyByteArray_AS_STRING(self);
2757
0
    Py_ssize_t arglen = PyByteArray_GET_SIZE(self);
2758
    // Prevent 'self' from being freed if computing len(sep) mutates 'self'
2759
    // in _Py_strhex_with_sep().
2760
    // See: https://github.com/python/cpython/issues/143195.
2761
0
    self->ob_exports++;
2762
0
    PyObject *res = _Py_strhex_with_sep(argbuf, arglen, sep, bytes_per_sep);
2763
0
    self->ob_exports--;
2764
0
    return res;
2765
0
}
2766
2767
static PyObject *
2768
_common_reduce(PyByteArrayObject *self, int proto)
2769
0
{
2770
0
    PyObject *state;
2771
0
    const char *buf;
2772
2773
0
    state = _PyObject_GetState((PyObject *)self);
2774
0
    if (state == NULL) {
2775
0
        return NULL;
2776
0
    }
2777
2778
0
    if (!Py_SIZE(self)) {
2779
0
        return Py_BuildValue("(O()N)", Py_TYPE(self), state);
2780
0
    }
2781
0
    buf = PyByteArray_AS_STRING(self);
2782
0
    if (proto < 3) {
2783
        /* use str based reduction for backwards compatibility with Python 2.x */
2784
0
        PyObject *latin1 = PyUnicode_DecodeLatin1(buf, Py_SIZE(self), NULL);
2785
0
        return Py_BuildValue("(O(Ns)N)", Py_TYPE(self), latin1, "latin-1", state);
2786
0
    }
2787
0
    else {
2788
        /* use more efficient byte based reduction */
2789
0
        return Py_BuildValue("(O(y#)N)", Py_TYPE(self), buf, Py_SIZE(self), state);
2790
0
    }
2791
0
}
2792
2793
/*[clinic input]
2794
@critical_section
2795
bytearray.__reduce__ as bytearray_reduce
2796
2797
Return state information for pickling.
2798
[clinic start generated code]*/
2799
2800
static PyObject *
2801
bytearray_reduce_impl(PyByteArrayObject *self)
2802
/*[clinic end generated code: output=52bf304086464cab input=0fac78e4b7d84dd2]*/
2803
0
{
2804
0
    return _common_reduce(self, 2);
2805
0
}
2806
2807
/*[clinic input]
2808
@critical_section
2809
bytearray.__reduce_ex__ as bytearray_reduce_ex
2810
2811
    proto: int = 0
2812
    /
2813
2814
Return state information for pickling.
2815
[clinic start generated code]*/
2816
2817
static PyObject *
2818
bytearray_reduce_ex_impl(PyByteArrayObject *self, int proto)
2819
/*[clinic end generated code: output=52eac33377197520 input=751718f477033a29]*/
2820
0
{
2821
0
    return _common_reduce(self, proto);
2822
0
}
2823
2824
/*[clinic input]
2825
bytearray.__sizeof__ as bytearray_sizeof
2826
2827
Returns the size of the bytearray object in memory, in bytes.
2828
[clinic start generated code]*/
2829
2830
static PyObject *
2831
bytearray_sizeof_impl(PyByteArrayObject *self)
2832
/*[clinic end generated code: output=738abdd17951c427 input=e27320fd98a4bc5a]*/
2833
0
{
2834
0
    Py_ssize_t res = _PyObject_SIZE(Py_TYPE(self));
2835
0
    Py_ssize_t alloc = FT_ATOMIC_LOAD_SSIZE_RELAXED(self->ob_alloc);
2836
0
    if (alloc > 0) {
2837
0
        res += _PyBytesObject_SIZE + alloc;
2838
0
    }
2839
2840
0
    return PyLong_FromSsize_t(res);
2841
0
}
2842
2843
static PySequenceMethods bytearray_as_sequence = {
2844
    bytearray_length,                       /* sq_length */
2845
    PyByteArray_Concat,                     /* sq_concat */
2846
    bytearray_repeat,                       /* sq_repeat */
2847
    bytearray_getitem,                      /* sq_item */
2848
    0,                                      /* sq_slice */
2849
    bytearray_setitem,                      /* sq_ass_item */
2850
    0,                                      /* sq_ass_slice */
2851
    bytearray_contains,                     /* sq_contains */
2852
    bytearray_iconcat,                      /* sq_inplace_concat */
2853
    bytearray_irepeat,                      /* sq_inplace_repeat */
2854
};
2855
2856
static PyMappingMethods bytearray_as_mapping = {
2857
    bytearray_length,
2858
    bytearray_subscript,
2859
    bytearray_ass_subscript,
2860
};
2861
2862
static PyBufferProcs bytearray_as_buffer = {
2863
    bytearray_getbuffer,
2864
    bytearray_releasebuffer,
2865
};
2866
2867
static PyMethodDef bytearray_methods[] = {
2868
    {"__alloc__", bytearray_alloc, METH_NOARGS, alloc_doc},
2869
    BYTEARRAY_REDUCE_METHODDEF
2870
    BYTEARRAY_REDUCE_EX_METHODDEF
2871
    BYTEARRAY_SIZEOF_METHODDEF
2872
    BYTEARRAY_APPEND_METHODDEF
2873
    {"capitalize", bytearray_capitalize, METH_NOARGS, _Py_capitalize__doc__},
2874
    {"center", _PyCFunction_CAST(bytearray_center), METH_FASTCALL,
2875
    stringlib_center__doc__},
2876
    BYTEARRAY_CLEAR_METHODDEF
2877
    BYTEARRAY_COPY_METHODDEF
2878
    BYTEARRAY_COUNT_METHODDEF
2879
    BYTEARRAY_DECODE_METHODDEF
2880
    BYTEARRAY_ENDSWITH_METHODDEF
2881
    {"expandtabs", _PyCFunction_CAST(bytearray_expandtabs),
2882
    METH_FASTCALL|METH_KEYWORDS, stringlib_expandtabs__doc__},
2883
    BYTEARRAY_EXTEND_METHODDEF
2884
    BYTEARRAY_FIND_METHODDEF
2885
    BYTEARRAY_FROMHEX_METHODDEF
2886
    BYTEARRAY_HEX_METHODDEF
2887
    BYTEARRAY_INDEX_METHODDEF
2888
    BYTEARRAY_INSERT_METHODDEF
2889
    {"isalnum", bytearray_isalnum, METH_NOARGS, _Py_isalnum__doc__},
2890
    {"isalpha", bytearray_isalpha, METH_NOARGS, _Py_isalpha__doc__},
2891
    {"isascii", bytearray_isascii, METH_NOARGS, _Py_isascii__doc__},
2892
    {"isdigit", bytearray_isdigit, METH_NOARGS, _Py_isdigit__doc__},
2893
    {"islower", bytearray_islower, METH_NOARGS, _Py_islower__doc__},
2894
    {"isspace", bytearray_isspace, METH_NOARGS, _Py_isspace__doc__},
2895
    {"istitle", bytearray_istitle, METH_NOARGS, _Py_istitle__doc__},
2896
    {"isupper", bytearray_isupper, METH_NOARGS, _Py_isupper__doc__},
2897
    BYTEARRAY_JOIN_METHODDEF
2898
    {"ljust", _PyCFunction_CAST(bytearray_ljust), METH_FASTCALL,
2899
    stringlib_ljust__doc__},
2900
    {"lower", bytearray_lower, METH_NOARGS, _Py_lower__doc__},
2901
    BYTEARRAY_LSTRIP_METHODDEF
2902
    BYTEARRAY_MAKETRANS_METHODDEF
2903
    BYTEARRAY_PARTITION_METHODDEF
2904
    BYTEARRAY_POP_METHODDEF
2905
    BYTEARRAY_REMOVE_METHODDEF
2906
    BYTEARRAY_REPLACE_METHODDEF
2907
    BYTEARRAY_REMOVEPREFIX_METHODDEF
2908
    BYTEARRAY_REMOVESUFFIX_METHODDEF
2909
    BYTEARRAY_RESIZE_METHODDEF
2910
    BYTEARRAY_REVERSE_METHODDEF
2911
    BYTEARRAY_RFIND_METHODDEF
2912
    BYTEARRAY_RINDEX_METHODDEF
2913
    {"rjust", _PyCFunction_CAST(bytearray_rjust), METH_FASTCALL,
2914
    stringlib_rjust__doc__},
2915
    BYTEARRAY_RPARTITION_METHODDEF
2916
    BYTEARRAY_RSPLIT_METHODDEF
2917
    BYTEARRAY_RSTRIP_METHODDEF
2918
    BYTEARRAY_SPLIT_METHODDEF
2919
    BYTEARRAY_SPLITLINES_METHODDEF
2920
    BYTEARRAY_STARTSWITH_METHODDEF
2921
    BYTEARRAY_STRIP_METHODDEF
2922
    {"swapcase", bytearray_swapcase, METH_NOARGS, _Py_swapcase__doc__},
2923
    BYTEARRAY_TAKE_BYTES_METHODDEF
2924
    {"title", bytearray_title, METH_NOARGS, _Py_title__doc__},
2925
    BYTEARRAY_TRANSLATE_METHODDEF
2926
    {"upper", bytearray_upper, METH_NOARGS, _Py_upper__doc__},
2927
    {"zfill", bytearray_zfill, METH_O, stringlib_zfill__doc__},
2928
    {NULL}
2929
};
2930
2931
static PyObject *
2932
bytearray_mod_lock_held(PyObject *v, PyObject *w)
2933
0
{
2934
0
    _Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED(v);
2935
0
    if (!PyByteArray_Check(v))
2936
0
        Py_RETURN_NOTIMPLEMENTED;
2937
2938
0
    PyByteArrayObject *self = _PyByteArray_CAST(v);
2939
    /* Increase exports to prevent bytearray storage from changing during op. */
2940
0
    self->ob_exports++;
2941
0
    PyObject *res = _PyBytes_FormatEx(
2942
0
        PyByteArray_AS_STRING(v), PyByteArray_GET_SIZE(v), w, 1
2943
0
    );
2944
0
    self->ob_exports--;
2945
0
    return res;
2946
0
}
2947
2948
static PyObject *
2949
bytearray_mod(PyObject *v, PyObject *w)
2950
0
{
2951
0
    PyObject *ret;
2952
0
    if (PyByteArray_Check(w)) {
2953
0
        Py_BEGIN_CRITICAL_SECTION2(v, w);
2954
0
        ret = bytearray_mod_lock_held(v, w);
2955
0
        Py_END_CRITICAL_SECTION2();
2956
0
    }
2957
0
    else {
2958
0
        Py_BEGIN_CRITICAL_SECTION(v);
2959
0
        ret = bytearray_mod_lock_held(v, w);
2960
0
        Py_END_CRITICAL_SECTION();
2961
0
    }
2962
0
    return ret;
2963
0
}
2964
2965
static PyNumberMethods bytearray_as_number = {
2966
    0,              /*nb_add*/
2967
    0,              /*nb_subtract*/
2968
    0,              /*nb_multiply*/
2969
    bytearray_mod,  /*nb_remainder*/
2970
};
2971
2972
PyDoc_STRVAR(bytearray_doc,
2973
"bytearray(iterable_of_ints) -> bytearray\n\
2974
bytearray(string, encoding[, errors]) -> bytearray\n\
2975
bytearray(bytes_or_buffer) -> mutable copy of bytes_or_buffer\n\
2976
bytearray(int) -> bytes array of size given by the parameter initialized with null bytes\n\
2977
bytearray() -> empty bytes array\n\
2978
\n\
2979
Construct a mutable bytearray object from:\n\
2980
  - an iterable yielding integers in range(256)\n\
2981
  - a text string encoded using the specified encoding\n\
2982
  - a bytes or a buffer object\n\
2983
  - any object implementing the buffer API.\n\
2984
  - an integer");
2985
2986
2987
static PyObject *bytearray_iter(PyObject *seq);
2988
2989
PyTypeObject PyByteArray_Type = {
2990
    PyVarObject_HEAD_INIT(&PyType_Type, 0)
2991
    "bytearray",
2992
    sizeof(PyByteArrayObject),
2993
    0,
2994
    bytearray_dealloc,                  /* tp_dealloc */
2995
    0,                                  /* tp_vectorcall_offset */
2996
    0,                                  /* tp_getattr */
2997
    0,                                  /* tp_setattr */
2998
    0,                                  /* tp_as_async */
2999
    bytearray_repr,                     /* tp_repr */
3000
    &bytearray_as_number,               /* tp_as_number */
3001
    &bytearray_as_sequence,             /* tp_as_sequence */
3002
    &bytearray_as_mapping,              /* tp_as_mapping */
3003
    0,                                  /* tp_hash */
3004
    0,                                  /* tp_call */
3005
    bytearray_str,                      /* tp_str */
3006
    PyObject_GenericGetAttr,            /* tp_getattro */
3007
    0,                                  /* tp_setattro */
3008
    &bytearray_as_buffer,               /* tp_as_buffer */
3009
    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE |
3010
        _Py_TPFLAGS_MATCH_SELF,       /* tp_flags */
3011
    bytearray_doc,                      /* tp_doc */
3012
    0,                                  /* tp_traverse */
3013
    0,                                  /* tp_clear */
3014
    bytearray_richcompare,              /* tp_richcompare */
3015
    0,                                  /* tp_weaklistoffset */
3016
    bytearray_iter,                     /* tp_iter */
3017
    0,                                  /* tp_iternext */
3018
    bytearray_methods,                  /* tp_methods */
3019
    0,                                  /* tp_members */
3020
    0,                                  /* tp_getset */
3021
    0,                                  /* tp_base */
3022
    0,                                  /* tp_dict */
3023
    0,                                  /* tp_descr_get */
3024
    0,                                  /* tp_descr_set */
3025
    0,                                  /* tp_dictoffset */
3026
    bytearray___init__,                 /* tp_init */
3027
    PyType_GenericAlloc,                /* tp_alloc */
3028
    bytearray_new,                      /* tp_new */
3029
    PyObject_Free,                      /* tp_free */
3030
    .tp_version_tag = _Py_TYPE_VERSION_BYTEARRAY,
3031
};
3032
3033
/*********************** Bytearray Iterator ****************************/
3034
3035
typedef struct {
3036
    PyObject_HEAD
3037
    Py_ssize_t it_index;
3038
    PyByteArrayObject *it_seq; /* Set to NULL when iterator is exhausted */
3039
} bytesiterobject;
3040
3041
22
#define _bytesiterobject_CAST(op)   ((bytesiterobject *)(op))
3042
3043
static void
3044
bytearrayiter_dealloc(PyObject *self)
3045
22
{
3046
22
    bytesiterobject *it = _bytesiterobject_CAST(self);
3047
22
    _PyObject_GC_UNTRACK(it);
3048
22
    Py_XDECREF(it->it_seq);
3049
22
    PyObject_GC_Del(it);
3050
22
}
3051
3052
static int
3053
bytearrayiter_traverse(PyObject *self, visitproc visit, void *arg)
3054
0
{
3055
0
    bytesiterobject *it = _bytesiterobject_CAST(self);
3056
0
    Py_VISIT(it->it_seq);
3057
0
    return 0;
3058
0
}
3059
3060
static PyObject *
3061
bytearrayiter_next(PyObject *self)
3062
0
{
3063
0
    bytesiterobject *it = _bytesiterobject_CAST(self);
3064
0
    int val;
3065
3066
0
    assert(it != NULL);
3067
0
    Py_ssize_t index = FT_ATOMIC_LOAD_SSIZE_RELAXED(it->it_index);
3068
0
    if (index < 0) {
3069
0
        return NULL;
3070
0
    }
3071
0
    PyByteArrayObject *seq = it->it_seq;
3072
0
    assert(PyByteArray_Check(seq));
3073
3074
0
    Py_BEGIN_CRITICAL_SECTION(seq);
3075
0
    if (index < Py_SIZE(seq)) {
3076
0
        val = (unsigned char)PyByteArray_AS_STRING(seq)[index];
3077
0
    }
3078
0
    else {
3079
0
        val = -1;
3080
0
    }
3081
0
    Py_END_CRITICAL_SECTION();
3082
3083
0
    if (val == -1) {
3084
0
        FT_ATOMIC_STORE_SSIZE_RELAXED(it->it_index, -1);
3085
0
#ifndef Py_GIL_DISABLED
3086
0
        Py_CLEAR(it->it_seq);
3087
0
#endif
3088
0
        return NULL;
3089
0
    }
3090
0
    FT_ATOMIC_STORE_SSIZE_RELAXED(it->it_index, index + 1);
3091
0
    return _PyLong_FromUnsignedChar((unsigned char)val);
3092
0
}
3093
3094
static PyObject *
3095
bytearrayiter_length_hint(PyObject *self, PyObject *Py_UNUSED(ignored))
3096
0
{
3097
0
    bytesiterobject *it = _bytesiterobject_CAST(self);
3098
0
    Py_ssize_t len = 0;
3099
0
    Py_ssize_t index = FT_ATOMIC_LOAD_SSIZE_RELAXED(it->it_index);
3100
0
    if (index >= 0) {
3101
0
        len = PyByteArray_GET_SIZE(it->it_seq) - index;
3102
0
        if (len < 0) {
3103
0
            len = 0;
3104
0
        }
3105
0
    }
3106
0
    return PyLong_FromSsize_t(len);
3107
0
}
3108
3109
PyDoc_STRVAR(length_hint_doc,
3110
    "Private method returning an estimate of len(list(it)).");
3111
3112
static PyObject *
3113
bytearrayiter_reduce(PyObject *self, PyObject *Py_UNUSED(ignored))
3114
0
{
3115
0
    PyObject *iter = _PyEval_GetBuiltin(&_Py_ID(iter));
3116
3117
    /* _PyEval_GetBuiltin can invoke arbitrary code,
3118
     * call must be before access of iterator pointers.
3119
     * see issue #101765 */
3120
0
    bytesiterobject *it = _bytesiterobject_CAST(self);
3121
0
    Py_ssize_t index = FT_ATOMIC_LOAD_SSIZE_RELAXED(it->it_index);
3122
0
    if (index >= 0) {
3123
0
        return Py_BuildValue("N(O)n", iter, it->it_seq, index);
3124
0
    }
3125
0
    return Py_BuildValue("N(())", iter);
3126
0
}
3127
3128
static PyObject *
3129
bytearrayiter_setstate(PyObject *self, PyObject *state)
3130
0
{
3131
0
    Py_ssize_t index = PyLong_AsSsize_t(state);
3132
0
    if (index == -1 && PyErr_Occurred()) {
3133
0
        return NULL;
3134
0
    }
3135
3136
0
    bytesiterobject *it = _bytesiterobject_CAST(self);
3137
0
    if (FT_ATOMIC_LOAD_SSIZE_RELAXED(it->it_index) >= 0) {
3138
0
        if (index < -1) {
3139
0
            index = -1;
3140
0
        }
3141
0
        else {
3142
0
            Py_ssize_t size = PyByteArray_GET_SIZE(it->it_seq);
3143
0
            if (index > size) {
3144
0
                index = size; /* iterator at end */
3145
0
            }
3146
0
        }
3147
0
        FT_ATOMIC_STORE_SSIZE_RELAXED(it->it_index, index);
3148
0
    }
3149
0
    Py_RETURN_NONE;
3150
0
}
3151
3152
PyDoc_STRVAR(setstate_doc, "Set state information for unpickling.");
3153
3154
static PyMethodDef bytearrayiter_methods[] = {
3155
    {"__length_hint__", bytearrayiter_length_hint, METH_NOARGS,
3156
     length_hint_doc},
3157
     {"__reduce__",     bytearrayiter_reduce, METH_NOARGS,
3158
     bytearray_reduce__doc__},
3159
    {"__setstate__",    bytearrayiter_setstate, METH_O,
3160
     setstate_doc},
3161
    {NULL, NULL} /* sentinel */
3162
};
3163
3164
PyTypeObject PyByteArrayIter_Type = {
3165
    PyVarObject_HEAD_INIT(&PyType_Type, 0)
3166
    "bytearray_iterator",              /* tp_name */
3167
    sizeof(bytesiterobject),           /* tp_basicsize */
3168
    0,                                 /* tp_itemsize */
3169
    /* methods */
3170
    bytearrayiter_dealloc,             /* tp_dealloc */
3171
    0,                                 /* tp_vectorcall_offset */
3172
    0,                                 /* tp_getattr */
3173
    0,                                 /* tp_setattr */
3174
    0,                                 /* tp_as_async */
3175
    0,                                 /* tp_repr */
3176
    0,                                 /* tp_as_number */
3177
    0,                                 /* tp_as_sequence */
3178
    0,                                 /* tp_as_mapping */
3179
    0,                                 /* tp_hash */
3180
    0,                                 /* tp_call */
3181
    0,                                 /* tp_str */
3182
    PyObject_GenericGetAttr,           /* tp_getattro */
3183
    0,                                 /* tp_setattro */
3184
    0,                                 /* tp_as_buffer */
3185
    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */
3186
    0,                                 /* tp_doc */
3187
    bytearrayiter_traverse,            /* tp_traverse */
3188
    0,                                 /* tp_clear */
3189
    0,                                 /* tp_richcompare */
3190
    0,                                 /* tp_weaklistoffset */
3191
    PyObject_SelfIter,                 /* tp_iter */
3192
    bytearrayiter_next,                /* tp_iternext */
3193
    bytearrayiter_methods,             /* tp_methods */
3194
    0,
3195
};
3196
3197
static PyObject *
3198
bytearray_iter(PyObject *seq)
3199
22
{
3200
22
    bytesiterobject *it;
3201
3202
22
    if (!PyByteArray_Check(seq)) {
3203
0
        PyErr_BadInternalCall();
3204
0
        return NULL;
3205
0
    }
3206
22
    it = PyObject_GC_New(bytesiterobject, &PyByteArrayIter_Type);
3207
22
    if (it == NULL)
3208
0
        return NULL;
3209
22
    it->it_index = 0;  // -1 indicates exhausted
3210
22
    it->it_seq = (PyByteArrayObject *)Py_NewRef(seq);
3211
22
    _PyObject_GC_TRACK(it);
3212
22
    return (PyObject *)it;
3213
22
}