@@ -81,10 +81,10 @@ typedef struct py_ssl_error_code {
8181 int library , reason ;
8282} py_ssl_error_code ;
8383
84- struct py_ssl_library_code {
84+ typedef struct py_ssl_library_code {
8585 const char * library ;
8686 int code ;
87- };
87+ } py_ssl_library_code ;
8888
8989#if defined(MS_WINDOWS ) && defined(Py_DEBUG )
9090/* Debug builds on Windows rely on getting errno directly from OpenSSL.
@@ -479,20 +479,17 @@ static int
479479ssl_error_fetch_lib_and_reason (_sslmodulestate * state , py_ssl_errcode errcode ,
480480 PyObject * * lib , PyObject * * reason )
481481{
482- int rc ;
483- PyObject * key = NULL ;
484482 int errlib = ERR_GET_LIB (errcode );
485483 int errrea = ERR_GET_REASON (errcode );
486484
487- key = PyLong_FromLong (errlib );
488- if (key == NULL ) {
489- return -1 ;
490- }
491- rc = PyDict_GetItemRef (state -> lib_codes_to_names , key , lib );
492- Py_DECREF (key );
493- if (rc < 0 ) {
485+ const void * key1 = (const void * )((uintptr_t )errlib );
486+ const void * val1 = _Py_hashtable_get (state -> lib_codes_to_names , key1 );
487+ if (val1 == NULL ) {
488+ * lib = NULL ;
494489 return -1 ;
495490 }
491+ assert (PyUnicode_CheckExact (val1 ));
492+ * lib = Py_NewRef ((PyObject * )val1 );
496493
497494 const void * key2 = (const void * )((uintptr_t )ERR_PACK (errlib , 0 , errrea ));
498495 const void * val2 = _Py_hashtable_get (state -> err_codes_to_names , key2 );
@@ -6874,36 +6871,66 @@ py_ht_errcode_to_name_create(void) {
68746871 return NULL ;
68756872}
68766873
6874+ /* internal hashtable (libcode) => (libname [PyObject * (unicode)]) */
6875+ static Py_uhash_t
6876+ py_ht_libcode_to_name_hash (const void * key ) {
6877+ return (Py_uhash_t )((uintptr_t )key );
6878+ }
6879+
6880+ static int
6881+ py_ht_libcode_to_name_comp (const void * a , const void * b ) {
6882+ return (uintptr_t )a == (uintptr_t )b ;
6883+ }
6884+
6885+ static void
6886+ py_ht_libcode_to_name_free (void * value ) {
6887+ assert (PyUnicode_CheckExact ((PyObject * )value ));
6888+ Py_CLEAR (value );
6889+ }
6890+
6891+ static _Py_hashtable_t *
6892+ py_ht_libcode_to_name_create (void ) {
6893+ _Py_hashtable_t * table = _Py_hashtable_new_full (
6894+ py_ht_libcode_to_name_hash ,
6895+ py_ht_libcode_to_name_comp ,
6896+ NULL ,
6897+ py_ht_libcode_to_name_free ,
6898+ NULL
6899+ );
6900+ if (table == NULL ) {
6901+ PyErr_NoMemory ();
6902+ return NULL ;
6903+ }
6904+
6905+ for (const py_ssl_library_code * p = library_codes ; p -> library != NULL ; p ++ ) {
6906+ const void * key = (const void * )((uintptr_t )p -> code );
6907+ PyObject * value = PyUnicode_FromString (p -> library );
6908+ if (value == NULL ) {
6909+ goto error ;
6910+ }
6911+ if (_Py_hashtable_set (table , key , value ) < 0 ) {
6912+ Py_DECREF (value );
6913+ goto error ;
6914+ }
6915+ }
6916+ return table ;
6917+ error :
6918+ _Py_hashtable_destroy (table );
6919+ return NULL ;
6920+ }
6921+
68776922static int
68786923sslmodule_init_errorcodes (PyObject * module )
68796924{
68806925 _sslmodulestate * state = get_ssl_state (module );
6881-
6882- struct py_ssl_library_code * libcode ;
6883-
6884- /* Mappings for error codes */
68856926 state -> err_codes_to_names = py_ht_errcode_to_name_create ();
68866927 if (state -> err_codes_to_names == NULL ) {
68876928 return -1 ;
68886929 }
6889- state -> lib_codes_to_names = PyDict_New ();
6890- if (state -> lib_codes_to_names == NULL )
6930+ state -> lib_codes_to_names = py_ht_libcode_to_name_create ();
6931+ if (state -> lib_codes_to_names == NULL ) {
68916932 return -1 ;
6892-
6893- libcode = library_codes ;
6894- while (libcode -> library != NULL ) {
6895- PyObject * mnemo , * key ;
6896- key = PyLong_FromLong (libcode -> code );
6897- mnemo = PyUnicode_FromString (libcode -> library );
6898- if (key == NULL || mnemo == NULL )
6899- return -1 ;
6900- if (PyDict_SetItem (state -> lib_codes_to_names , key , mnemo ))
6901- return -1 ;
6902- Py_DECREF (key );
6903- Py_DECREF (mnemo );
6904- libcode ++ ;
69056933 }
6906-
69076934 return 0 ;
69086935}
69096936
@@ -7072,7 +7099,6 @@ sslmodule_traverse(PyObject *m, visitproc visit, void *arg)
70727099 Py_VISIT (state -> PySSLWantWriteErrorObject );
70737100 Py_VISIT (state -> PySSLSyscallErrorObject );
70747101 Py_VISIT (state -> PySSLEOFErrorObject );
7075- Py_VISIT (state -> lib_codes_to_names );
70767102 Py_VISIT (state -> Sock_Type );
70777103
70787104 return 0 ;
@@ -7099,8 +7125,10 @@ sslmodule_clear(PyObject *m)
70997125 _Py_hashtable_destroy (state -> err_codes_to_names );
71007126 state -> err_codes_to_names = NULL ;
71017127 }
7102-
7103- Py_CLEAR (state -> lib_codes_to_names );
7128+ if (state -> lib_codes_to_names != NULL ) {
7129+ _Py_hashtable_destroy (state -> lib_codes_to_names );
7130+ state -> lib_codes_to_names = NULL ;
7131+ }
71047132 Py_CLEAR (state -> Sock_Type );
71057133 Py_CLEAR (state -> str_library );
71067134 Py_CLEAR (state -> str_reason );
0 commit comments