Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package perl-HTML-Parser for openSUSE:Factory checked in at 2026-11-06 19:34:40 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/perl-HTML-Parser (Old) and /work/SRC/openSUSE:Factory/.perl-HTML-Parser.new.3759290 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "perl-HTML-Parser" Fri Nov 6 19:34:40 2026 rev:45 rq:1395151 version:3.860.0 Changes: -------- --- /work/SRC/openSUSE:Factory/perl-HTML-Parser/perl-HTML-Parser.changes 2026-06-09 14:14:23.113880314 +0200 +++ /work/SRC/openSUSE:Factory/.perl-HTML-Parser.new.3759290/perl-HTML-Parser.changes 2026-11-06 19:38:00.080017814 +0100 @@ -1,0 +2,10 @@ +Sun Sep 20 09:51:08 UTC 2026 - Tina Müller <[email protected]> + +- updated to 3.860.0 (3.86) + see /usr/share/doc/packages/perl-HTML-Parser/Changes + + 3.86 2026-09-19 + - Expand an entity whose value is the string being decoded to the + value that string had when the call began (GH#69) (Paul Johnson) + +------------------------------------------------------------------- Old: ---- HTML-Parser-3.85.tar.gz New: ---- HTML-Parser-3.86.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ perl-HTML-Parser.spec ++++++ --- /var/tmp/diff_new_pack.h31cTo/_old 2026-11-06 19:38:01.261067216 +0100 +++ /var/tmp/diff_new_pack.h31cTo/_new 2026-11-06 19:38:01.263067300 +0100 @@ -18,10 +18,10 @@ %define cpan_name HTML-Parser Name: perl-HTML-Parser -Version: 3.850.0 +Version: 3.860.0 Release: 0 -# 3.85 -> normalize -> 3.850.0 -%define cpan_version 3.85 +# 3.86 -> normalize -> 3.860.0 +%define cpan_version 3.86 License: Artistic-1.0 OR GPL-1.0-or-later Summary: HTML parser class URL: https://metacpan.org/release/%{cpan_name} ++++++ HTML-Parser-3.85.tar.gz -> HTML-Parser-3.86.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/HTML-Parser-3.85/Changes new/HTML-Parser-3.86/Changes --- old/HTML-Parser-3.85/Changes 2026-05-19 23:39:05.000000000 +0200 +++ new/HTML-Parser-3.86/Changes 2026-09-19 23:41:47.000000000 +0200 @@ -1,5 +1,9 @@ Change history for HTML-Parser +3.86 2026-09-19 + - Expand an entity whose value is the string being decoded to the + value that string had when the call began (GH#69) (Paul Johnson) + 3.85 2026-05-19 - Replace deprecated uvuni_to_utf8() with uvchr_to_utf8() (GH#50) (GitHub Copilot, reported by James E Keenan) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/HTML-Parser-3.85/META.json new/HTML-Parser-3.86/META.json --- old/HTML-Parser-3.85/META.json 2026-05-19 23:39:05.000000000 +0200 +++ new/HTML-Parser-3.86/META.json 2026-09-19 23:41:47.000000000 +0200 @@ -88,32 +88,32 @@ "provides" : { "HTML::Entities" : { "file" : "lib/HTML/Entities.pm", - "version" : "3.85" + "version" : "3.86" }, "HTML::Filter" : { "file" : "lib/HTML/Filter.pm", - "version" : "3.85", + "version" : "3.86", "x_deprecated" : 1 }, "HTML::HeadParser" : { "file" : "lib/HTML/HeadParser.pm", - "version" : "3.85" + "version" : "3.86" }, "HTML::LinkExtor" : { "file" : "lib/HTML/LinkExtor.pm", - "version" : "3.85" + "version" : "3.86" }, "HTML::Parser" : { "file" : "lib/HTML/Parser.pm", - "version" : "3.85" + "version" : "3.86" }, "HTML::PullParser" : { "file" : "lib/HTML/PullParser.pm", - "version" : "3.85" + "version" : "3.86" }, "HTML::TokeParser" : { "file" : "lib/HTML/TokeParser.pm", - "version" : "3.85" + "version" : "3.86" } }, "release_status" : "stable", @@ -128,7 +128,7 @@ "web" : "https://github.com/libwww-perl/HTML-Parser" } }, - "version" : "3.85", + "version" : "3.86", "x_contributors" : [ "Andy Lester <[email protected]>", "Antonio Radici <[email protected]>", diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/HTML-Parser-3.85/META.yml new/HTML-Parser-3.86/META.yml --- old/HTML-Parser-3.85/META.yml 2026-05-19 23:39:05.000000000 +0200 +++ new/HTML-Parser-3.86/META.yml 2026-09-19 23:41:47.000000000 +0200 @@ -33,26 +33,26 @@ provides: HTML::Entities: file: lib/HTML/Entities.pm - version: '3.85' + version: '3.86' HTML::Filter: file: lib/HTML/Filter.pm - version: '3.85' + version: '3.86' x_deprecated: 1 HTML::HeadParser: file: lib/HTML/HeadParser.pm - version: '3.85' + version: '3.86' HTML::LinkExtor: file: lib/HTML/LinkExtor.pm - version: '3.85' + version: '3.86' HTML::Parser: file: lib/HTML/Parser.pm - version: '3.85' + version: '3.86' HTML::PullParser: file: lib/HTML/PullParser.pm - version: '3.85' + version: '3.86' HTML::TokeParser: file: lib/HTML/TokeParser.pm - version: '3.85' + version: '3.86' requires: Carp: '0' Exporter: '0' @@ -68,7 +68,7 @@ bugtracker: https://github.com/libwww-perl/HTML-Parser/issues homepage: https://github.com/libwww-perl/HTML-Parser repository: https://github.com/libwww-perl/HTML-Parser.git -version: '3.85' +version: '3.86' x_contributors: - 'Andy Lester <[email protected]>' - 'Antonio Radici <[email protected]>' diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/HTML-Parser-3.85/Makefile.PL new/HTML-Parser-3.86/Makefile.PL --- old/HTML-Parser-3.85/Makefile.PL 2026-05-19 23:39:05.000000000 +0200 +++ new/HTML-Parser-3.86/Makefile.PL 2026-09-19 23:41:47.000000000 +0200 @@ -37,7 +37,7 @@ "URI" => 0, "strict" => 0 }, - "VERSION" => "3.85", + "VERSION" => "3.86", "test" => { "TESTS" => "t/*.t" } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/HTML-Parser-3.85/lib/HTML/Entities.pm new/HTML-Parser-3.86/lib/HTML/Entities.pm --- old/HTML-Parser-3.85/lib/HTML/Entities.pm 2026-05-19 23:39:05.000000000 +0200 +++ new/HTML-Parser-3.86/lib/HTML/Entities.pm 2026-09-19 23:41:47.000000000 +0200 @@ -70,6 +70,14 @@ _decode_entities($string, { nb => "@", nbsp => "\xA0" }, 1); print $string; # will print "foo bar" +An entity whose value is the string being decoded expands to the value +that string had when the call began. This routine does not scan +replacement text again, so any entities inside it are left alone. + +Looking up a value can run Perl code, through a tied hash or an +overloaded object. If that code modifies the string being decoded, +this routine dies. + This routine is exported by default. =item encode_entities( $string ) @@ -136,7 +144,7 @@ =cut use strict; -our $VERSION = '3.85'; +our $VERSION = '3.86'; our (%entity2char, %char2entity); require 5.008; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/HTML-Parser-3.85/lib/HTML/Filter.pm new/HTML-Parser-3.86/lib/HTML/Filter.pm --- old/HTML-Parser-3.85/lib/HTML/Filter.pm 2026-05-19 23:39:05.000000000 +0200 +++ new/HTML-Parser-3.86/lib/HTML/Filter.pm 2026-09-19 23:41:47.000000000 +0200 @@ -4,7 +4,7 @@ require HTML::Parser; our @ISA = qw(HTML::Parser); -our $VERSION = '3.85'; +our $VERSION = '3.86'; sub declaration { $_[0]->output("<!$_[1]>") } sub process { $_[0]->output($_[2]) } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/HTML-Parser-3.85/lib/HTML/HeadParser.pm new/HTML-Parser-3.86/lib/HTML/HeadParser.pm --- old/HTML-Parser-3.85/lib/HTML/HeadParser.pm 2026-05-19 23:39:05.000000000 +0200 +++ new/HTML-Parser-3.86/lib/HTML/HeadParser.pm 2026-09-19 23:41:47.000000000 +0200 @@ -91,7 +91,7 @@ use strict; our $DEBUG; #$DEBUG = 1; -our $VERSION = '3.85'; +our $VERSION = '3.86'; =item $hp = HTML::HeadParser->new diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/HTML-Parser-3.85/lib/HTML/LinkExtor.pm new/HTML-Parser-3.86/lib/HTML/LinkExtor.pm --- old/HTML-Parser-3.85/lib/HTML/LinkExtor.pm 2026-05-19 23:39:05.000000000 +0200 +++ new/HTML-Parser-3.86/lib/HTML/LinkExtor.pm 2026-09-19 23:41:47.000000000 +0200 @@ -2,7 +2,7 @@ require HTML::Parser; our @ISA = qw(HTML::Parser); -our $VERSION = '3.85'; +our $VERSION = '3.86'; =head1 NAME diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/HTML-Parser-3.85/lib/HTML/Parser.pm new/HTML-Parser-3.86/lib/HTML/Parser.pm --- old/HTML-Parser-3.85/lib/HTML/Parser.pm 2026-05-19 23:39:05.000000000 +0200 +++ new/HTML-Parser-3.86/lib/HTML/Parser.pm 2026-09-19 23:41:47.000000000 +0200 @@ -2,7 +2,7 @@ use strict; -our $VERSION = '3.85'; +our $VERSION = '3.86'; require HTML::Entities; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/HTML-Parser-3.85/lib/HTML/PullParser.pm new/HTML-Parser-3.86/lib/HTML/PullParser.pm --- old/HTML-Parser-3.85/lib/HTML/PullParser.pm 2026-05-19 23:39:05.000000000 +0200 +++ new/HTML-Parser-3.86/lib/HTML/PullParser.pm 2026-09-19 23:41:47.000000000 +0200 @@ -4,7 +4,7 @@ require HTML::Parser; our @ISA = qw(HTML::Parser); -our $VERSION = '3.85'; +our $VERSION = '3.86'; use Carp (); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/HTML-Parser-3.85/lib/HTML/TokeParser.pm new/HTML-Parser-3.86/lib/HTML/TokeParser.pm --- old/HTML-Parser-3.85/lib/HTML/TokeParser.pm 2026-05-19 23:39:05.000000000 +0200 +++ new/HTML-Parser-3.86/lib/HTML/TokeParser.pm 2026-09-19 23:41:47.000000000 +0200 @@ -4,7 +4,7 @@ require HTML::PullParser; our @ISA = qw(HTML::PullParser); -our $VERSION = '3.85'; +our $VERSION = '3.86'; use Carp (); use HTML::Entities qw(decode_entities); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/HTML-Parser-3.85/t/entities.t new/HTML-Parser-3.86/t/entities.t --- old/HTML-Parser-3.85/t/entities.t 2026-05-19 23:39:05.000000000 +0200 +++ new/HTML-Parser-3.86/t/entities.t 2026-09-19 23:41:47.000000000 +0200 @@ -4,7 +4,7 @@ use HTML::Entities qw(_decode_entities decode_entities encode_entities encode_entities_numeric); -use Test::More tests => 32; +use Test::More tests => 43; my $x = "Våre norske tegn bør æres"; @@ -100,8 +100,7 @@ # CVE-2026-8829 # _decode_entities heap-use-after-free when the input SV is the same SV as # a self-referential entity value. The payload must be large enough to -# force grow_gap() to realloc the SV's PV; the fix copies the entity value -# into an owned buffer so repl is not left pointing at the freed allocation. +# force grow_gap() to realloc the SV's PV. { my $prefix_a = "A" x 32; my $suffix_b = "B" x 8192; @@ -112,6 +111,139 @@ "_decode_entities() with self-aliased entity hash value"); } +# An entity name that runs to the end of the input must not match a +# "name;" key on a byte beyond the end. Growing the string moves the +# tail without its NUL, so that byte holds whatever the buffer held +# before. Trim the string in place so a ";" is left just past its end. +{ + my %t = ("ab;" => "X" x 40, "a;" => "Y"); + my $s = "&ab;&a" . (";" x 200); + substr($s, 6) = ""; + _decode_entities($s, \%t); + is( + $s, + ("X" x 40) . "&a", + "_decode_entities() does not read past the end of the input" + ); +} + +# GH#68 +# An entity whose value is the string being decoded expands to the value +# that string had when the call began, which is what an entity table +# holding a separate copy of that string has always given. The first two +# cases are the examples from the ticket. +{ + my %g; + $g{foo} = ""; + $g{bar} = "&foo;X&bar;"; + _decode_entities($g{bar}, \%g); + is($g{bar}, "X&foo;X&bar;", + "_decode_entities() expands a self-reference after another entity"); + + my %i; + $i{foo} = "[.....]"; + $i{bar} = "&foo;X&bar;Y"; + _decode_entities($i{bar}, \%i); + is($i{bar}, "[.....]X&foo;X&bar;YY", + "_decode_entities() leaves no stale bytes at a self-reference"); + + my %j; + $j{amp} = "&"; + $j{bar} = "&bar;&"; + _decode_entities($j{bar}, \%j); + is($j{bar}, "&bar;&&", + "_decode_entities() keeps decoding after a self-reference"); + + my %p; + $p{nb} = " X"; + _decode_entities($p{nb}, \%p, 1); + is($p{nb}, " XspX", + "_decode_entities() expands a self-reference matched as a prefix"); + + my %u; + $u{smile} = "\x{263a}"; + $u{bar} = "\xe9⌣&bar;"; + _decode_entities($u{bar}, \%u); + is( + $u{bar}, + "\x{e9}\x{263a}\x{e9}⌣&bar;", + "_decode_entities() expands a self-reference after an upgrade" + ); +} + +# Looking up an entity value can run Perl code, through a tied hash or +# an overloaded object. That code must not be able to pull the string +# out from under the decoder. +{ + + package UndefOnFetch; + require Tie::Hash; + our @ISA = ("Tie::StdHash"); + our $target; + sub FETCH { undef $$target; "x" } +} +{ + my %tied; + tie %tied, "UndefOnFetch"; + my $s = "&foo;" . ("a" x 100); + $UndefOnFetch::target = \$s; + eval { _decode_entities($s, \%tied) }; + like( + $@, + qr/modified while fetching an entity value/, + "_decode_entities() dies when a tied table undefines the string" + ); +} +{ + package ReallocateOnFetch; + require Tie::Hash; + our @ISA = ("Tie::StdHash"); + our $target; + sub FETCH { undef $$target; $$target = "Z" x 1000; undef } +} +{ + my %tied; + tie %tied, "ReallocateOnFetch"; + my $s = "&foo;" . ("a" x 100); + $ReallocateOnFetch::target = \$s; + eval { _decode_entities($s, \%tied) }; + like( + $@, + qr/modified while fetching an entity value/, + "_decode_entities() dies when a tied table reallocates the string" + ); +} +{ + my $s = "&foo;" . ("a" x 100); + my %t = (foo => bless {}, "ShrinkOnStringify"); + { + + package ShrinkOnStringify; + use overload + '""' => sub { undef $s; $s = "Z" x 10; "x" }, + fallback => 1; + } + eval { _decode_entities($s, \%t) }; + like( + $@, + qr/modified while fetching an entity value/, + "_decode_entities() dies when a value shrinks the string" + ); +} +{ + my %h; + { + + package DeleteOnStringify; + use overload '""' => sub { delete $h{str}; "x" }, fallback => 1; + } + $h{obj} = bless {}, "DeleteOnStringify"; + $h{str} = "&obj;" . ("a" x 100); + eval { _decode_entities($h{str}, \%h) }; + is($@, "", "_decode_entities() survives a value deleting the string"); + ok(!exists $h{str}, "the deleted string stays deleted"); +} + # From: Bill Simpson-Young <[email protected]> # Subject: HTML entities problem with 5.11 # To: [email protected] diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/HTML-Parser-3.85/util.c new/HTML-Parser-3.86/util.c --- old/HTML-Parser-3.85/util.c 2026-05-19 23:39:05.000000000 +0200 +++ new/HTML-Parser-3.86/util.c 2026-09-19 23:41:47.000000000 +0200 @@ -61,6 +61,16 @@ *e += grow; } +static void +save_original(pTHX_ SV* sv, STRLEN len, char** orig) +{ + if (*orig) + return; + Newx(*orig, len ? len : 1, char); + SAVEFREEPV(*orig); + Copy(SvPVX(sv), *orig, len, char); +} + EXTERN SV* decode_entities(pTHX_ SV* sv, HV* entity2char, bool expand_prefix) { @@ -72,7 +82,8 @@ char *repl; STRLEN repl_len; - char *repl_allocated = 0; + char *orig = 0; + int orig_utf8 = SvUTF8(sv); char buf[UTF8_MAXLEN]; int repl_utf8; int high_surrogate = 0; @@ -82,6 +93,12 @@ repl_utf8 = 0; #endif + /* Looking up an entity value can run Perl code, which must not be + * able to free sv while we hold pointers into it. */ + ENTER; + SvREFCNT_inc_simple_void(sv); + SAVEFREESV(sv); + while (s < end) { assert(t <= s); @@ -90,7 +107,6 @@ ent_start = s; repl = 0; - repl_allocated = 0; if (s < end && *s == '#') { UV num = 0; @@ -174,22 +190,22 @@ s++; if (ent_name != s && entity2char) { SV** svp; + char *pvx = SvPVX(sv); + STRLEN cur = SvCUR(sv); + STRLEN alloc = SvLEN(sv); + U32 utf8 = SvUTF8(sv); if ( (svp = hv_fetch(entity2char, ent_name, s - ent_name, 0)) || - (*s == ';' && (svp = hv_fetch(entity2char, ent_name, s - ent_name + 1, 0))) + (s < end && *s == ';' && (svp = hv_fetch(entity2char, ent_name, s - ent_name + 1, 0))) ) { - char *src = SvPV(*svp, repl_len); - repl_utf8 = SvUTF8(*svp); if ((SV*)*svp == sv) { - /* Self-aliased: hash entry SV == input SV. - * grow_gap() may realloc sv's PV later; copy - * the entity value into an owned buffer first. - * Freed by the repl_allocated cleanup below. */ - Newx(repl_allocated, repl_len ? repl_len : 1, char); - Copy(src, repl_allocated, repl_len, char); - repl = repl_allocated; + save_original(aTHX_ sv, len, &orig); + repl = orig; + repl_len = len; + repl_utf8 = orig_utf8; } else { - repl = src; + repl = SvPV(*svp, repl_len); + repl_utf8 = SvUTF8(*svp); } } else if (expand_prefix) { @@ -197,14 +213,14 @@ while (ss > ent_name) { svp = hv_fetch(entity2char, ent_name, ss - ent_name, 0); if (svp) { - char *src = SvPV(*svp, repl_len); - repl_utf8 = SvUTF8(*svp); if ((SV*)*svp == sv) { - Newx(repl_allocated, repl_len ? repl_len : 1, char); - Copy(src, repl_allocated, repl_len, char); - repl = repl_allocated; + save_original(aTHX_ sv, len, &orig); + repl = orig; + repl_len = len; + repl_utf8 = orig_utf8; } else { - repl = src; + repl = SvPV(*svp, repl_len); + repl_utf8 = SvUTF8(*svp); } s = ss; break; @@ -212,19 +228,24 @@ ss--; } } + /* The lookups may have run Perl code, and we still hold + * pointers into the buffer it could have changed. */ + if (SvPVX(sv) != pvx || SvCUR(sv) != cur || + SvLEN(sv) != alloc || SvUTF8(sv) != utf8) + croak("String being decoded was modified" + " while fetching an entity value"); } high_surrogate = 0; } if (repl) { - /* repl_allocated is now function-scoped; set by the - * named-entity self-alias path above or by the UTF8 mismatch - * branch below. Same cleanup in either case. */ + char *repl_allocated = 0; + save_original(aTHX_ sv, len, &orig); if (s < end && *s == ';') s++; t--; /* '&' already copied, undo it */ - if (*s != '&') { + if (s >= end || *s != '&') { high_surrogate = 0; } @@ -271,6 +292,8 @@ *t = '\0'; SvCUR_set(sv, t - SvPVX(sv)); + LEAVE; + return sv; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/HTML-Parser-3.85/xt/release/changes_has_content.t new/HTML-Parser-3.86/xt/release/changes_has_content.t --- old/HTML-Parser-3.85/xt/release/changes_has_content.t 2026-05-19 23:39:05.000000000 +0200 +++ new/HTML-Parser-3.86/xt/release/changes_has_content.t 2026-09-19 23:41:47.000000000 +0200 @@ -2,7 +2,7 @@ note 'Checking Changes'; my $changes_file = 'Changes'; -my $newver = '3.85'; +my $newver = '3.86'; my $trial_token = '-TRIAL'; my $encoding = 'UTF-8'; ++++++ _scmsync.obsinfo ++++++ --- /var/tmp/diff_new_pack.h31cTo/_old 2026-11-06 19:38:01.389072571 +0100 +++ /var/tmp/diff_new_pack.h31cTo/_new 2026-11-06 19:38:01.393072738 +0100 @@ -1,6 +1,6 @@ -mtime: 1780917448 -commit: a98c4d2c128eef96aad66437d5139620ab432a6330ffc510beb7963fae2c71cf +mtime: 1789897869 +commit: 5db239745deef404546b0820ac870f51604cc4e75d68586e7b202a07f984864a url: https://src.opensuse.org/perl/perl-HTML-Parser -revision: a98c4d2c128eef96aad66437d5139620ab432a6330ffc510beb7963fae2c71cf +revision: 5db239745deef404546b0820ac870f51604cc4e75d68586e7b202a07f984864a projectscmsync: https://src.opensuse.org/perl/_ObsPrj ++++++ build.specials.obscpio ++++++ ++++++ build.specials.obscpio ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/.gitignore new/.gitignore --- old/.gitignore 1970-01-01 01:00:00.000000000 +0100 +++ new/.gitignore 2026-09-20 11:51:09.000000000 +0200 @@ -0,0 +1 @@ +.osc
