From c2e705e650bc5569a7ea3b7c7ebace23538be808 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20P=C3=ADsa=C5=99?= Date: Tue, 28 Nov 2023 15:35:10 +0100 Subject: [PATCH 2/2] Fix copying external entity from an ext_ent_handler handler MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit With libxml2-2.12.0 and perl-5.38.0 t/44extent.t failed: $ perl -Iblib/{lib,arch} ./t/44extent.t 1..7 Entity: line 1: parser error : Char 0x0 out of allowed range pseudoroot ^ Entity: line 1: parser error : PCDATA invalid Char value 0 pseudoroot ^ [...] :8: parser error : Entity 'b' failed to parse &b; ^ # Looks like your test exited with 2 before it could output anything. The cause was xmlParserInputBufferCreateMem() which does not copy a supplied buffer. A string returned by the ext_ent_handler handler. As a result, libxml2 read from a deallocated memory parsing random garbage. This patch fixes it by copying the string with xmlParserInputBufferPush(). https://github.com/shlomif/perl-XML-LibXML/issues/81 Signed-off-by: Petr Písař --- LibXML.xs | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/LibXML.xs b/LibXML.xs index b5b0b95..7e21ea8 100644 --- a/LibXML.xs +++ b/LibXML.xs @@ -25,6 +25,7 @@ extern "C" { #include "Av_CharPtrPtr.h" /* XS_*_charPtrPtr() */ #include +#include /* INT_MAX */ #ifndef WIN32 #include @@ -869,11 +870,17 @@ LibXML_load_external_entity( results = POPs; results_pv = SvPV(results, results_len); - input_buf = xmlParserInputBufferCreateMem( - results_pv, - results_len, - XML_CHAR_ENCODING_NONE - ); + if (results_len > INT_MAX) { + croak("a buffer would be too big\n"); + } + input_buf = xmlAllocParserInputBuffer(XML_CHAR_ENCODING_NONE); + if (!input_buf) { + croak("cannot create a buffer!\n"); + } + if (-1 == xmlParserInputBufferPush(input_buf, (int)results_len, results_pv)) { + xmlFreeParserInputBuffer(input_buf); + croak("cannot push an external entity into a buffer!\n"); + } PUTBACK; FREETMPS; -- 2.42.0