mirror of https://github.com/python/cpython.git
gh-111972: Make Unicode name C APIcapsule initialization thread-safe (#112249)
This commit is contained in:
parent
81261fa67f
commit
0785c68559
|
@ -28,6 +28,8 @@ typedef struct {
|
||||||
|
|
||||||
} _PyUnicode_Name_CAPI;
|
} _PyUnicode_Name_CAPI;
|
||||||
|
|
||||||
|
extern _PyUnicode_Name_CAPI* _PyUnicode_GetNameCAPI(void);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -5869,6 +5869,23 @@ PyUnicode_AsUTF16String(PyObject *unicode)
|
||||||
return _PyUnicode_EncodeUTF16(unicode, NULL, 0);
|
return _PyUnicode_EncodeUTF16(unicode, NULL, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_PyUnicode_Name_CAPI *
|
||||||
|
_PyUnicode_GetNameCAPI(void)
|
||||||
|
{
|
||||||
|
PyInterpreterState *interp = _PyInterpreterState_GET();
|
||||||
|
_PyUnicode_Name_CAPI *ucnhash_capi;
|
||||||
|
|
||||||
|
ucnhash_capi = _Py_atomic_load_ptr(&interp->unicode.ucnhash_capi);
|
||||||
|
if (ucnhash_capi == NULL) {
|
||||||
|
ucnhash_capi = (_PyUnicode_Name_CAPI *)PyCapsule_Import(
|
||||||
|
PyUnicodeData_CAPSULE_NAME, 1);
|
||||||
|
|
||||||
|
// It's fine if we overwite the value here. It's always the same value.
|
||||||
|
_Py_atomic_store_ptr(&interp->unicode.ucnhash_capi, ucnhash_capi);
|
||||||
|
}
|
||||||
|
return ucnhash_capi;
|
||||||
|
}
|
||||||
|
|
||||||
/* --- Unicode Escape Codec ----------------------------------------------- */
|
/* --- Unicode Escape Codec ----------------------------------------------- */
|
||||||
|
|
||||||
PyObject *
|
PyObject *
|
||||||
|
@ -5884,7 +5901,6 @@ _PyUnicode_DecodeUnicodeEscapeInternal(const char *s,
|
||||||
PyObject *errorHandler = NULL;
|
PyObject *errorHandler = NULL;
|
||||||
PyObject *exc = NULL;
|
PyObject *exc = NULL;
|
||||||
_PyUnicode_Name_CAPI *ucnhash_capi;
|
_PyUnicode_Name_CAPI *ucnhash_capi;
|
||||||
PyInterpreterState *interp = _PyInterpreterState_GET();
|
|
||||||
|
|
||||||
// so we can remember if we've seen an invalid escape char or not
|
// so we can remember if we've seen an invalid escape char or not
|
||||||
*first_invalid_escape = NULL;
|
*first_invalid_escape = NULL;
|
||||||
|
@ -6032,19 +6048,13 @@ _PyUnicode_DecodeUnicodeEscapeInternal(const char *s,
|
||||||
|
|
||||||
/* \N{name} */
|
/* \N{name} */
|
||||||
case 'N':
|
case 'N':
|
||||||
ucnhash_capi = interp->unicode.ucnhash_capi;
|
ucnhash_capi = _PyUnicode_GetNameCAPI();
|
||||||
if (ucnhash_capi == NULL) {
|
if (ucnhash_capi == NULL) {
|
||||||
/* load the unicode data module */
|
PyErr_SetString(
|
||||||
ucnhash_capi = (_PyUnicode_Name_CAPI *)PyCapsule_Import(
|
|
||||||
PyUnicodeData_CAPSULE_NAME, 1);
|
|
||||||
if (ucnhash_capi == NULL) {
|
|
||||||
PyErr_SetString(
|
|
||||||
PyExc_UnicodeError,
|
PyExc_UnicodeError,
|
||||||
"\\N escapes not supported (can't load unicodedata module)"
|
"\\N escapes not supported (can't load unicodedata module)"
|
||||||
);
|
);
|
||||||
goto onError;
|
goto onError;
|
||||||
}
|
|
||||||
interp->unicode.ucnhash_capi = ucnhash_capi;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
message = "malformed \\N character escape";
|
message = "malformed \\N character escape";
|
||||||
|
|
|
@ -931,8 +931,6 @@ PyObject *PyCodec_BackslashReplaceErrors(PyObject *exc)
|
||||||
return Py_BuildValue("(Nn)", res, end);
|
return Py_BuildValue("(Nn)", res, end);
|
||||||
}
|
}
|
||||||
|
|
||||||
static _PyUnicode_Name_CAPI *ucnhash_capi = NULL;
|
|
||||||
|
|
||||||
PyObject *PyCodec_NameReplaceErrors(PyObject *exc)
|
PyObject *PyCodec_NameReplaceErrors(PyObject *exc)
|
||||||
{
|
{
|
||||||
if (PyObject_TypeCheck(exc, (PyTypeObject *)PyExc_UnicodeEncodeError)) {
|
if (PyObject_TypeCheck(exc, (PyTypeObject *)PyExc_UnicodeEncodeError)) {
|
||||||
|
@ -953,13 +951,9 @@ PyObject *PyCodec_NameReplaceErrors(PyObject *exc)
|
||||||
return NULL;
|
return NULL;
|
||||||
if (!(object = PyUnicodeEncodeError_GetObject(exc)))
|
if (!(object = PyUnicodeEncodeError_GetObject(exc)))
|
||||||
return NULL;
|
return NULL;
|
||||||
if (!ucnhash_capi) {
|
_PyUnicode_Name_CAPI *ucnhash_capi = _PyUnicode_GetNameCAPI();
|
||||||
/* load the unicode data module */
|
if (ucnhash_capi == NULL) {
|
||||||
ucnhash_capi = (_PyUnicode_Name_CAPI *)PyCapsule_Import(
|
return NULL;
|
||||||
PyUnicodeData_CAPSULE_NAME, 1);
|
|
||||||
if (!ucnhash_capi) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
for (i = start, ressize = 0; i < end; ++i) {
|
for (i = start, ressize = 0; i < end; ++i) {
|
||||||
/* object is guaranteed to be "ready" */
|
/* object is guaranteed to be "ready" */
|
||||||
|
|
Loading…
Reference in New Issue