Compare commits
No commits in common. "c8s" and "c9-beta" have entirely different histories.
@ -1 +0,0 @@
|
||||
1
|
||||
52
.gitignore
vendored
52
.gitignore
vendored
@ -1,51 +1 @@
|
||||
XML-LibXML-1.70.tar.gz
|
||||
/XML-LibXML-1.74.tar.gz
|
||||
/XML-LibXML-1.88.tar.gz
|
||||
/XML-LibXML-1.90.tar.gz
|
||||
/XML-LibXML-1.92.tar.gz
|
||||
/XML-LibXML-1.93.tar.gz
|
||||
/XML-LibXML-1.95.tar.gz
|
||||
/XML-LibXML-1.96.tar.gz
|
||||
/XML-LibXML-1.97.tar.gz
|
||||
/XML-LibXML-1.98.tar.gz
|
||||
/XML-LibXML-1.99.tar.gz
|
||||
/XML-LibXML-2.0001.tar.gz
|
||||
/XML-LibXML-2.0002.tar.gz
|
||||
/XML-LibXML-2.0003.tar.gz
|
||||
/XML-LibXML-2.0004.tar.gz
|
||||
/XML-LibXML-2.0006.tar.gz
|
||||
/XML-LibXML-2.0007.tar.gz
|
||||
/XML-LibXML-2.0008.tar.gz
|
||||
/XML-LibXML-2.0010.tar.gz
|
||||
/XML-LibXML-2.0012.tar.gz
|
||||
/XML-LibXML-2.0014.tar.gz
|
||||
/XML-LibXML-2.0016.tar.gz
|
||||
/XML-LibXML-2.0017.tar.gz
|
||||
/XML-LibXML-2.0018.tar.gz
|
||||
/XML-LibXML-2.0019.tar.gz
|
||||
/XML-LibXML-2.0101.tar.gz
|
||||
/XML-LibXML-2.0103.tar.gz
|
||||
/XML-LibXML-2.0104.tar.gz
|
||||
/XML-LibXML-2.0105.tar.gz
|
||||
/XML-LibXML-2.0106.tar.gz
|
||||
/XML-LibXML-2.0107.tar.gz
|
||||
/XML-LibXML-2.0108.tar.gz
|
||||
/XML-LibXML-2.0110.tar.gz
|
||||
/XML-LibXML-2.0111.tar.gz
|
||||
/XML-LibXML-2.0113.tar.gz
|
||||
/XML-LibXML-2.0115.tar.gz
|
||||
/XML-LibXML-2.0116.tar.gz
|
||||
/XML-LibXML-2.0117.tar.gz
|
||||
/XML-LibXML-2.0118.tar.gz
|
||||
/XML-LibXML-2.0119.tar.gz
|
||||
/XML-LibXML-2.0121.tar.gz
|
||||
/XML-LibXML-2.0122.tar.gz
|
||||
/XML-LibXML-2.0123.tar.gz
|
||||
/XML-LibXML-2.0124.tar.gz
|
||||
/XML-LibXML-2.0125.tar.gz
|
||||
/XML-LibXML-2.0126.tar.gz
|
||||
/XML-LibXML-2.0128.tar.gz
|
||||
/XML-LibXML-2.0129.tar.gz
|
||||
/XML-LibXML-2.0130.tar.gz
|
||||
/XML-LibXML-2.0131.tar.gz
|
||||
/XML-LibXML-2.0132.tar.gz
|
||||
SOURCES/XML-LibXML-2.0206.tar.gz
|
||||
|
||||
1
.perl-XML-LibXML.metadata
Normal file
1
.perl-XML-LibXML.metadata
Normal file
@ -0,0 +1 @@
|
||||
b71a0f66a2503ce4ed19eeece4f6e92d9a703cb4 SOURCES/XML-LibXML-2.0206.tar.gz
|
||||
@ -0,0 +1,180 @@
|
||||
From 3d0adda7560137309be8b10c63ff41e41dfb1516 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Petr=20P=C3=ADsa=C5=99?= <ppisar@redhat.com>
|
||||
Date: Tue, 28 Jan 2020 17:05:32 +0100
|
||||
Subject: [PATCH] Parse an ampersand entity in SAX interface
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
After disabling parsing external entities in XML-LibXML-2.0202,
|
||||
XML::LibXML::SAX interface stopped expanding & and & entities
|
||||
in attribute values (often found in href XHTML attributes) and
|
||||
returned "&" instead. This was discovered by a RDF-Trine test
|
||||
suite failure <https://github.com/kasei/perlrdf/issues/167>.
|
||||
|
||||
First, I suspected XML-LibXML
|
||||
<https://rt.cpan.org/Ticket/Display.html?id=131498>, but it turned out
|
||||
that the unexpanded entity comes from libxml2 C library itself. And
|
||||
that it's not just an ommitted expansion, but that it's actually an
|
||||
escape sequence for "&" characters. Other XML metacharacters (like
|
||||
"<") are not affeced. Also text nodes are also not affected. My
|
||||
finding was confirmed by an old libxml2 bug report
|
||||
<https://bugzilla.gnome.org/show_bug.cgi?id=316487>.
|
||||
|
||||
This patch "fixes" this discepancy by replacing all "&"
|
||||
subtstrings with a literal "&" in SAX interface of start_element()
|
||||
callbacks.
|
||||
|
||||
Signed-off-by: Petr Písař <ppisar@redhat.com>
|
||||
---
|
||||
MANIFEST | 1 +
|
||||
perl-libxml-sax.c | 44 ++++++++++++++++++++++++++++++++++++++++++--
|
||||
t/52_sax_intent.t | 40 ++++++++++++++++++++++++++++++++++++++++
|
||||
3 files changed, 83 insertions(+), 2 deletions(-)
|
||||
create mode 100755 t/52_sax_intent.t
|
||||
|
||||
diff --git a/MANIFEST b/MANIFEST
|
||||
index 5248ea5..ccc3410 100644
|
||||
--- a/MANIFEST
|
||||
+++ b/MANIFEST
|
||||
@@ -174,6 +174,7 @@ t/49callbacks_returning_undef.t
|
||||
t/49global_extent.t
|
||||
t/50devel.t
|
||||
t/51_parse_html_string_rt87089.t
|
||||
+t/52_sax_intent.t
|
||||
t/60error_prev_chain.t
|
||||
t/60struct_error.t
|
||||
t/61error.t
|
||||
diff --git a/perl-libxml-sax.c b/perl-libxml-sax.c
|
||||
index b949d3c..232a879 100644
|
||||
--- a/perl-libxml-sax.c
|
||||
+++ b/perl-libxml-sax.c
|
||||
@@ -20,6 +20,7 @@ extern "C" {
|
||||
#include "ppport.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
+#include <string.h>
|
||||
#include <libxml/xmlmemory.h>
|
||||
#include <libxml/parser.h>
|
||||
#include <libxml/parserInternals.h>
|
||||
@@ -639,6 +640,34 @@ PmmGenNsName( const xmlChar * name, const xmlChar * nsURI )
|
||||
return retval;
|
||||
}
|
||||
|
||||
+/* If a value argument does not contain "&", the value pointer is returned.
|
||||
+ * Otherwise a new xmlChar * string is allocated, the value copied there and
|
||||
+ * "&" occurences replaced with "&". Then the caller must free it. */
|
||||
+static
|
||||
+xmlChar *
|
||||
+_expandAmp( const xmlChar *value )
|
||||
+{
|
||||
+ xmlChar *expanded = NULL;
|
||||
+ const xmlChar *entity;
|
||||
+ int length;
|
||||
+
|
||||
+ if (value == NULL ||
|
||||
+ (NULL == (entity = (const xmlChar *)strstr((const char *)value, "&")))) {
|
||||
+ return (xmlChar *)value;
|
||||
+ }
|
||||
+
|
||||
+ do {
|
||||
+ length = entity - value;
|
||||
+ expanded = xmlStrncat(expanded, value, length);
|
||||
+ expanded = xmlStrncat(expanded, (const xmlChar *)"&", 1);
|
||||
+ value += length + 5; /* "&" */
|
||||
+ } while (NULL != (entity = (const xmlChar*)strstr((const char *)value, "&")));
|
||||
+
|
||||
+ expanded = xmlStrcat(expanded, value);
|
||||
+
|
||||
+ return expanded;
|
||||
+}
|
||||
+
|
||||
HV *
|
||||
PmmGenAttributeHashSV( pTHX_ PmmSAXVectorPtr sax,
|
||||
const xmlChar **attr, SV * handler )
|
||||
@@ -653,8 +682,8 @@ PmmGenAttributeHashSV( pTHX_ PmmSAXVectorPtr sax,
|
||||
const xmlChar * nsURI = NULL;
|
||||
const xmlChar **ta = attr;
|
||||
const xmlChar * name = NULL;
|
||||
- const xmlChar * value = NULL;
|
||||
|
||||
+ xmlChar * value = NULL;
|
||||
xmlChar * keyname = NULL;
|
||||
xmlChar * localname = NULL;
|
||||
xmlChar * prefix = NULL;
|
||||
@@ -665,7 +694,13 @@ PmmGenAttributeHashSV( pTHX_ PmmSAXVectorPtr sax,
|
||||
while ( *ta != NULL ) {
|
||||
atV = newHV();
|
||||
name = *ta; ta++;
|
||||
- value = *ta; ta++;
|
||||
+ /* XXX: libxml2 SAX2 interface does not expand &
|
||||
+ * entity in the attribute values
|
||||
+ * <https://bugzilla.gnome.org/show_bug.cgi?id=316487>
|
||||
+ * resulting in stray "&" sequences after disabling
|
||||
+ * external entity expansion
|
||||
+ * <https://rt.cpan.org/Ticket/Display.html?id=131498>. */
|
||||
+ value = _expandAmp(*ta);
|
||||
|
||||
if ( name != NULL && XML_STR_NOT_EMPTY( name ) ) {
|
||||
localname = xmlSplitQName(NULL, name, &prefix);
|
||||
@@ -754,6 +789,11 @@ PmmGenAttributeHashSV( pTHX_ PmmSAXVectorPtr sax,
|
||||
prefix = NULL;
|
||||
|
||||
}
|
||||
+
|
||||
+ if (value != *ta) {
|
||||
+ xmlFree(value);
|
||||
+ }
|
||||
+ ta++;
|
||||
}
|
||||
}
|
||||
|
||||
diff --git a/t/52_sax_intent.t b/t/52_sax_intent.t
|
||||
new file mode 100755
|
||||
index 0000000..a45b4d1
|
||||
--- /dev/null
|
||||
+++ b/t/52_sax_intent.t
|
||||
@@ -0,0 +1,40 @@
|
||||
+use strict;
|
||||
+use warnings;
|
||||
+use Test::More;
|
||||
+
|
||||
+my %tests = (
|
||||
+ # attribte name raw attrib. value expected parsed value
|
||||
+ predefined => ['"', '"'], # alawys worked
|
||||
+ numeric => ['A', 'A'], # always worked
|
||||
+ numericampersand => ['&', '&'], # a regression
|
||||
+ ampA => ['&A', '&A'], # a corner case
|
||||
+ Aamp => ['A&', 'A&'], # a corner case
|
||||
+ AampBampC => ['A&B&C', 'A&B&C'], # a corner case
|
||||
+);
|
||||
+plan tests => scalar (keys %tests);
|
||||
+
|
||||
+my $input = '<?xml version="1.0"?><root';
|
||||
+for my $test (sort keys %tests) {
|
||||
+ $input .= sprintf(" %s='%s'", $test, $tests{$test}->[0]);
|
||||
+}
|
||||
+$input .= '/>';
|
||||
+
|
||||
+diag("Parsing $input");
|
||||
+use XML::LibXML::SAX;
|
||||
+
|
||||
+XML::LibXML::SAX->new(Handler => 'Handler')->parse_string($input);
|
||||
+
|
||||
+
|
||||
+package Handler;
|
||||
+sub start_element {
|
||||
+ my ($self, $node) = @_;
|
||||
+ for my $attribute (sort keys %{$node->{Attributes}}) {
|
||||
+ my $name = $node->{Attributes}->{$attribute}->{Name};
|
||||
+ Test::More::is(
|
||||
+ $node->{Attributes}->{$attribute}->{Value},
|
||||
+ $tests{$name}->[1],
|
||||
+ sprintf("%s='%s' attribute", $name, $tests{$name}->[0])
|
||||
+ );
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
--
|
||||
2.21.1
|
||||
|
||||
@ -0,0 +1,48 @@
|
||||
diff -up XML-LibXML-2.0206/Makefile.PL.orig XML-LibXML-2.0206/Makefile.PL
|
||||
--- XML-LibXML-2.0206/Makefile.PL.orig 2020-09-15 10:00:42.000000000 +0200
|
||||
+++ XML-LibXML-2.0206/Makefile.PL 2020-11-30 15:54:20.965335954 +0100
|
||||
@@ -17,15 +17,31 @@ use warnings;
|
||||
|
||||
require 5.008001;
|
||||
|
||||
-use Alien::Base::Wrapper qw( Alien::Libxml2 );
|
||||
use ExtUtils::MakeMaker;
|
||||
use Config;
|
||||
|
||||
my $SKIP_SAX_INSTALL = $ENV{SKIP_SAX_INSTALL};
|
||||
|
||||
+my $libs = '';
|
||||
+my $inc = '';
|
||||
+if (`xml2-config --modules 2>/dev/null`) {
|
||||
+ $libs = `xml2-config --libs 2>/dev/null`;
|
||||
+ $inc = `xml2-config --cflags 2>/dev/null`;
|
||||
+}
|
||||
+elsif (`pkg-config --modversion libcrypto 2>/dev/null`) {
|
||||
+ $libs = `pkg-config --libs libxml-2.0 2>/dev/null`;
|
||||
+ $inc = `pkg-config --cflags libxml-2.0 2>/dev/null`;
|
||||
+}
|
||||
+
|
||||
+$libs =~ s/[\r\n]+/ /g;
|
||||
+$inc =~ s/[\r\n]+/ /g;
|
||||
+
|
||||
+die "Could not determine location of libxml2 libs."
|
||||
+ unless $libs =~ /^-/;
|
||||
+die "Could not determine location of libxml2 headers."
|
||||
+ unless $inc =~ /^-/;
|
||||
+
|
||||
my %ConfigReqs = (
|
||||
- "Alien::Libxml2" => '0.14',
|
||||
- "Alien::Base::Wrapper" => 0,
|
||||
"Config" => 0,
|
||||
"ExtUtils::MakeMaker" => 0,
|
||||
);
|
||||
@@ -71,7 +87,8 @@ my %prereqs = (
|
||||
my %xsbuild = (
|
||||
DEFINE => '-DHAVE_UTF8',
|
||||
OBJECT => '$(O_FILES)',
|
||||
- Alien::Base::Wrapper->mm_args,
|
||||
+ LIBS => $libs,
|
||||
+ INC => $inc,
|
||||
);
|
||||
|
||||
my %WriteMakefileArgs = (
|
||||
@ -7,36 +7,31 @@ Name: perl-XML-LibXML
|
||||
# https://bugzilla.redhat.com/show_bug.cgi?id=469480
|
||||
# it might not be needed anymore
|
||||
# this module is maintained, the other is not
|
||||
Version: 2.0132
|
||||
Release: 3%{?dist}
|
||||
Version: 2.0206
|
||||
Release: 5%{?dist}
|
||||
Epoch: 1
|
||||
Summary: Perl interface to the libxml2 library
|
||||
Group: Development/Libraries
|
||||
License: (GPL+ or Artistic) and MIT
|
||||
URL: http://search.cpan.org/dist/XML-LibXML/
|
||||
Source0: http://search.cpan.org/CPAN/authors/id/S/SH/SHLOMIF/XML-LibXML-%{version}.tar.gz
|
||||
# https://github.com/cpan-authors/XML-LibXML/commit/059abf5f9336e2213794b5b545c707394cca3ac7
|
||||
Patch0: perl-XML-LibXML-2.0132-CVE-2026-8177.patch
|
||||
URL: https://metacpan.org/release/XML-LibXML
|
||||
Source0: https://cpan.metacpan.org/authors/id/S/SH/SHLOMIF/XML-LibXML-%{version}.tar.gz
|
||||
# Fix parsing ampersand entities in SAX interface, CPAN RT#131498,
|
||||
# posted to the upstream.
|
||||
Patch0: XML-LibXML-2.0202-Parse-an-ampersand-entity-in-SAX-interface.patch
|
||||
# To reduce dependencies replace Alien::Libxml2 with pkg-config
|
||||
Patch1: XML-LibXML-2.0206-Use-pkgconfig-instead-of-Alien-Libxml2.patch
|
||||
BuildRequires: coreutils
|
||||
BuildRequires: findutils
|
||||
BuildRequires: glibc-common
|
||||
BuildRequires: gcc
|
||||
BuildRequires: libxml2-devel
|
||||
BuildRequires: make
|
||||
BuildRequires: perl-interpreter
|
||||
BuildRequires: perl-devel
|
||||
BuildRequires: perl-generators
|
||||
BuildRequires: perl(Config)
|
||||
BuildRequires: perl(Cwd)
|
||||
BuildRequires: perl(Devel::CheckLib)
|
||||
BuildRequires: perl(ExtUtils::MakeMaker)
|
||||
BuildRequires: perl(File::Spec)
|
||||
BuildRequires: perl(lib)
|
||||
BuildRequires: perl-interpreter
|
||||
BuildRequires: perl(ExtUtils::MakeMaker) >= 6.76
|
||||
BuildRequires: perl(strict)
|
||||
BuildRequires: perl(Symbol)
|
||||
BuildRequires: perl(vars)
|
||||
BuildRequires: perl(warnings)
|
||||
BuildRequires: sed
|
||||
BuildRequires: pkgconfig(libxml-2.0)
|
||||
# Run-time
|
||||
BuildRequires: perl(base)
|
||||
BuildRequires: perl(Carp)
|
||||
@ -51,12 +46,15 @@ BuildRequires: perl(overload)
|
||||
BuildRequires: perl(parent)
|
||||
BuildRequires: perl(Scalar::Util)
|
||||
BuildRequires: perl(Tie::Hash)
|
||||
BuildRequires: perl(vars)
|
||||
BuildRequires: perl(XML::NamespaceSupport)
|
||||
BuildRequires: perl(XML::SAX::Base)
|
||||
BuildRequires: perl(XML::SAX::DocumentLocator)
|
||||
BuildRequires: perl(XML::SAX::Exception)
|
||||
# Tests
|
||||
BuildRequires: perl(Errno)
|
||||
BuildRequires: perl(File::Spec)
|
||||
BuildRequires: perl(lib)
|
||||
BuildRequires: perl(locale)
|
||||
BuildRequires: perl(POSIX)
|
||||
BuildRequires: perl(Test::More)
|
||||
@ -75,7 +73,7 @@ BuildRequires: perl(URI::file)
|
||||
BuildRequires: perl(utf8)
|
||||
# Author test - Test::CPAN::Changes
|
||||
# Author test - Test::Pod
|
||||
# Author test - Test::Kwalitee::Extra
|
||||
# Author test - Test::Kwalitee
|
||||
# Author test - Test::TrailingSpace
|
||||
Requires: perl(:MODULE_COMPAT_%(eval "`perl -V:version`"; echo $version))
|
||||
# Run-require "perl-interpreter" because a triggerin script needs it.
|
||||
@ -96,23 +94,21 @@ validating XML parser and the high performance DOM implementation.
|
||||
%prep
|
||||
%setup -q -n XML-LibXML-%{version}
|
||||
%patch0 -p1
|
||||
%patch1 -p1
|
||||
chmod -x *.c
|
||||
for i in Changes; do
|
||||
/usr/bin/iconv -f iso8859-1 -t utf-8 $i > $i.conv && /bin/mv -f $i.conv $i
|
||||
done
|
||||
# Remove bundled modules
|
||||
rm -r inc/*
|
||||
sed -i -e '/^inc\// d' MANIFEST
|
||||
|
||||
%build
|
||||
perl Makefile.PL SKIP_SAX_INSTALL=1 INSTALLDIRS=vendor OPTIMIZE="%{optflags}"
|
||||
make %{?_smp_mflags}
|
||||
perl Makefile.PL SKIP_SAX_INSTALL=1 INSTALLDIRS=vendor \
|
||||
OPTIMIZE="%{optflags}" NO_PACKLIST=1 NO_PERLLOCAL=1
|
||||
%{make_build}
|
||||
|
||||
%install
|
||||
make pure_install DESTDIR=%{buildroot}
|
||||
find %{buildroot} -type f -name .packlist -delete
|
||||
%{make_install}
|
||||
find %{buildroot} -type f -name '*.bs' -empty -delete
|
||||
chmod -R u+w %{buildroot}/*
|
||||
%{_fixperms} %{buildroot}/*
|
||||
|
||||
%check
|
||||
THREAD_TEST=0%{?with_thread_test:1} make test
|
||||
@ -139,10 +135,69 @@ fi
|
||||
%{_mandir}/man3/*.3*
|
||||
|
||||
%changelog
|
||||
* Tue Jun 23 2026 RHEL Packaging Agent <redhat-ymir-agent@redhat.com> - 1:2.0132-3
|
||||
- Fix out-of-bounds heap read via truncated UTF-8 in node name
|
||||
validation (CVE-2026-8177)
|
||||
- Resolves: RHEL-186519
|
||||
* Mon Aug 09 2021 Mohan Boddu <mboddu@redhat.com> - 1:2.0206-5
|
||||
- Rebuilt for IMA sigs, glibc 2.34, aarch64 flags
|
||||
Related: rhbz#1991688
|
||||
|
||||
* Fri Apr 16 2021 Mohan Boddu <mboddu@redhat.com> - 1:2.0206-4
|
||||
- Rebuilt for RHEL 9 BETA on Apr 15th 2021. Related: rhbz#1947937
|
||||
|
||||
* Wed Jan 27 2021 Fedora Release Engineering <releng@fedoraproject.org> - 1:2.0206-3
|
||||
- Rebuilt for https://fedoraproject.org/wiki/Fedora_34_Mass_Rebuild
|
||||
|
||||
* Mon Nov 30 2020 Jitka Plesnikova <jplesnik@redhat.com> - 1:2.0206-2
|
||||
- Replace using of Alien::Libxml2 with pkg-config
|
||||
|
||||
* Tue Sep 15 2020 Jitka Plesnikova <jplesnik@redhat.com> - 1:2.0206-1
|
||||
- 2.0206 bump
|
||||
|
||||
* Tue Jul 28 2020 Fedora Release Engineering <releng@fedoraproject.org> - 1:2.0205-3
|
||||
- Rebuilt for https://fedoraproject.org/wiki/Fedora_33_Mass_Rebuild
|
||||
|
||||
* Tue Jun 23 2020 Jitka Plesnikova <jplesnik@redhat.com> - 1:2.0205-2
|
||||
- Perl 5.32 rebuild
|
||||
|
||||
* Mon May 11 2020 Jitka Plesnikova <jplesnik@redhat.com> - 1:2.0205-1
|
||||
- 2.0205 bump
|
||||
|
||||
* Wed Mar 18 2020 Jitka Plesnikova <jplesnik@redhat.com> - 1:2.0204-1
|
||||
- 2.0204 bump
|
||||
|
||||
* Wed Mar 11 2020 Jitka Plesnikova <jplesnik@redhat.com> - 1:2.0203-1
|
||||
- 2.0203 bump
|
||||
|
||||
* Tue Jan 28 2020 Petr Pisar <ppisar@redhat.com> - 1:2.0202-2
|
||||
- Fix parsing ampersand entities in SAX interface (CPAN RT#131498)
|
||||
|
||||
* Mon Jan 13 2020 Jitka Plesnikova <jplesnik@redhat.com> - 1:2.0202-1
|
||||
- 2.0202 bump
|
||||
|
||||
* Fri Jul 26 2019 Fedora Release Engineering <releng@fedoraproject.org> - 1:2.0201-3
|
||||
- Rebuilt for https://fedoraproject.org/wiki/Fedora_31_Mass_Rebuild
|
||||
|
||||
* Fri May 31 2019 Jitka Plesnikova <jplesnik@redhat.com> - 1:2.0201-2
|
||||
- Perl 5.30 rebuild
|
||||
|
||||
* Mon May 27 2019 Jitka Plesnikova <jplesnik@redhat.com> - 1:2.0201-1
|
||||
- 2.0201 bump
|
||||
|
||||
* Mon Mar 25 2019 Jitka Plesnikova <jplesnik@redhat.com> - 1:2.0200-1
|
||||
- 2.0200 bump
|
||||
|
||||
* Mon Feb 11 2019 Jitka Plesnikova <jplesnik@redhat.com> - 1:2.0134-1
|
||||
- 2.0134 bump
|
||||
|
||||
* Wed Feb 06 2019 Jitka Plesnikova <jplesnik@redhat.com> - 1:2.0133-1
|
||||
- 2.0133 bump
|
||||
|
||||
* Sat Feb 02 2019 Fedora Release Engineering <releng@fedoraproject.org> - 1:2.0132-5
|
||||
- Rebuilt for https://fedoraproject.org/wiki/Fedora_30_Mass_Rebuild
|
||||
|
||||
* Fri Jul 13 2018 Fedora Release Engineering <releng@fedoraproject.org> - 1:2.0132-4
|
||||
- Rebuilt for https://fedoraproject.org/wiki/Fedora_29_Mass_Rebuild
|
||||
|
||||
* Fri Jun 29 2018 Jitka Plesnikova <jplesnik@redhat.com> - 1:2.0132-3
|
||||
- Perl 5.28 rebuild
|
||||
|
||||
* Fri Feb 09 2018 Fedora Release Engineering <releng@fedoraproject.org> - 1:2.0132-2
|
||||
- Rebuilt for https://fedoraproject.org/wiki/Fedora_28_Mass_Rebuild
|
||||
@ -1,7 +0,0 @@
|
||||
# RHEL
|
||||
--- !Policy
|
||||
product_versions:
|
||||
- rhel-*
|
||||
decision_context: osci_compose_gate
|
||||
rules:
|
||||
- !PassingTestCaseRule {test_case_name: osci.brew-build.tier0.functional}
|
||||
@ -1,324 +0,0 @@
|
||||
From ea9a5f9e9bbe48aa1fa7b16dc53d610fba093e17 Mon Sep 17 00:00:00 2001
|
||||
From: Toddr Bot <toddbot@rinaldo.us>
|
||||
Date: Tue, 19 May 2026 19:32:08 +0000
|
||||
Subject: [PATCH] fix: replace domParseChar with xmlValidateName to prevent OOB
|
||||
UTF-8 read
|
||||
|
||||
domParseChar() read continuation bytes for multi-byte UTF-8 sequences without
|
||||
validating they exist or have required 10xxxxxx form. Truncated sequences like
|
||||
"a\xF0" caused heap reads past NUL terminator. Replace with libxml2's
|
||||
xmlValidateName(), which correctly handles all UTF-8 edge cases.
|
||||
|
||||
Adds 65 regression tests covering truncation points, invalid continuations, and
|
||||
5 affected DOM entry points (createElement, createAttribute, setNodeName, etc).
|
||||
|
||||
Fixes https://github.com/cpan-authors/XML-LibXML/issues/146
|
||||
---
|
||||
LibXML.xs | 33 +------------
|
||||
MANIFEST | 1 +
|
||||
dom.c | 88 ---------------------------------
|
||||
dom.h | 32 ------------
|
||||
t/48_security_oob_utf8_gh146.t | 90 ++++++++++++++++++++++++++++++++++
|
||||
5 files changed, 93 insertions(+), 151 deletions(-)
|
||||
create mode 100644 t/48_security_oob_utf8_gh146.t
|
||||
|
||||
diff --git a/LibXML.xs b/LibXML.xs
|
||||
index efca0b6..cac5447 100644
|
||||
--- a/LibXML.xs
|
||||
+++ b/LibXML.xs
|
||||
@@ -989,40 +989,11 @@ LibXML_cleanup_parser() {
|
||||
int
|
||||
LibXML_test_node_name( xmlChar * name )
|
||||
{
|
||||
- xmlChar * cur = name;
|
||||
- int tc = 0;
|
||||
- int len = 0;
|
||||
-
|
||||
- if ( cur == NULL || *cur == 0 ) {
|
||||
- /* warn("name is empty" ); */
|
||||
- return(0);
|
||||
- }
|
||||
-
|
||||
- tc = domParseChar( cur, &len );
|
||||
-
|
||||
- if ( !( IS_LETTER( tc ) || (tc == '_') || (tc == ':')) ) {
|
||||
- /* warn( "is not a letter\n" ); */
|
||||
+ if ( name == NULL || *name == 0 ) {
|
||||
return(0);
|
||||
}
|
||||
|
||||
- tc = 0;
|
||||
- cur += len;
|
||||
-
|
||||
- while (*cur != 0 ) {
|
||||
- tc = domParseChar( cur, &len );
|
||||
-
|
||||
- if (!(IS_LETTER(tc) || IS_DIGIT(tc) || (tc == '_') ||
|
||||
- (tc == '-') || (tc == ':') || (tc == '.') ||
|
||||
- IS_COMBINING(tc) || IS_EXTENDER(tc)) ) {
|
||||
- /* warn( "is not a letter\n" ); */
|
||||
- return(0);
|
||||
- }
|
||||
- tc = 0;
|
||||
- cur += len;
|
||||
- }
|
||||
-
|
||||
- /* warn("name is ok"); */
|
||||
- return(1);
|
||||
+ return xmlValidateName( name, 0 ) == 0;
|
||||
}
|
||||
|
||||
/* Assumes that the node has a proxy. */
|
||||
diff --git a/MANIFEST b/MANIFEST
|
||||
index 2efb21a..e72a35d 100644
|
||||
--- a/MANIFEST
|
||||
+++ b/MANIFEST
|
||||
@@ -168,6 +168,7 @@ t/48_replaceNode_DTD_nodes_rT_80521.t
|
||||
t/48_rt123379_setNamespace.t
|
||||
t/48_rt55000.t
|
||||
t/48_rt93429_recover_2_in_html_parsing.t
|
||||
+t/48_security_oob_utf8_gh146.t
|
||||
t/48importing_nodes_IDs_rt_69520.t
|
||||
t/49_load_html.t
|
||||
t/49callbacks_returning_undef.t
|
||||
diff --git a/dom.c b/dom.c
|
||||
index 10eb33d..0a818b2 100644
|
||||
--- a/dom.c
|
||||
+++ b/dom.c
|
||||
@@ -235,94 +235,6 @@ domReconcileNs(xmlNodePtr tree)
|
||||
xmlFreeNsList(unused);
|
||||
}
|
||||
|
||||
-/**
|
||||
- * NAME domParseChar
|
||||
- * TYPE function
|
||||
- * SYNOPSIS
|
||||
- * int utf8char = domParseChar( curchar, &len );
|
||||
- *
|
||||
- * The current char value, if using UTF-8 this may actually span
|
||||
- * multiple bytes in the given string. This function parses an utf8
|
||||
- * character from a string into a UTF8 character (an integer). It uses
|
||||
- * a slightly modified version of libxml2's character parser. libxml2
|
||||
- * itself does not provide any function to parse characters dircetly
|
||||
- * from a string and test if they are valid utf8 characters.
|
||||
- *
|
||||
- * XML::LibXML uses this function rather than perls native UTF8
|
||||
- * support for two reasons:
|
||||
- * 1) perls UTF8 handling functions often lead to encoding errors,
|
||||
- * which partly comes, that they are badly documented.
|
||||
- * 2) not all perl versions XML::LibXML intends to run with have native
|
||||
- * UTF8 support.
|
||||
- *
|
||||
- * domParseChar() allows to use the very same code with all versions
|
||||
- * of perl :)
|
||||
- *
|
||||
- * Returns the current char value and its length
|
||||
- *
|
||||
- * NOTE: If the character passed to this function is not a UTF
|
||||
- * character, the return value will be 0 and the length of the
|
||||
- * character is -1!
|
||||
- */
|
||||
-int
|
||||
-domParseChar( xmlChar *cur, int *len )
|
||||
-{
|
||||
- unsigned char c;
|
||||
- unsigned int val;
|
||||
-
|
||||
- /*
|
||||
- * We are supposed to handle UTF8, check it's valid
|
||||
- * From rfc2044: encoding of the Unicode values on UTF-8:
|
||||
- *
|
||||
- * UCS-4 range (hex.) UTF-8 octet sequence (binary)
|
||||
- * 0000 0000-0000 007F 0xxxxxxx
|
||||
- * 0000 0080-0000 07FF 110xxxxx 10xxxxxx
|
||||
- * 0000 0800-0000 FFFF 1110xxxx 10xxxxxx 10xxxxxx
|
||||
- *
|
||||
- * Check for the 0x110000 limit too
|
||||
- */
|
||||
-
|
||||
- if ( cur == NULL || *cur == 0 ) {
|
||||
- *len = 0;
|
||||
- return(0);
|
||||
- }
|
||||
-
|
||||
- c = *cur;
|
||||
- if ( c & 0x80 ) {
|
||||
- if ((c & 0xe0) == 0xe0) {
|
||||
- if ((c & 0xf0) == 0xf0) {
|
||||
- /* 4-byte code */
|
||||
- *len = 4;
|
||||
- val = (cur[0] & 0x7) << 18;
|
||||
- val |= (cur[1] & 0x3f) << 12;
|
||||
- val |= (cur[2] & 0x3f) << 6;
|
||||
- val |= cur[3] & 0x3f;
|
||||
- } else {
|
||||
- /* 3-byte code */
|
||||
- *len = 3;
|
||||
- val = (cur[0] & 0xf) << 12;
|
||||
- val |= (cur[1] & 0x3f) << 6;
|
||||
- val |= cur[2] & 0x3f;
|
||||
- }
|
||||
- } else {
|
||||
- /* 2-byte code */
|
||||
- *len = 2;
|
||||
- val = (cur[0] & 0x1f) << 6;
|
||||
- val |= cur[1] & 0x3f;
|
||||
- }
|
||||
- if ( !IS_CHAR(val) ) {
|
||||
- *len = -1;
|
||||
- return(0);
|
||||
- }
|
||||
- return(val);
|
||||
- }
|
||||
- else {
|
||||
- /* 1-byte code */
|
||||
- *len = 1;
|
||||
- return((int)c);
|
||||
- }
|
||||
-}
|
||||
-
|
||||
/**
|
||||
* Name: domReadWellBalancedString
|
||||
* Synopsis: xmlNodePtr domReadWellBalancedString( xmlDocPtr doc, xmlChar *string )
|
||||
diff --git a/dom.h b/dom.h
|
||||
index 29cf2b5..cf0f474 100644
|
||||
--- a/dom.h
|
||||
+++ b/dom.h
|
||||
@@ -54,38 +54,6 @@ extern "C" {
|
||||
void
|
||||
domReconcileNs(xmlNodePtr tree);
|
||||
|
||||
-/**
|
||||
- * NAME domParseChar
|
||||
- * TYPE function
|
||||
- * SYNOPSIS
|
||||
- * int utf8char = domParseChar( curchar, &len );
|
||||
- *
|
||||
- * The current char value, if using UTF-8 this may actually span
|
||||
- * multiple bytes in the given string. This function parses an utf8
|
||||
- * character from a string into a UTF8 character (an integer). It uses
|
||||
- * a slightly modified version of libxml2's character parser. libxml2
|
||||
- * itself does not provide any function to parse characters dircetly
|
||||
- * from a string and test if they are valid utf8 characters.
|
||||
- *
|
||||
- * XML::LibXML uses this function rather than perls native UTF8
|
||||
- * support for two reasons:
|
||||
- * 1) perls UTF8 handling functions often lead to encoding errors,
|
||||
- * which partly comes, that they are badly documented.
|
||||
- * 2) not all perl versions XML::LibXML intends to run with have native
|
||||
- * UTF8 support.
|
||||
- *
|
||||
- * domParseChar() allows to use the very same code with all versions
|
||||
- * of perl :)
|
||||
- *
|
||||
- * Returns the current char value and its length
|
||||
- *
|
||||
- * NOTE: If the character passed to this function is not a UTF
|
||||
- * character, the return value will be 0 and the length of the
|
||||
- * character is -1!
|
||||
- */
|
||||
-int
|
||||
-domParseChar( xmlChar *characters, int *len );
|
||||
-
|
||||
xmlNodePtr
|
||||
domReadWellBalancedString( xmlDocPtr doc, xmlChar* string, int repair );
|
||||
|
||||
diff --git a/t/48_security_oob_utf8_gh146.t b/t/48_security_oob_utf8_gh146.t
|
||||
new file mode 100644
|
||||
index 0000000..74fb6d4
|
||||
--- /dev/null
|
||||
+++ b/t/48_security_oob_utf8_gh146.t
|
||||
@@ -0,0 +1,90 @@
|
||||
+# Security regression test for GitHub issue #146:
|
||||
+# Out-of-bounds heap read via hand-rolled UTF-8 walker on truncated sequences.
|
||||
+#
|
||||
+# The original domParseChar() read continuation bytes for multi-byte UTF-8
|
||||
+# sequences without verifying they exist or are valid. A truncated sequence
|
||||
+# (e.g., "a\xF0") caused reads past the NUL terminator into uninitialized
|
||||
+# heap memory. This affects all DOM methods that validate node names via
|
||||
+# LibXML_test_node_name(): createElement, createAttribute, setNodeName,
|
||||
+# createElementNS, createAttributeNS, etc.
|
||||
+#
|
||||
+# Impact: denial of service (crash on unmapped memory) and potential
|
||||
+# information disclosure (reading adjacent heap allocations).
|
||||
+#
|
||||
+# Fixed by replacing the hand-rolled UTF-8 walker (domParseChar) with
|
||||
+# libxml2's own xmlValidateName(), which correctly handles all UTF-8
|
||||
+# edge cases.
|
||||
+#
|
||||
+# NOTE: This test verifies that malformed UTF-8 does not crash the process
|
||||
+# (the actual security issue). Whether a given sequence is rejected depends
|
||||
+# on the linked libxml2 version — older 2.9.x builds may accept some
|
||||
+# sequences that newer versions reject.
|
||||
+
|
||||
+use strict;
|
||||
+use warnings;
|
||||
+
|
||||
+use Test::More;
|
||||
+use XML::LibXML;
|
||||
+
|
||||
+# Truncated UTF-8 sequences that previously caused OOB heap reads.
|
||||
+# Each entry: [ bytes, description ]
|
||||
+my @truncated_sequences = (
|
||||
+ [ "a\xC0", "truncated 2-byte (leader only)" ],
|
||||
+ [ "a\xC2", "truncated 2-byte (valid leader, missing continuation)" ],
|
||||
+ [ "a\xE0", "truncated 3-byte (leader only)" ],
|
||||
+ [ "a\xE0\x80", "truncated 3-byte (leader + 1 continuation)" ],
|
||||
+ [ "a\xF0", "truncated 4-byte (leader only)" ],
|
||||
+ [ "a\xF0\x80", "truncated 4-byte (leader + 1 continuation)" ],
|
||||
+ [ "a\xF0\x80\x80", "truncated 4-byte (leader + 2 continuations)" ],
|
||||
+);
|
||||
+
|
||||
+# Invalid continuation bytes — the leader is valid but the continuations
|
||||
+# are not 10xxxxxx.
|
||||
+my @invalid_continuations = (
|
||||
+ [ "a\xC2\x41", "2-byte with ASCII continuation" ],
|
||||
+ [ "a\xE0\x41\x80", "3-byte with ASCII in first continuation" ],
|
||||
+ [ "a\xE0\x80\x41", "3-byte with ASCII in second continuation" ],
|
||||
+ [ "a\xF0\x41\x80\x80", "4-byte with ASCII in first continuation" ],
|
||||
+ [ "a\xF0\x80\x41\x80", "4-byte with ASCII in second continuation" ],
|
||||
+ [ "a\xF0\x80\x80\x41", "4-byte with ASCII in third continuation" ],
|
||||
+);
|
||||
+
|
||||
+my @all_bad = (@truncated_sequences, @invalid_continuations);
|
||||
+
|
||||
+my @methods = qw( createElement setNodeName createElementNS
|
||||
+ createAttribute createAttributeNS );
|
||||
+
|
||||
+# TEST:$bad_count=13
|
||||
+# TEST:$method_count=5
|
||||
+plan tests => scalar(@all_bad) * scalar(@methods);
|
||||
+
|
||||
+my $doc = XML::LibXML::Document->new();
|
||||
+my $nsURI = "http://example.com/ns";
|
||||
+
|
||||
+for my $case (@all_bad) {
|
||||
+ my ($bytes, $desc) = @$case;
|
||||
+
|
||||
+ for my $method (@methods) {
|
||||
+ eval {
|
||||
+ if ($method eq 'createElement') {
|
||||
+ $doc->createElement($bytes);
|
||||
+ }
|
||||
+ elsif ($method eq 'setNodeName') {
|
||||
+ my $node = $doc->createElement("tmp");
|
||||
+ $node->setNodeName($bytes);
|
||||
+ }
|
||||
+ elsif ($method eq 'createElementNS') {
|
||||
+ $doc->createElementNS($nsURI, $bytes);
|
||||
+ }
|
||||
+ elsif ($method eq 'createAttribute') {
|
||||
+ $doc->createAttribute($bytes, "value");
|
||||
+ }
|
||||
+ elsif ($method eq 'createAttributeNS') {
|
||||
+ $doc->createAttributeNS($nsURI, $bytes, "value");
|
||||
+ }
|
||||
+ };
|
||||
+
|
||||
+ # TEST*$bad_count*$method_count
|
||||
+ pass("$method survives $desc without crashing");
|
||||
+ }
|
||||
+}
|
||||
--
|
||||
2.52.0
|
||||
|
||||
@ -1,12 +0,0 @@
|
||||
summary: Private (RHEL) beakerlib tests
|
||||
enabled: false
|
||||
adjust:
|
||||
- when: distro == rhel
|
||||
enabled: true
|
||||
because: private tests are accesible only within rhel pipeline
|
||||
discover:
|
||||
- name: rhel
|
||||
how: fmf
|
||||
url: https://pkgs.devel.redhat.com/git/tests/perl-XML-LibXML
|
||||
execute:
|
||||
how: tmt
|
||||
Loading…
Reference in New Issue
Block a user