diff -r 311481a3aae7 Modules/_ssl.c --- a/Modules/_ssl.c Wed Aug 15 16:16:09 2012 +0200 +++ b/Modules/_ssl.c Wed Aug 15 16:26:27 2012 +0200 @@ -111,17 +111,70 @@ #include "_ssl_data.h" /* SSL error object */ -static PyObject *PySSLErrorObject; -static PyObject *PySSLZeroReturnErrorObject; -static PyObject *PySSLWantReadErrorObject; -static PyObject *PySSLWantWriteErrorObject; -static PyObject *PySSLSyscallErrorObject; -static PyObject *PySSLEOFErrorObject; +typedef struct { + PyObject *PySSLErrorObject; + PyObject *PySSLZeroReturnErrorObject; + PyObject *PySSLWantReadErrorObject; + PyObject *PySSLWantWriteErrorObject; + PyObject *PySSLSyscallErrorObject; + PyObject *PySSLEOFErrorObject; + PyObject *err_codes_to_names; + PyObject *err_names_to_codes; + PyObject *lib_codes_to_names; + PyObject *PySSLContext_Type; + PyObject *PySSLSocket_Type; +} _sslstate; + + +#define _ssl_state(o) ((_sslstate *)PyModule_GetState(o)) + +static int +_ssl_clear(PyObject *m) +{ + _sslstate *state = _ssl_state(m); + Py_CLEAR(state->PySSLErrorObject); + Py_CLEAR(state->PySSLZeroReturnErrorObject); + Py_CLEAR(state->PySSLWantReadErrorObject); + Py_CLEAR(state->PySSLWantWriteErrorObject); + Py_CLEAR(state->PySSLSyscallErrorObject); + Py_CLEAR(state->PySSLEOFErrorObject); + Py_CLEAR(state->err_codes_to_names); + Py_CLEAR(state->err_names_to_codes); + Py_CLEAR(state->lib_codes_to_names); + Py_CLEAR(state->PySSLContext_Type); + Py_CLEAR(state->PySSLSocket_Type); + return 0; +} + +static int +_ssl_traverse(PyObject *m, visitproc visit, void *arg) +{ + _sslstate *state = _ssl_state(m); + Py_VISIT(state->PySSLErrorObject); + Py_VISIT(state->PySSLZeroReturnErrorObject); + Py_VISIT(state->PySSLWantReadErrorObject); + Py_VISIT(state->PySSLWantWriteErrorObject); + Py_VISIT(state->PySSLSyscallErrorObject); + Py_VISIT(state->PySSLEOFErrorObject); + Py_VISIT(state->err_codes_to_names); + Py_VISIT(state->err_names_to_codes); + Py_VISIT(state->lib_codes_to_names); + Py_VISIT(state->PySSLContext_Type); + Py_VISIT(state->PySSLSocket_Type); + return 0; +} + +static void +_ssl_free(void *m) +{ + _ssl_clear((PyObject *)m); +} + +static PyModuleDef _sslmodule; + +#define _sslstate_global ((_sslstate *)PyModule_GetState(PyState_FindModule(&_sslmodule))) /* Error mappings */ -static PyObject *err_codes_to_names; -static PyObject *err_names_to_codes; -static PyObject *lib_codes_to_names; #ifdef WITH_THREAD @@ -192,8 +245,8 @@ enum py_ssl_server_or_client socket_type; } PySSLSocket; -static PyTypeObject PySSLContext_Type; -static PyTypeObject PySSLSocket_Type; + + static PyObject *PySSL_SSLwrite(PySSLSocket *self, PyObject *args); static PyObject *PySSL_SSLread(PySSLSocket *self, PyObject *args); @@ -202,8 +255,8 @@ static PyObject *PySSL_peercert(PySSLSocket *self, PyObject *args); static PyObject *PySSL_cipher(PySSLSocket *self); -#define PySSLContext_Check(v) (Py_TYPE(v) == &PySSLContext_Type) -#define PySSLSocket_Check(v) (Py_TYPE(v) == &PySSLSocket_Type) +#define PySSLContext_Check(v) (Py_TYPE(v) == _sslstate_global->PySSLContext_Type) +#define PySSLSocket_Check(v) (Py_TYPE(v) == _sslstate_global->PySSLSocket_Type) typedef enum { SOCKET_IS_NONBLOCKING, @@ -288,7 +341,7 @@ key = Py_BuildValue("ii", lib, reason); if (key == NULL) goto fail; - reason_obj = PyDict_GetItem(err_codes_to_names, key); + reason_obj = PyDict_GetItem(_sslstate_global->err_codes_to_names, key); Py_DECREF(key); if (reason_obj == NULL) { /* XXX if reason < 100, it might reflect a library number (!!) */ @@ -297,7 +350,7 @@ key = PyLong_FromLong(lib); if (key == NULL) goto fail; - lib_obj = PyDict_GetItem(lib_codes_to_names, key); + lib_obj = PyDict_GetItem(_sslstate_global->lib_codes_to_names, key); Py_DECREF(key); if (lib_obj == NULL) { PyErr_Clear(); @@ -340,7 +393,7 @@ static PyObject * PySSL_SetError(PySSLSocket *obj, int ret, char *filename, int lineno) { - PyObject *type = PySSLErrorObject; + PyObject *type = _sslstate_global->PySSLErrorObject; char *errstr = NULL; int err; enum py_ssl_error p = PY_SSL_ERROR_NONE; @@ -355,17 +408,17 @@ switch (err) { case SSL_ERROR_ZERO_RETURN: errstr = "TLS/SSL connection has been closed (EOF)"; - type = PySSLZeroReturnErrorObject; + type = _sslstate_global->PySSLZeroReturnErrorObject; p = PY_SSL_ERROR_ZERO_RETURN; break; case SSL_ERROR_WANT_READ: errstr = "The operation did not complete (read)"; - type = PySSLWantReadErrorObject; + type = _sslstate_global->PySSLWantReadErrorObject; p = PY_SSL_ERROR_WANT_READ; break; case SSL_ERROR_WANT_WRITE: p = PY_SSL_ERROR_WANT_WRITE; - type = PySSLWantWriteErrorObject; + type = _sslstate_global->PySSLWantWriteErrorObject; errstr = "The operation did not complete (write)"; break; case SSL_ERROR_WANT_X509_LOOKUP: @@ -383,7 +436,7 @@ = (PySocketSockObject *) PyWeakref_GetObject(obj->Socket); if (ret == 0 || (((PyObject *)s) == Py_None)) { p = PY_SSL_ERROR_EOF; - type = PySSLEOFErrorObject; + type = _sslstate_global->PySSLEOFErrorObject; errstr = "EOF occurred in violation of protocol"; } else if (ret == -1) { /* underlying BIO reported an I/O error */ @@ -394,7 +447,7 @@ return NULL; } else { /* possible? */ p = PY_SSL_ERROR_SYSCALL; - type = PySSLSyscallErrorObject; + type = _sslstate_global->PySSLSyscallErrorObject; errstr = "Some I/O error occurred"; } } else { @@ -427,7 +480,7 @@ errcode = ERR_peek_last_error(); else errcode = 0; - fill_and_set_sslerror(PySSLErrorObject, errcode, errstr, lineno, errcode); + fill_and_set_sslerror(_sslstate_global->PySSLErrorObject, errcode, errstr, lineno, errcode); ERR_clear_error(); return NULL; } @@ -443,10 +496,12 @@ { PySSLSocket *self; - self = PyObject_New(PySSLSocket, &PySSLSocket_Type); + self = PyObject_New(PySSLSocket, _sslstate_global->PySSLSocket_Type); if (self == NULL) return NULL; + Py_INCREF(_sslstate_global->PySSLSocket_Type); + self->peer_cert = NULL; self->ssl = NULL; self->Socket = NULL; @@ -531,11 +586,11 @@ ERRSTR("The handshake operation timed out")); goto error; } else if (sockstate == SOCKET_HAS_BEEN_CLOSED) { - PyErr_SetString(PySSLErrorObject, + PyErr_SetString(_sslstate_global->PySSLErrorObject, ERRSTR("Underlying socket has been closed.")); goto error; } else if (sockstate == SOCKET_TOO_LARGE_FOR_SELECT) { - PyErr_SetString(PySSLErrorObject, + PyErr_SetString(_sslstate_global->PySSLErrorObject, ERRSTR("Underlying socket too large for select().")); goto error; } else if (sockstate == SOCKET_IS_NONBLOCKING) { @@ -752,7 +807,7 @@ ext = X509_get_ext(certificate, i); if(!(method = X509V3_EXT_get(ext))) { PyErr_SetString - (PySSLErrorObject, + (_sslstate_global->PySSLErrorObject, ERRSTR("No method for internalizing subjectAltName!")); goto fail; } @@ -1003,20 +1058,20 @@ return NULL; if ((cert=BIO_new(BIO_s_file())) == NULL) { - PyErr_SetString(PySSLErrorObject, + PyErr_SetString(_sslstate_global->PySSLErrorObject, "Can't malloc memory to read file"); goto fail0; } if (BIO_read_filename(cert, PyBytes_AsString(filename)) <= 0) { - PyErr_SetString(PySSLErrorObject, + PyErr_SetString(_sslstate_global->PySSLErrorObject, "Can't open file"); goto fail0; } x = PEM_read_bio_X509_AUX(cert,NULL, NULL, NULL); if (x == NULL) { - PyErr_SetString(PySSLErrorObject, + PyErr_SetString(_sslstate_global->PySSLErrorObject, "Error decoding PEM-encoded file"); goto fail0; } @@ -1166,12 +1221,16 @@ static void PySSL_dealloc(PySSLSocket *self) { + PyTypeObject *type = Py_TYPE(self); if (self->peer_cert) /* Possible not to have one? */ X509_free (self->peer_cert); if (self->ssl) SSL_free(self->ssl); Py_XDECREF(self->Socket); PyObject_Del(self); + if((void *)type->tp_dealloc == (void *)PySSL_dealloc) { + Py_DECREF(type); + } } /* If the socket has a timeout, do a select()/poll() on the socket. @@ -1275,11 +1334,11 @@ "The write operation timed out"); goto error; } else if (sockstate == SOCKET_HAS_BEEN_CLOSED) { - PyErr_SetString(PySSLErrorObject, + PyErr_SetString(_sslstate_global->PySSLErrorObject, "Underlying socket has been closed."); goto error; } else if (sockstate == SOCKET_TOO_LARGE_FOR_SELECT) { - PyErr_SetString(PySSLErrorObject, + PyErr_SetString(_sslstate_global->PySSLErrorObject, "Underlying socket too large for select()."); goto error; } @@ -1303,7 +1362,7 @@ "The write operation timed out"); goto error; } else if (sockstate == SOCKET_HAS_BEEN_CLOSED) { - PyErr_SetString(PySSLErrorObject, + PyErr_SetString(_sslstate_global->PySSLErrorObject, "Underlying socket has been closed."); goto error; } else if (sockstate == SOCKET_IS_NONBLOCKING) { @@ -1410,7 +1469,7 @@ "The read operation timed out"); goto error; } else if (sockstate == SOCKET_TOO_LARGE_FOR_SELECT) { - PyErr_SetString(PySSLErrorObject, + PyErr_SetString(_sslstate_global->PySSLErrorObject, "Underlying socket too large for select()."); goto error; } else if (sockstate == SOCKET_HAS_BEEN_CLOSED) { @@ -1542,7 +1601,7 @@ goto error; } else if (sockstate == SOCKET_TOO_LARGE_FOR_SELECT) { - PyErr_SetString(PySSLErrorObject, + PyErr_SetString(_sslstate_global->PySSLErrorObject, "Underlying socket too large for select()."); goto error; } @@ -1630,38 +1689,21 @@ {NULL, NULL} }; -static PyTypeObject PySSLSocket_Type = { - PyVarObject_HEAD_INIT(NULL, 0) - "_ssl._SSLSocket", /*tp_name*/ - sizeof(PySSLSocket), /*tp_basicsize*/ - 0, /*tp_itemsize*/ - /* methods */ - (destructor)PySSL_dealloc, /*tp_dealloc*/ - 0, /*tp_print*/ - 0, /*tp_getattr*/ - 0, /*tp_setattr*/ - 0, /*tp_reserved*/ - 0, /*tp_repr*/ - 0, /*tp_as_number*/ - 0, /*tp_as_sequence*/ - 0, /*tp_as_mapping*/ - 0, /*tp_hash*/ - 0, /*tp_call*/ - 0, /*tp_str*/ - 0, /*tp_getattro*/ - 0, /*tp_setattro*/ - 0, /*tp_as_buffer*/ - Py_TPFLAGS_DEFAULT, /*tp_flags*/ - 0, /*tp_doc*/ - 0, /*tp_traverse*/ - 0, /*tp_clear*/ - 0, /*tp_richcompare*/ - 0, /*tp_weaklistoffset*/ - 0, /*tp_iter*/ - 0, /*tp_iternext*/ - PySSLMethods, /*tp_methods*/ +static PyType_Slot PySSLSocket_Type_slots[] = { + {Py_tp_dealloc, (destructor)PySSL_dealloc}, + {Py_tp_methods, PySSLMethods}, + {0, 0} }; +static PyType_Spec PySSLSocket_Type_spec = { + "_ssl._SSLSocket", + sizeof(PySSLSocket), + 0, + Py_TPFLAGS_DEFAULT, + PySSLSocket_Type_slots, +}; + + /* * _SSLContext objects @@ -1701,7 +1743,7 @@ return NULL; } if (ctx == NULL) { - PyErr_SetString(PySSLErrorObject, + PyErr_SetString(_sslstate_global->PySSLErrorObject, "failed to allocate SSL context"); return NULL; } @@ -1729,11 +1771,15 @@ static void context_dealloc(PySSLContext *self) { + PyTypeObject *type = Py_TYPE(self); SSL_CTX_free(self->ctx); #ifdef OPENSSL_NPN_NEGOTIATED PyMem_Free(self->npn_protocols); #endif - Py_TYPE(self)->tp_free(self); + type->tp_free(self); + if((void *)type->tp_dealloc == (void *)context_dealloc) { + Py_INCREF(type); + } } static PyObject * @@ -1750,7 +1796,7 @@ otherwise the error will be reported again when another SSL call is done. */ ERR_clear_error(); - PyErr_SetString(PySSLErrorObject, + PyErr_SetString(_sslstate_global->PySSLErrorObject, "No cipher can be selected."); return NULL; } @@ -1849,7 +1895,7 @@ case SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT: return PyLong_FromLong(PY_SSL_CERT_REQUIRED); } - PyErr_SetString(PySSLErrorObject, + PyErr_SetString(_sslstate_global->PySSLErrorObject, "invalid return value from SSL_CTX_get_verify_mode"); return NULL; } @@ -2333,47 +2379,23 @@ {NULL, NULL} /* sentinel */ }; -static PyTypeObject PySSLContext_Type = { - PyVarObject_HEAD_INIT(NULL, 0) - "_ssl._SSLContext", /*tp_name*/ - sizeof(PySSLContext), /*tp_basicsize*/ - 0, /*tp_itemsize*/ - (destructor)context_dealloc, /*tp_dealloc*/ - 0, /*tp_print*/ - 0, /*tp_getattr*/ - 0, /*tp_setattr*/ - 0, /*tp_reserved*/ - 0, /*tp_repr*/ - 0, /*tp_as_number*/ - 0, /*tp_as_sequence*/ - 0, /*tp_as_mapping*/ - 0, /*tp_hash*/ - 0, /*tp_call*/ - 0, /*tp_str*/ - 0, /*tp_getattro*/ - 0, /*tp_setattro*/ - 0, /*tp_as_buffer*/ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/ - 0, /*tp_doc*/ - 0, /*tp_traverse*/ - 0, /*tp_clear*/ - 0, /*tp_richcompare*/ - 0, /*tp_weaklistoffset*/ - 0, /*tp_iter*/ - 0, /*tp_iternext*/ - context_methods, /*tp_methods*/ - 0, /*tp_members*/ - context_getsetlist, /*tp_getset*/ - 0, /*tp_base*/ - 0, /*tp_dict*/ - 0, /*tp_descr_get*/ - 0, /*tp_descr_set*/ - 0, /*tp_dictoffset*/ - 0, /*tp_init*/ - 0, /*tp_alloc*/ - context_new, /*tp_new*/ +static PyType_Slot PySSLContext_Type_slots[] = { + {Py_tp_dealloc, (destructor)context_dealloc}, + {Py_tp_methods, context_methods}, + {Py_tp_getset, context_getsetlist}, + {Py_tp_new, context_new}, + {0, 0} }; +static PyType_Spec PySSLContext_Type_spec = { + "_ssl._SSLContext", + sizeof(PySSLContext), + 0, + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, + PySSLContext_Type_slots, +}; + + #ifdef HAVE_OPENSSL_RAND @@ -2427,7 +2449,7 @@ errstr = ERR_reason_error_string(err); v = Py_BuildValue("(ks)", err, errstr); if (v != NULL) { - PyErr_SetObject(PySSLErrorObject, v); + PyErr_SetObject(_sslstate_global->PySSLErrorObject, v); Py_DECREF(v); } return NULL; @@ -2488,7 +2510,7 @@ bytes = RAND_egd(PyBytes_AsString(path)); Py_DECREF(path); if (bytes == -1) { - PyErr_SetString(PySSLErrorObject, + PyErr_SetString(_sslstate_global->PySSLErrorObject, "EGD connection failed or EGD did not return " "enough data to seed the PRNG"); return NULL; @@ -2606,12 +2628,12 @@ PyModuleDef_HEAD_INIT, "_ssl", module_doc, - -1, + sizeof(_sslstate), PySSL_methods, NULL, - NULL, - NULL, - NULL + _ssl_traverse, + _ssl_clear, + _ssl_free }; @@ -2641,18 +2663,25 @@ PySocketModule_APIObject *socket_api; struct py_ssl_error_code *errcode; struct py_ssl_library_code *libcode; - - if (PyType_Ready(&PySSLContext_Type) < 0) - return NULL; - if (PyType_Ready(&PySSLSocket_Type) < 0) - return NULL; + _sslstate *state; m = PyModule_Create(&_sslmodule); if (m == NULL) return NULL; d = PyModule_GetDict(m); - /* Load _socket module and its C API */ + state = _ssl_state(m); + + state->PySSLContext_Type = PyType_FromSpec(&PySSLContext_Type_spec); + + if (state->PySSLContext_Type == NULL) + return NULL; + + state->PySSLSocket_Type = PyType_FromSpec(&PySSLSocket_Type_spec); + if (state->PySSLSocket_Type == NULL) + return NULL; + + /* Load _socket module and its C API */ socket_api = PySocketModule_ImportModuleAndAPI(); if (!socket_api) return NULL; @@ -2671,43 +2700,43 @@ /* Add symbols to module dict */ sslerror_type_slots[0].pfunc = PyExc_OSError; - PySSLErrorObject = PyType_FromSpec(&sslerror_type_spec); - if (PySSLErrorObject == NULL) + state->PySSLErrorObject = PyType_FromSpec(&sslerror_type_spec); + if (state->PySSLErrorObject == NULL) return NULL; - PySSLZeroReturnErrorObject = PyErr_NewExceptionWithDoc( + state->PySSLZeroReturnErrorObject = PyErr_NewExceptionWithDoc( "ssl.SSLZeroReturnError", SSLZeroReturnError_doc, - PySSLErrorObject, NULL); - PySSLWantReadErrorObject = PyErr_NewExceptionWithDoc( + state->PySSLErrorObject, NULL); + state->PySSLWantReadErrorObject = PyErr_NewExceptionWithDoc( "ssl.SSLWantReadError", SSLWantReadError_doc, - PySSLErrorObject, NULL); - PySSLWantWriteErrorObject = PyErr_NewExceptionWithDoc( + state->PySSLErrorObject, NULL); + state->PySSLWantWriteErrorObject = PyErr_NewExceptionWithDoc( "ssl.SSLWantWriteError", SSLWantWriteError_doc, - PySSLErrorObject, NULL); - PySSLSyscallErrorObject = PyErr_NewExceptionWithDoc( + state->PySSLErrorObject, NULL); + state->PySSLSyscallErrorObject = PyErr_NewExceptionWithDoc( "ssl.SSLSyscallError", SSLSyscallError_doc, - PySSLErrorObject, NULL); - PySSLEOFErrorObject = PyErr_NewExceptionWithDoc( + state->PySSLErrorObject, NULL); + state->PySSLEOFErrorObject = PyErr_NewExceptionWithDoc( "ssl.SSLEOFError", SSLEOFError_doc, - PySSLErrorObject, NULL); - if (PySSLZeroReturnErrorObject == NULL - || PySSLWantReadErrorObject == NULL - || PySSLWantWriteErrorObject == NULL - || PySSLSyscallErrorObject == NULL - || PySSLEOFErrorObject == NULL) + state->PySSLErrorObject, NULL); + if (state->PySSLZeroReturnErrorObject == NULL + || state->PySSLWantReadErrorObject == NULL + || state->PySSLWantWriteErrorObject == NULL + || state->PySSLSyscallErrorObject == NULL + || state->PySSLEOFErrorObject == NULL) return NULL; - if (PyDict_SetItemString(d, "SSLError", PySSLErrorObject) != 0 - || PyDict_SetItemString(d, "SSLZeroReturnError", PySSLZeroReturnErrorObject) != 0 - || PyDict_SetItemString(d, "SSLWantReadError", PySSLWantReadErrorObject) != 0 - || PyDict_SetItemString(d, "SSLWantWriteError", PySSLWantWriteErrorObject) != 0 - || PyDict_SetItemString(d, "SSLSyscallError", PySSLSyscallErrorObject) != 0 - || PyDict_SetItemString(d, "SSLEOFError", PySSLEOFErrorObject) != 0) + if (PyDict_SetItemString(d, "SSLError", state->PySSLErrorObject) != 0 + || PyDict_SetItemString(d, "SSLZeroReturnError", state->PySSLZeroReturnErrorObject) != 0 + || PyDict_SetItemString(d, "SSLWantReadError", state->PySSLWantReadErrorObject) != 0 + || PyDict_SetItemString(d, "SSLWantWriteError", state->PySSLWantWriteErrorObject) != 0 + || PyDict_SetItemString(d, "SSLSyscallError", state->PySSLSyscallErrorObject) != 0 + || PyDict_SetItemString(d, "SSLEOFError", state->PySSLEOFErrorObject) != 0) return NULL; if (PyDict_SetItemString(d, "_SSLContext", - (PyObject *)&PySSLContext_Type) != 0) + state->PySSLContext_Type) != 0) return NULL; if (PyDict_SetItemString(d, "_SSLSocket", - (PyObject *)&PySSLSocket_Type) != 0) + state->PySSLSocket_Type) != 0) return NULL; PyModule_AddIntConstant(m, "SSL_ERROR_ZERO_RETURN", PY_SSL_ERROR_ZERO_RETURN); @@ -2798,9 +2827,10 @@ PyModule_AddObject(m, "HAS_NPN", r); /* Mappings for error codes */ - err_codes_to_names = PyDict_New(); - err_names_to_codes = PyDict_New(); - if (err_codes_to_names == NULL || err_names_to_codes == NULL) + state->err_codes_to_names = PyDict_New(); + state->err_names_to_codes = PyDict_New(); + if (state->err_codes_to_names == NULL + || state->err_names_to_codes == NULL) return NULL; errcode = error_codes; while (errcode->mnemonic != NULL) { @@ -2809,21 +2839,23 @@ key = Py_BuildValue("ii", errcode->library, errcode->reason); if (mnemo == NULL || key == NULL) return NULL; - if (PyDict_SetItem(err_codes_to_names, key, mnemo)) + if (PyDict_SetItem(state->err_codes_to_names, key, mnemo)) return NULL; - if (PyDict_SetItem(err_names_to_codes, mnemo, key)) + if (PyDict_SetItem(state->err_names_to_codes, mnemo, key)) return NULL; Py_DECREF(key); Py_DECREF(mnemo); errcode++; } - if (PyModule_AddObject(m, "err_codes_to_names", err_codes_to_names)) + Py_INCREF(state->err_codes_to_names); + Py_INCREF(state->err_names_to_codes); + if (PyModule_AddObject(m, "err_codes_to_names", state->err_codes_to_names)) return NULL; - if (PyModule_AddObject(m, "err_names_to_codes", err_names_to_codes)) + if (PyModule_AddObject(m, "err_names_to_codes", state->err_names_to_codes)) return NULL; - lib_codes_to_names = PyDict_New(); - if (lib_codes_to_names == NULL) + state->lib_codes_to_names = PyDict_New(); + if (state->lib_codes_to_names == NULL) return NULL; libcode = library_codes; while (libcode->library != NULL) { @@ -2832,15 +2864,16 @@ mnemo = PyUnicode_FromString(libcode->library); if (key == NULL || mnemo == NULL) return NULL; - if (PyDict_SetItem(lib_codes_to_names, key, mnemo)) + if (PyDict_SetItem(state->lib_codes_to_names, key, mnemo)) return NULL; Py_DECREF(key); Py_DECREF(mnemo); libcode++; } - if (PyModule_AddObject(m, "lib_codes_to_names", lib_codes_to_names)) + Py_INCREF(state->lib_codes_to_names); + if (PyModule_AddObject(m, "lib_codes_to_names", state->lib_codes_to_names)) return NULL; - + /* OpenSSL version */ /* SSLeay() gives us the version of the library linked against, which could be different from the headers version.