Skip to content
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Pedantically use int32_t instead of int for max.
  • Loading branch information
gpshead committed Sep 4, 2022
commit 67c9af4270ca11353f21e297b5c272503d28376a
3 changes: 3 additions & 0 deletions Include/internal/pycore_initconfig.h
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,9 @@ PyAPI_FUNC(PyStatus) _PyArgv_AsWstrList(const _PyArgv *args,
PyAPI_FUNC(int) _Py_str_to_int(
const char *str,
int *result);
PyAPI_FUNC(int) _Py_str_to_int32(
const char *str,
int32_t *result);
PyAPI_FUNC(const wchar_t*) _Py_get_xoption(
const PyWideStringList *xoptions,
const wchar_t *name);
Expand Down
2 changes: 1 addition & 1 deletion Include/internal/pycore_interp.h
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ struct _is {
struct types_state types;
struct callable_cache callable_cache;

int int_max_str_digits;
int32_t int_max_str_digits;

/* The following fields are here to avoid allocation during init.
The data is exposed through PyInterpreterState pointer fields.
Expand Down
6 changes: 3 additions & 3 deletions Objects/longobject.c
Original file line number Diff line number Diff line change
Expand Up @@ -1767,7 +1767,7 @@ long_to_decimal_string_internal(PyObject *aa,
if (size_a >= 10 * _PY_LONG_MAX_STR_DIGITS_THRESHOLD
/ (3 * PyLong_SHIFT) + 2) {
PyInterpreterState *interp = _PyInterpreterState_GET();
int max_str_digits = interp->int_max_str_digits;
int32_t max_str_digits = interp->int_max_str_digits;
if ((max_str_digits > 0) &&
(max_str_digits / (3 * PyLong_SHIFT) <= (size_a - 11) / 10)) {
PyErr_Format(PyExc_ValueError, _MAX_STR_DIGITS_ERROR_FMT_TO_STR,
Expand Down Expand Up @@ -1837,7 +1837,7 @@ long_to_decimal_string_internal(PyObject *aa,
}
if (strlen > _PY_LONG_MAX_STR_DIGITS_THRESHOLD) {
PyInterpreterState *interp = _PyInterpreterState_GET();
int max_str_digits = interp->int_max_str_digits;
int32_t max_str_digits = interp->int_max_str_digits;
Py_ssize_t strlen_nosign = strlen - negative;
if ((max_str_digits > 0) && (strlen_nosign > max_str_digits)) {
Py_DECREF(scratch);
Expand Down Expand Up @@ -2514,7 +2514,7 @@ digit beyond the first.
/* Limit the size to avoid excessive computation attacks. */
if (digits > _PY_LONG_MAX_STR_DIGITS_THRESHOLD) {
PyInterpreterState *interp = _PyInterpreterState_GET();
int max_str_digits = interp->int_max_str_digits;
int32_t max_str_digits = interp->int_max_str_digits;
if ((max_str_digits > 0) && (digits > max_str_digits)) {
PyErr_Format(PyExc_ValueError, _MAX_STR_DIGITS_ERROR_FMT_TO_INT,
max_str_digits, digits);
Expand Down
8 changes: 4 additions & 4 deletions Python/clinic/sysmodule.c.h

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

30 changes: 26 additions & 4 deletions Python/initconfig.c
Original file line number Diff line number Diff line change
Expand Up @@ -1630,6 +1630,28 @@ config_wstr_to_int(const wchar_t *wstr, int *result)
}


static int
config_wstr_to_int32(const wchar_t *wstr, int32_t *result)
{
#if INT32_MAX == INT_MAX && INT32_MIN == INT_MIN
return config_wstr_to_int(wstr, result);
#else
const wchar_t *endptr = wstr;
errno = 0;
long value = wcstol(wstr, (wchar_t **)&endptr, 10);
if (*endptr != '\0' || errno == ERANGE) {
return -1;
}
if (value < INT32_MIN || value > INT32_MAX) {
return -1;
}

*result = (int32_t)value;
return 0;
#endif
}


static PyStatus
config_read_env_vars(PyConfig *config)
{
Expand Down Expand Up @@ -1778,15 +1800,15 @@ config_init_tracemalloc(PyConfig *config)
static PyStatus
config_init_int_max_str_digits(PyConfig *config)
{
int maxdigits;
int valid = 0;
int32_t maxdigits;
bool valid = 0;

/* default to unconfigured, _PyLong_InitTypes() does the rest */
config->int_max_str_digits = -1;
Comment thread
gpshead marked this conversation as resolved.

const char *env = config_get_env(config, "PYTHONINTMAXSTRDIGITS");
if (env) {
if (!_Py_str_to_int(env, &maxdigits)) {
if (!_Py_str_to_int32(env, &maxdigits)) {
valid = ((maxdigits == 0) || (maxdigits >= _PY_LONG_MAX_STR_DIGITS_THRESHOLD));
}
if (!valid) {
Expand All @@ -1804,7 +1826,7 @@ config_init_int_max_str_digits(PyConfig *config)
if (xoption) {
const wchar_t *sep = wcschr(xoption, L'=');
if (sep) {
if (!config_wstr_to_int(sep + 1, &maxdigits)) {
if (!config_wstr_to_int32(sep + 1, &maxdigits)) {
valid = ((maxdigits == 0) || (maxdigits >= _PY_LONG_MAX_STR_DIGITS_THRESHOLD));
}
}
Expand Down
22 changes: 22 additions & 0 deletions Python/preconfig.c
Original file line number Diff line number Diff line change
Expand Up @@ -559,6 +559,28 @@ _Py_str_to_int(const char *str, int *result)
}


int
_Py_str_to_int32(const char *str, int32_t *result)
{
#if INT32_MAX == INT_MAX && INT32_MIN == INT_MIN
return _Py_str_to_int(str, result);
#else
const char *endptr = str;
errno = 0;
long value = strtol(str, (char **)&endptr, 10);
if (*endptr != '\0' || errno == ERANGE) {
return -1;
}
if (value < INT32_MIN || value > INT32_MAX) {
return -1;
}

*result = (int32_t)value;
return 0;
#endif
}


void
_Py_get_env_flag(int use_environment, int *flag, const char *name)
{
Expand Down
12 changes: 8 additions & 4 deletions Python/sysmodule.c
Original file line number Diff line number Diff line change
Expand Up @@ -1684,23 +1684,27 @@ sys_get_int_max_str_digits_impl(PyObject *module)
/*[clinic end generated code: output=0042f5e8ae0e8631 input=8dab13e2023e60d5]*/
{
PyInterpreterState *interp = _PyInterpreterState_GET();
return PyLong_FromSsize_t(interp->int_max_str_digits);
return PyLong_FromLong(interp->int_max_str_digits);
}

/*[clinic input]
sys.set_int_max_str_digits

maxdigits: int
maxdigits: long

Set the maximum string digits limit for non-binary int<->str conversions.
[clinic start generated code]*/

static PyObject *
sys_set_int_max_str_digits_impl(PyObject *module, int maxdigits)
/*[clinic end generated code: output=734d4c2511f2a56d input=d7e3f325db6910c5]*/
sys_set_int_max_str_digits_impl(PyObject *module, long maxdigits)
/*[clinic end generated code: output=40ea5d33a82c5c44 input=657c61a1822f6bcf]*/
{
PyThreadState *tstate = _PyThreadState_GET();
if ((!maxdigits) || (maxdigits >= _PY_LONG_MAX_STR_DIGITS_THRESHOLD)) {
if (maxdigits > INT32_MAX) {
/* Silently cap to our range; already effectively unlimited. */
maxdigits = INT32_MAX;
}
tstate->interp->int_max_str_digits = maxdigits;
Py_RETURN_NONE;
} else {
Expand Down