mirror of https://github.com/python/cpython
gh-116738: Make `_csv` module thread-safe (#118344)
This commit is contained in:
parent
08f6bf7171
commit
a00221e5a7
|
@ -14,6 +14,7 @@ module instead.
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "Python.h"
|
#include "Python.h"
|
||||||
|
#include "pycore_pyatomic_ft_wrappers.h"
|
||||||
|
|
||||||
#include <stddef.h> // offsetof()
|
#include <stddef.h> // offsetof()
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
@ -34,7 +35,7 @@ typedef struct {
|
||||||
PyTypeObject *dialect_type;
|
PyTypeObject *dialect_type;
|
||||||
PyTypeObject *reader_type;
|
PyTypeObject *reader_type;
|
||||||
PyTypeObject *writer_type;
|
PyTypeObject *writer_type;
|
||||||
long field_limit; /* max parsed field size */
|
Py_ssize_t field_limit; /* max parsed field size */
|
||||||
PyObject *str_write;
|
PyObject *str_write;
|
||||||
} _csvstate;
|
} _csvstate;
|
||||||
|
|
||||||
|
@ -706,10 +707,11 @@ parse_grow_buff(ReaderObj *self)
|
||||||
static int
|
static int
|
||||||
parse_add_char(ReaderObj *self, _csvstate *module_state, Py_UCS4 c)
|
parse_add_char(ReaderObj *self, _csvstate *module_state, Py_UCS4 c)
|
||||||
{
|
{
|
||||||
if (self->field_len >= module_state->field_limit) {
|
Py_ssize_t field_limit = FT_ATOMIC_LOAD_SSIZE_RELAXED(module_state->field_limit);
|
||||||
|
if (self->field_len >= field_limit) {
|
||||||
PyErr_Format(module_state->error_obj,
|
PyErr_Format(module_state->error_obj,
|
||||||
"field larger than field limit (%ld)",
|
"field larger than field limit (%zd)",
|
||||||
module_state->field_limit);
|
field_limit);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (self->field_len == self->field_size && !parse_grow_buff(self))
|
if (self->field_len == self->field_size && !parse_grow_buff(self))
|
||||||
|
@ -1659,20 +1661,20 @@ _csv_field_size_limit_impl(PyObject *module, PyObject *new_limit)
|
||||||
/*[clinic end generated code: output=f2799ecd908e250b input=cec70e9226406435]*/
|
/*[clinic end generated code: output=f2799ecd908e250b input=cec70e9226406435]*/
|
||||||
{
|
{
|
||||||
_csvstate *module_state = get_csv_state(module);
|
_csvstate *module_state = get_csv_state(module);
|
||||||
long old_limit = module_state->field_limit;
|
Py_ssize_t old_limit = FT_ATOMIC_LOAD_SSIZE_RELAXED(module_state->field_limit);
|
||||||
if (new_limit != NULL) {
|
if (new_limit != NULL) {
|
||||||
if (!PyLong_CheckExact(new_limit)) {
|
if (!PyLong_CheckExact(new_limit)) {
|
||||||
PyErr_Format(PyExc_TypeError,
|
PyErr_Format(PyExc_TypeError,
|
||||||
"limit must be an integer");
|
"limit must be an integer");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
module_state->field_limit = PyLong_AsLong(new_limit);
|
Py_ssize_t new_limit_value = PyLong_AsSsize_t(new_limit);
|
||||||
if (module_state->field_limit == -1 && PyErr_Occurred()) {
|
if (new_limit_value == -1 && PyErr_Occurred()) {
|
||||||
module_state->field_limit = old_limit;
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
FT_ATOMIC_STORE_SSIZE_RELAXED(module_state->field_limit, new_limit_value);
|
||||||
}
|
}
|
||||||
return PyLong_FromLong(old_limit);
|
return PyLong_FromSsize_t(old_limit);
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyType_Slot error_slots[] = {
|
static PyType_Slot error_slots[] = {
|
||||||
|
|
Loading…
Reference in New Issue