Skip to content

Commit 5e8b4e6

Browse files
authored
Bump xmlsec1 unix lib to 1.3.11 (#422)
xmlsec1 1.3.11 may call OPENSSL_cleanup() from the OpenSSL backend during shutdown. OpenSSL cannot be reinitialized in the same process after that cleanup runs. Update the lifecycle test to call init() before shutdown(), run it last, and stop testing shutdown/init reinitialization. Document the new lifecycle constraint in the module docs and runtime docstrings. See lsh123/xmlsec#1148 for details.
1 parent 6e1baf2 commit 5e8b4e6

6 files changed

Lines changed: 37 additions & 15 deletions

File tree

.github/workflows/cache_libs.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ on:
2020
required: false
2121
type: string
2222
XMLSEC1_VERSION:
23-
default: "1.3.10"
23+
default: "1.3.11"
2424
required: false
2525
type: string
2626
ZLIB_VERSION:

build_support/lib_xmlsec_dependency_builder.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ class LibXmlsecDependencyBuilder:
5050
'libxml2_version': '2.14.6', # Make sure it matches with lxml
5151
'libxslt_version': '1.1.43',
5252
'openssl_version': '3.6.0',
53-
'xmlsec1_version': '1.3.10',
53+
'xmlsec1_version': '1.3.11',
5454
'zlib_version': '1.3.1',
5555
}
5656
WINDOWS_DEFAULT_LIB_VERSIONS: ClassVar[dict[str, str]] = {

doc/source/modules/xmlsec.rst

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,17 @@
11
``xmlsec``
22
----------
33

4+
Lifecycle
5+
~~~~~~~~~
6+
7+
The module initializes the underlying xmlsec library on import. Applications
8+
that call :func:`xmlsec.shutdown` should treat it as process-final and should
9+
not call :func:`xmlsec.init` afterwards.
10+
11+
This is required because upstream xmlsec1 versions starting with 1.3.11 may
12+
call ``OPENSSL_cleanup()`` during shutdown when using the OpenSSL backend.
13+
OpenSSL cannot be reinitialized in the same process after that cleanup has run.
14+
415
.. automodule:: xmlsec
516
:members:
617
:undoc-members:

src/main.c

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -101,8 +101,11 @@ static int PyXmlSec_Init(void) {
101101
static char PyXmlSec_PyInit__doc__[] = \
102102
"init() -> None\n"
103103
"Initializes the library for general operation.\n\n"
104-
"This is called upon library import and does not need to be called\n"
105-
"again :func:`~.shutdown` is called explicitly).\n";
104+
"This is called upon library import and normally does not need to be\n"
105+
"called explicitly. It is only valid before shutdown() has been called.\n\n"
106+
"Calling init() after shutdown() is unsupported because upstream\n"
107+
"xmlsec1 1.3.11+ may call OPENSSL_cleanup() during shutdown, and OpenSSL\n"
108+
"cannot be reinitialized in the same process after that cleanup.\n";
106109
static PyObject* PyXmlSec_PyInit(PyObject *self) {
107110
if (PyXmlSec_Init() < 0) {
108111
return NULL;
@@ -114,7 +117,11 @@ static char PyXmlSec_PyShutdown__doc__[] = \
114117
"shutdown() -> None\n"
115118
"Shutdowns the library and cleanup any leftover resources.\n\n"
116119
"This is called automatically upon interpreter termination and\n"
117-
"should not need to be called explicitly.";
120+
"should not need to be called explicitly.\n\n"
121+
"Shutdown is process-final. Do not call init() after shutdown(),\n"
122+
"because upstream xmlsec1 1.3.11+ may call OPENSSL_cleanup() during shutdown,\n"
123+
"and OpenSSL cannot be reinitialized in the same process after that\n"
124+
"cleanup.";
118125
static PyObject* PyXmlSec_PyShutdown(PyObject* self) {
119126
PyXmlSec_Free(free_mode);
120127
Py_RETURN_NONE;

tests/conftest.py

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
def pytest_collection_modifyitems(items):
2-
"""Put the module init test first.
2+
"""Put the module shutdown test last.
33
4-
This way, we implicitly check whether any subsequent test fails because of module reinitialization.
4+
xmlsec shutdown is process-final with OpenSSL cleanup introduced in
5+
xmlsec1 1.3.11, so no tests should use xmlsec after it runs.
56
"""
67

7-
def module_init_tests_first(item):
8-
return int('test_xmlsec.py::TestModule::test_reinitialize_module' not in item.nodeid)
8+
def module_init_shutdown_tests_last(item):
9+
return int('test_xmlsec.py::TestModule::test_init_shutdown_module' in item.nodeid)
910

10-
items.sort(key=module_init_tests_first)
11+
items.sort(key=module_init_shutdown_tests_last)

tests/test_xmlsec.py

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,14 @@
33

44

55
class TestModule(base.TestMemoryLeaks):
6-
def test_reinitialize_module(self):
7-
"""This test doesn't explicitly verify anything, but will be invoked first in the suite.
6+
iterations = 0
87

9-
So if the subsequent tests don't fail, we know that the ``init()``/``shutdown()``
10-
function pair doesn't break anything.
8+
def test_init_shutdown_module(self):
9+
"""Check explicit initialization before final module shutdown.
10+
11+
This test is invoked last because shutdown is process-final: since
12+
xmlsec1 1.3.11, its OpenSSL backend may call OPENSSL_cleanup(), after
13+
which OpenSSL cannot be reinitialized in the same process.
1114
"""
12-
xmlsec.shutdown()
1315
xmlsec.init()
16+
xmlsec.shutdown()

0 commit comments

Comments
 (0)