mirror of
				https://github.com/python/cpython.git
				synced 2025-11-03 23:21:29 +00:00 
			
		
		
		
	gh-111972: Make Unicode name C APIcapsule initialization thread-safe (#112249)
This commit is contained in:
		
							parent
							
								
									81261fa67f
								
							
						
					
					
						commit
						0785c68559
					
				
					 3 changed files with 26 additions and 20 deletions
				
			
		| 
						 | 
					@ -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,11 +6048,7 @@ _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) {
 | 
					 | 
				
			||||||
                /* load the unicode data module */
 | 
					 | 
				
			||||||
                ucnhash_capi = (_PyUnicode_Name_CAPI *)PyCapsule_Import(
 | 
					 | 
				
			||||||
                                                PyUnicodeData_CAPSULE_NAME, 1);
 | 
					 | 
				
			||||||
            if (ucnhash_capi == NULL) {
 | 
					            if (ucnhash_capi == NULL) {
 | 
				
			||||||
                PyErr_SetString(
 | 
					                PyErr_SetString(
 | 
				
			||||||
                        PyExc_UnicodeError,
 | 
					                        PyExc_UnicodeError,
 | 
				
			||||||
| 
						 | 
					@ -6044,8 +6056,6 @@ _PyUnicode_DecodeUnicodeEscapeInternal(const char *s,
 | 
				
			||||||
                );
 | 
					                );
 | 
				
			||||||
                goto onError;
 | 
					                goto onError;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
                interp->unicode.ucnhash_capi = ucnhash_capi;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
            message = "malformed \\N character escape";
 | 
					            message = "malformed \\N character escape";
 | 
				
			||||||
            if (s >= end) {
 | 
					            if (s >= end) {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -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,14 +951,10 @@ 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(
 | 
					 | 
				
			||||||
                                            PyUnicodeData_CAPSULE_NAME, 1);
 | 
					 | 
				
			||||||
            if (!ucnhash_capi) {
 | 
					 | 
				
			||||||
            return NULL;
 | 
					            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" */
 | 
				
			||||||
            c = PyUnicode_READ_CHAR(object, i);
 | 
					            c = PyUnicode_READ_CHAR(object, i);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue