Coverage Report

Created: 2026-10-31 06:21

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