Skip to content

Commit f589513

Browse files
miss-islingtonaisk
andauthored
[3.13] pythongh-116738: Make _csv module thread-safe (pythonGH-118344) (python#125328)
pythongh-116738: Make `_csv` module thread-safe (pythonGH-118344) (cherry picked from commit a00221e) Co-authored-by: AN Long <aisk@users.noreply.github.com>
1 parent 73c152b commit f589513

File tree

1 file changed

+11
-9
lines changed

1 file changed

+11
-9
lines changed

Modules/_csv.c

+11-9
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ module instead.
1414
#endif
1515

1616
#include "Python.h"
17+
#include "pycore_pyatomic_ft_wrappers.h"
1718

1819
#include <stddef.h> // offsetof()
1920
#include <stdbool.h>
@@ -34,7 +35,7 @@ typedef struct {
3435
PyTypeObject *dialect_type;
3536
PyTypeObject *reader_type;
3637
PyTypeObject *writer_type;
37-
long field_limit; /* max parsed field size */
38+
Py_ssize_t field_limit; /* max parsed field size */
3839
PyObject *str_write;
3940
} _csvstate;
4041

@@ -702,10 +703,11 @@ parse_grow_buff(ReaderObj *self)
702703
static int
703704
parse_add_char(ReaderObj *self, _csvstate *module_state, Py_UCS4 c)
704705
{
705-
if (self->field_len >= module_state->field_limit) {
706+
Py_ssize_t field_limit = FT_ATOMIC_LOAD_SSIZE_RELAXED(module_state->field_limit);
707+
if (self->field_len >= field_limit) {
706708
PyErr_Format(module_state->error_obj,
707-
"field larger than field limit (%ld)",
708-
module_state->field_limit);
709+
"field larger than field limit (%zd)",
710+
field_limit);
709711
return -1;
710712
}
711713
if (self->field_len == self->field_size && !parse_grow_buff(self))
@@ -1651,20 +1653,20 @@ _csv_field_size_limit_impl(PyObject *module, PyObject *new_limit)
16511653
/*[clinic end generated code: output=f2799ecd908e250b input=cec70e9226406435]*/
16521654
{
16531655
_csvstate *module_state = get_csv_state(module);
1654-
long old_limit = module_state->field_limit;
1656+
Py_ssize_t old_limit = FT_ATOMIC_LOAD_SSIZE_RELAXED(module_state->field_limit);
16551657
if (new_limit != NULL) {
16561658
if (!PyLong_CheckExact(new_limit)) {
16571659
PyErr_Format(PyExc_TypeError,
16581660
"limit must be an integer");
16591661
return NULL;
16601662
}
1661-
module_state->field_limit = PyLong_AsLong(new_limit);
1662-
if (module_state->field_limit == -1 && PyErr_Occurred()) {
1663-
module_state->field_limit = old_limit;
1663+
Py_ssize_t new_limit_value = PyLong_AsSsize_t(new_limit);
1664+
if (new_limit_value == -1 && PyErr_Occurred()) {
16641665
return NULL;
16651666
}
1667+
FT_ATOMIC_STORE_SSIZE_RELAXED(module_state->field_limit, new_limit_value);
16661668
}
1667-
return PyLong_FromLong(old_limit);
1669+
return PyLong_FromSsize_t(old_limit);
16681670
}
16691671

16701672
static PyType_Slot error_slots[] = {

0 commit comments

Comments
 (0)