crystal
crystal copied to clipboard
XML: modernize API when available & workaround issues with legacy versions
Uses the libxml per context error handlers when available.
For example we can always use it for XML::Reader since it's available since at least libxml 2.9 (released in 2012), that becomes the default expected libxml version.
Sadly the other per context error handlers only appeared in libxml 2.13 (released in 2024) so we can't assume they exist, but can still use them when compiling against this version.
This patch adds a libxml version detection using pkg-config. We can specify the LIBXML_VERSION environment variable to target another release if the runtime version will be different (though it is highly recommended to use libxml 2.13+), or for the Windows MSVC target.
On older libxml releases, errors can be raised per context (e.g. xml reader) and through the structured error handler (now deprecated) and the older generic (long deprecated).
For these older releases, this patch still sets the globals (actually thread locals), be they error handlers or some xml save configuration, but saves them when the fiber might yield, restoring the default handlers; it eventually restores the globals when the fiber is resumed, so the current thread will see the values previously configured for the fiber, whatever if another fiber did something else, or the fiber got resumed by another thread (execution context).
~~NOTE: libxml 2.14 almost always segfaults during GC while running spec/std/xml, while the 2.9 to 2.13 releases are fine.~~ fixed in #15906.