Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package perl-Plack for openSUSE:Factory 
checked in at 2026-10-26 14:17:24
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/perl-Plack (Old)
 and      /work/SRC/openSUSE:Factory/.perl-Plack.new.2252680 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "perl-Plack"

Mon Oct 26 14:17:24 2026 rev:15 rq:1392700 version:1.0057

Changes:
--------
--- /work/SRC/openSUSE:Factory/perl-Plack/perl-Plack.changes    2026-06-13 
18:49:46.375500283 +0200
+++ /work/SRC/openSUSE:Factory/.perl-Plack.new.2252680/perl-Plack.changes       
2026-10-26 14:17:27.580759108 +0100
@@ -1,0 +2,37 @@
+Sat Oct 24 09:36:45 UTC 2026 - Tina Müller <[email protected]>
+
+- updated to 1.0057
+   see /usr/share/doc/packages/perl-Plack/Changes
+
+  1.0057  2026-10-24 02:01:28 PDT
+      [BUG FIXES]
+          - Fix Plack, Plack::Request and Plack::Response in 1.0056 still 
declaring $VERSION 1.0055,
+            which kept PAUSE from indexing 1.0056. This release contains the 
same fixes as 1.0056,
+            including CVE-2026-115825
+
+  1.0056  2026-10-24 01:55:22 PDT
+      [SECURITY]
+          - Fix HTTP::Server::PSGI allocating a buffer as large as the 
declared Content-Length,
+            which let a single request crash the server with "Out of memory!" 
(CVE-2026-115825) bsc#1287639
+      [BUG FIXES]
+          - Fix HTTP::Server::PSGI passing bytes after the Content-Length body 
to the app in psgi.input
+          - Fix HTTP::Server::PSGI accepting malformed, negative, duplicate or 
too long (more than
+            18 digits) Content-Length. Such requests now get 400 Bad Request
+          - Fix HTTP::Server::PSGI ignoring Transfer-Encoding and passing the 
raw chunked body to the app.
+            Such requests now get 501 Not Implemented
+          - Fix HTTP::Server::PSGI passing stray bytes after the headers as 
psgi.input when the request
+            has no Content-Length or a Content-Length of 0
+
+  1.0055  2026-10-13 15:00:27 PDT
+      [SECURITY]
+          - Fix memory leak of every request env in 
Plack::Middleware::Recursive (CVE-2026-110333)
+          - Plack::Request::Upload->basename never returns '', '.' or '..' 
(CVE-2026-110332)
+          - Plack::App::URLMap matches SERVER_PORT literally when stripping it 
from Host (CVE-2026-110335)
+      [BUG FIXES]
+          - Plack::Middleware::ErrorDocument restores the env after a 
subrequest, so outer
+            middleware such as AccessLog sees the original request 
(CVE-2026-110334)
+      [DOCUMENTATION]
+          - Document that Plack::Handler::FCGI and Apache2 keep dot segments 
in PATH_INFO and
+            warn against relying on front-server path-based access control 
(CVE-2026-110336)
+
+-------------------------------------------------------------------

Old:
----
  Plack-1.0054.tar.gz

New:
----
  Plack-1.0057.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ perl-Plack.spec ++++++
--- /var/tmp/diff_new_pack.Fi8ljl/_old  2026-10-26 14:17:28.486797016 +0100
+++ /var/tmp/diff_new_pack.Fi8ljl/_new  2026-10-26 14:17:28.488797100 +0100
@@ -18,7 +18,7 @@
 
 %define cpan_name Plack
 Name:           perl-Plack
-Version:        1.0054
+Version:        1.0057
 Release:        0
 License:        Artistic-1.0 OR GPL-1.0-or-later
 Summary:        Perl Superglue for Web frameworks and Web Servers (PSGI 
toolkit)

++++++ Plack-1.0054.tar.gz -> Plack-1.0057.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Plack-1.0054/Changes new/Plack-1.0057/Changes
--- old/Plack-1.0054/Changes    2026-05-05 08:38:14.000000000 +0200
+++ new/Plack-1.0057/Changes    2026-10-24 11:01:28.000000000 +0200
@@ -1,5 +1,36 @@
 Go to http://github.com/plack/Plack/issues for the roadmap and known issues.
 
+1.0057  2026-10-24 02:01:28 PDT
+    [BUG FIXES]
+        - Fix Plack, Plack::Request and Plack::Response in 1.0056 still 
declaring $VERSION 1.0055,
+          which kept PAUSE from indexing 1.0056. This release contains the 
same fixes as 1.0056,
+          including CVE-2026-115825
+
+1.0056  2026-10-24 01:55:22 PDT
+    [SECURITY]
+        - Fix HTTP::Server::PSGI allocating a buffer as large as the declared 
Content-Length,
+          which let a single request crash the server with "Out of memory!" 
(CVE-2026-115825)
+    [BUG FIXES]
+        - Fix HTTP::Server::PSGI passing bytes after the Content-Length body 
to the app in psgi.input
+        - Fix HTTP::Server::PSGI accepting malformed, negative, duplicate or 
too long (more than
+          18 digits) Content-Length. Such requests now get 400 Bad Request
+        - Fix HTTP::Server::PSGI ignoring Transfer-Encoding and passing the 
raw chunked body to the app.
+          Such requests now get 501 Not Implemented
+        - Fix HTTP::Server::PSGI passing stray bytes after the headers as 
psgi.input when the request
+          has no Content-Length or a Content-Length of 0
+
+1.0055  2026-10-13 15:00:27 PDT
+    [SECURITY]
+        - Fix memory leak of every request env in Plack::Middleware::Recursive 
(CVE-2026-110333)
+        - Plack::Request::Upload->basename never returns '', '.' or '..' 
(CVE-2026-110332)
+        - Plack::App::URLMap matches SERVER_PORT literally when stripping it 
from Host (CVE-2026-110335)
+    [BUG FIXES]
+        - Plack::Middleware::ErrorDocument restores the env after a 
subrequest, so outer
+          middleware such as AccessLog sees the original request 
(CVE-2026-110334)
+    [DOCUMENTATION]
+        - Document that Plack::Handler::FCGI and Apache2 keep dot segments in 
PATH_INFO and
+          warn against relying on front-server path-based access control 
(CVE-2026-110336)
+
 1.0054  2026-05-04 23:38:13 PDT
     [BUG FIXES]
         - Revert Plack::App::File REQUEST_METHOD check after locating file due 
to regression #725
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Plack-1.0054/MANIFEST new/Plack-1.0057/MANIFEST
--- old/Plack-1.0054/MANIFEST   2026-05-05 08:38:14.000000000 +0200
+++ new/Plack-1.0057/MANIFEST   2026-10-24 11:01:28.000000000 +0200
@@ -108,9 +108,11 @@
 t/HTTP-Message-PSGI/path_info.t
 t/HTTP-Message-PSGI/unknown_response.t
 t/HTTP-Message-PSGI/utf8_req.t
+t/HTTP-Server-PSGI/framing.t
 t/HTTP-Server-PSGI/harakiri.t
 t/HTTP-Server-PSGI/listen.t
 t/HTTP-Server-PSGI/post.t
+t/HTTP-Server-PSGI/read_size.t
 t/Plack-Builder/builder.t
 t/Plack-Builder/mount.t
 t/Plack-Builder/oo_interface.t
@@ -161,6 +163,7 @@
 t/Plack-Middleware/content_length.t
 t/Plack-Middleware/directory.t
 t/Plack-Middleware/error_document.t
+t/Plack-Middleware/error_document_restore_env.t
 t/Plack-Middleware/error_document_streaming_app.t
 t/Plack-Middleware/errors/404.html
 t/Plack-Middleware/errors/500.html
@@ -185,6 +188,7 @@
 t/Plack-Middleware/psgibin.t
 t/Plack-Middleware/rearrange_headers.t
 t/Plack-Middleware/recursive/base.t
+t/Plack-Middleware/recursive/leak.t
 t/Plack-Middleware/recursive/streaming.t
 t/Plack-Middleware/recursive/throw.t
 t/Plack-Middleware/recursive/throw_streaming.t
@@ -205,6 +209,7 @@
 t/Plack-Middleware/urlmap.t
 t/Plack-Middleware/urlmap_builder.t
 t/Plack-Middleware/urlmap_env.t
+t/Plack-Middleware/urlmap_port_meta.t
 t/Plack-Middleware/urlmap_ports.t
 t/Plack-Middleware/wrapcgi.t
 t/Plack-Middleware/wrapcgi_exec.t
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Plack-1.0054/META.json new/Plack-1.0057/META.json
--- old/Plack-1.0054/META.json  2026-05-05 08:38:14.000000000 +0200
+++ new/Plack-1.0057/META.json  2026-10-24 11:01:28.000000000 +0200
@@ -102,7 +102,7 @@
          "web" : "https://github.com/plack/Plack";
       }
    },
-   "version" : "1.0054",
+   "version" : "1.0057",
    "x_authority" : "cpan:MIYAGAWA",
    "x_contributors" : [
       "Aaron Trevena <[email protected]>",
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Plack-1.0054/META.yml new/Plack-1.0057/META.yml
--- old/Plack-1.0054/META.yml   2026-05-05 08:38:14.000000000 +0200
+++ new/Plack-1.0057/META.yml   2026-10-24 11:01:28.000000000 +0200
@@ -47,7 +47,7 @@
   bugtracker: https://github.com/plack/Plack/issues
   homepage: https://github.com/plack/Plack
   repository: https://github.com/plack/Plack.git
-version: '1.0054'
+version: '1.0057'
 x_authority: cpan:MIYAGAWA
 x_contributors:
   - 'Aaron Trevena <[email protected]>'
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Plack-1.0054/Makefile.PL new/Plack-1.0057/Makefile.PL
--- old/Plack-1.0054/Makefile.PL        2026-05-05 08:38:14.000000000 +0200
+++ new/Plack-1.0057/Makefile.PL        2026-10-24 11:01:28.000000000 +0200
@@ -50,7 +50,7 @@
     "Test::More" => "0.88",
     "Test::Requires" => 0
   },
-  "VERSION" => "1.0054",
+  "VERSION" => "1.0057",
   "test" => {
     "TESTS" => "t/*.t t/HTTP-Message-PSGI/*.t t/HTTP-Server-PSGI/*.t 
t/Plack-Builder/*.t t/Plack-HTTPParser-PP/*.t t/Plack-Handler/*.t 
t/Plack-Loader/*.t t/Plack-MIME/*.t t/Plack-Middleware/*.t 
t/Plack-Middleware/cascade/*.t t/Plack-Middleware/recursive/*.t 
t/Plack-Middleware/stacktrace/*.t t/Plack-Request/*.t t/Plack-Response/*.t 
t/Plack-Runner/*.t t/Plack-TempBuffer/*.t t/Plack-Test/*.t t/Plack-Util/*.t"
   }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Plack-1.0054/lib/HTTP/Server/PSGI.pm 
new/Plack-1.0057/lib/HTTP/Server/PSGI.pm
--- old/Plack-1.0054/lib/HTTP/Server/PSGI.pm    2026-05-05 08:38:14.000000000 
+0200
+++ new/Plack-1.0057/lib/HTTP/Server/PSGI.pm    2026-10-24 11:01:28.000000000 
+0200
@@ -31,6 +31,7 @@
 }
 
 use constant MAX_REQUEST_SIZE => 131072;
+use constant CHUNKSIZE        => 64 * 1024;
 use constant MSWin32          => $^O eq 'MSWin32';
 
 sub new {
@@ -159,15 +160,24 @@
         my $reqlen = parse_http_request($buf, $env);
         if ($reqlen >= 0) {
             $buf = substr $buf, $reqlen;
+            if (defined $env->{HTTP_TRANSFER_ENCODING}) {
+                # request bodies with Transfer-Encoding are not supported
+                $res = [ 501, [ 'Content-Type' => 'text/plain' ], [ 'Not 
Implemented' ] ];
+                last;
+            }
+            if (defined $env->{CONTENT_LENGTH} && $env->{CONTENT_LENGTH} !~ 
/\A[0-9]{1,18}\z/) {
+                # malformed, duplicate or too long (more than 18 digits) 
Content-Length
+                last;
+            }
             if (my $cl = $env->{CONTENT_LENGTH}) {
                 my $buffer = Stream::Buffered->new($cl);
                 while ($cl > 0) {
                     my $chunk;
                     if (length $buf) {
-                        $chunk = $buf;
-                        $buf = '';
+                        # $cl may be beyond UV_MAX, which substr() can't take
+                        $chunk = substr $buf, 0, ($cl < length $buf ? $cl : 
length $buf), '';
                     } else {
-                        $self->read_timeout($conn, \$chunk, $cl, 0, 
$self->{timeout})
+                        $self->read_timeout($conn, \$chunk, $cl < CHUNKSIZE ? 
$cl : CHUNKSIZE, 0, $self->{timeout})
                             or return;
                     }
                     $buffer->print($chunk);
@@ -175,7 +185,7 @@
                 }
                 $env->{'psgi.input'} = $buffer->rewind;
             } else {
-                open my $input, "<", \$buf;
+                open my $input, "<", \"";
                 $env->{'psgi.input'} = $input;
             }
 
@@ -340,7 +350,8 @@
 
 Some features in HTTP/1.1, notably chunked requests, responses and
 pipeline requests are B<NOT> supported, and it also does not support
-HTTP/0.9.
+HTTP/0.9. Requests with a C<Transfer-Encoding> header are rejected with
+501 Not Implemented.
 
 See L<Starman> or uWSGI server if you want HTTP/1.1 and other features
 ready for a production use.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Plack-1.0054/lib/Plack/App/URLMap.pm 
new/Plack-1.0057/lib/Plack/App/URLMap.pm
--- old/Plack-1.0054/lib/Plack/App/URLMap.pm    2026-05-05 08:38:14.000000000 
+0200
+++ new/Plack-1.0057/lib/Plack/App/URLMap.pm    2026-10-24 11:01:28.000000000 
+0200
@@ -45,7 +45,7 @@
     my($http_host, $server_name) = @{$env}{qw( HTTP_HOST SERVER_NAME )};
 
     if ($http_host and my $port = $env->{SERVER_PORT}) {
-        $http_host =~ s/:$port$//;
+        $http_host =~ s/:\Q$port\E$//;
     }
 
     for my $map (@{ $self->{_sorted_mapping} }) {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Plack-1.0054/lib/Plack/Handler/Apache2.pm 
new/Plack-1.0057/lib/Plack/Handler/Apache2.pm
--- old/Plack-1.0054/lib/Plack/Handler/Apache2.pm       2026-05-05 
08:38:14.000000000 +0200
+++ new/Plack-1.0057/lib/Plack/Handler/Apache2.pm       2026-10-24 
11:01:28.000000000 +0200
@@ -225,6 +225,17 @@
 standalone HTTP servers such as L<Starman> or L<Starlet> proxied with
 mod_proxy.
 
+=head1 PATH_INFO AND ACCESS CONTROL
+
+Because mod_perl squeezes multiple slashes in C<PATH_INFO>, this
+handler rebuilds C<PATH_INFO> from the unparsed request URI,
+percent-decoded. Dot segments such as C</../> are B<not> removed, so
+a request to C</admin/../public/x> is matched by Apache's
+C<< <Location> >> blocks as C</public/x> while your application sees
+C</admin/../public/x>. Do not rely on Apache's path-based access
+control to protect parts of your application: enforce it in the
+application (or in middleware) instead.
+
 =head1 CREATING CUSTOM HANDLER
 
 If you want to create a custom handler that loads or creates PSGI
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Plack-1.0054/lib/Plack/Handler/FCGI.pm 
new/Plack-1.0057/lib/Plack/Handler/FCGI.pm
--- old/Plack-1.0054/lib/Plack/Handler/FCGI.pm  2026-05-05 08:38:14.000000000 
+0200
+++ new/Plack-1.0057/lib/Plack/Handler/FCGI.pm  2026-10-24 11:01:28.000000000 
+0200
@@ -389,6 +389,22 @@
 
 See 
L<https://www.nginx.com/resources/wiki/start/topics/examples/fastcgiexample/> 
for more details.
 
+=head2 PATH_INFO AND ACCESS CONTROL
+
+Some web servers squeeze multiple slashes in C<PATH_INFO>, so this
+handler ignores the C<PATH_INFO> passed by the web server and rebuilds
+it from C<REQUEST_URI>, percent-decoded and with C<SCRIPT_NAME>
+stripped. Dot segments such as C</../> are B<not> removed.
+
+The web server, on the other hand, usually matches its C<location> or
+C<< <Location> >> blocks against the normalized path. A request to
+C</admin/../public/x> is matched by the web server as C</public/x>,
+but your application sees C<PATH_INFO> C</admin/../public/x>. Do not
+rely on path-based access control in the front web server to protect
+parts of your application: enforce it in the application (or in
+middleware) instead, or make sure the web server rejects request
+URIs containing dot segments.
+
 =head3 Apache mod_fastcgi
 
 After installing C<mod_fastcgi>, you should add the C<FastCgiExternalServer>
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Plack-1.0054/lib/Plack/Middleware/ErrorDocument.pm 
new/Plack-1.0057/lib/Plack/Middleware/ErrorDocument.pm
--- old/Plack-1.0054/lib/Plack/Middleware/ErrorDocument.pm      2026-05-05 
08:38:14.000000000 +0200
+++ new/Plack-1.0057/lib/Plack/Middleware/ErrorDocument.pm      2026-10-24 
11:01:28.000000000 +0200
@@ -28,6 +28,11 @@
                 }
             }
 
+            # the env is shared with outer middleware (e.g. AccessLog),
+            # so restore the original request after the subrequest
+            my @keys = qw(REQUEST_METHOD REQUEST_URI PATH_INFO QUERY_STRING 
CONTENT_LENGTH);
+            my %orig = map { exists $env->{$_} ? ($_ => $env->{$_}) : () } 
@keys;
+
             # TODO: What if SCRIPT_NAME is not empty?
             $env->{REQUEST_METHOD} = 'GET';
             $env->{REQUEST_URI}    = $path;
@@ -35,7 +40,13 @@
             $env->{QUERY_STRING}   = '';
             delete $env->{CONTENT_LENGTH};
 
-            my $sub_r = $self->app->($env);
+            my $sub_r = eval { $self->app->($env) };
+            my $err = $@;
+
+            for my $key (@keys) {
+                exists $orig{$key} ? ($env->{$key} = $orig{$key}) : delete 
$env->{$key};
+            }
+            die $err if $err;
             if ($sub_r->[0] == 200) {
                 $r->[1] = $sub_r->[1];
                 if (@$r == 3) {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Plack-1.0054/lib/Plack/Middleware/Recursive.pm 
new/Plack-1.0057/lib/Plack/Middleware/Recursive.pm
--- old/Plack-1.0054/lib/Plack/Middleware/Recursive.pm  2026-05-05 
08:38:14.000000000 +0200
+++ new/Plack-1.0057/lib/Plack/Middleware/Recursive.pm  2026-10-24 
11:01:28.000000000 +0200
@@ -46,12 +46,13 @@
 
     my $old_path_info = $env->{PATH_INFO};
 
+    # the include callback is stored in $env, so don't let it keep $env alive
+    Scalar::Util::weaken($env);
+
     return sub {
         my $new_path_info = shift;
         my($path, $query) = split /\?/, $new_path_info, 2;
 
-        Scalar::Util::weaken($env);
-
         $env->{PATH_INFO}      = $path;
         $env->{QUERY_STRING}   = $query;
         $env->{REQUEST_METHOD} = 'GET';
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Plack-1.0054/lib/Plack/Request/Upload.pm 
new/Plack-1.0057/lib/Plack/Request/Upload.pm
--- old/Plack-1.0054/lib/Plack/Request/Upload.pm        2026-05-05 
08:38:14.000000000 +0200
+++ new/Plack-1.0057/lib/Plack/Request/Upload.pm        2026-10-24 
11:01:28.000000000 +0200
@@ -35,6 +35,8 @@
         $basename =~ s|\\|/|g;
         $basename = ( File::Spec::Unix->splitpath($basename) )[2];
         $basename =~ s|[^\w\.-]+|_|g;
+        # never return an empty name or a directory reference
+        $basename = '_' if $basename =~ /^\.{0,2}\z/;
         $self->{basename} = $basename;
     }
     $self->{basename};
@@ -79,7 +81,13 @@
 
 =item basename
 
-Returns basename for "filename".
+Returns basename for "filename". Characters other than word
+characters, C<.> and C<-> are replaced with C<_>, and a name that
+would be empty, C<.> or C<..> is returned as C<_>.
+
+Note that the returned value is still client-supplied: you should
+make sure it doesn't overwrite existing files before using it as a
+file name.
 
 =back
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Plack-1.0054/lib/Plack/Request.pm 
new/Plack-1.0057/lib/Plack/Request.pm
--- old/Plack-1.0054/lib/Plack/Request.pm       2026-05-05 08:38:14.000000000 
+0200
+++ new/Plack-1.0057/lib/Plack/Request.pm       2026-10-24 11:01:28.000000000 
+0200
@@ -2,7 +2,7 @@
 use strict;
 use warnings;
 use 5.008_001;
-our $VERSION = '1.0054';
+our $VERSION = '1.0057';
 
 use HTTP::Headers::Fast;
 use Carp ();
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Plack-1.0054/lib/Plack/Response.pm 
new/Plack-1.0057/lib/Plack/Response.pm
--- old/Plack-1.0054/lib/Plack/Response.pm      2026-05-05 08:38:14.000000000 
+0200
+++ new/Plack-1.0057/lib/Plack/Response.pm      2026-10-24 11:01:28.000000000 
+0200
@@ -1,7 +1,7 @@
 package Plack::Response;
 use strict;
 use warnings;
-our $VERSION = '1.0054';
+our $VERSION = '1.0057';
 
 use Plack::Util::Accessor qw(body status);
 use Carp ();
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Plack-1.0054/lib/Plack.pm 
new/Plack-1.0057/lib/Plack.pm
--- old/Plack-1.0054/lib/Plack.pm       2026-05-05 08:38:14.000000000 +0200
+++ new/Plack-1.0057/lib/Plack.pm       2026-10-24 11:01:28.000000000 +0200
@@ -3,7 +3,7 @@
 use strict;
 use warnings;
 use 5.008_001;
-our $VERSION = '1.0054';
+our $VERSION = '1.0057';
 
 1;
 __END__
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Plack-1.0054/t/HTTP-Server-PSGI/framing.t 
new/Plack-1.0057/t/HTTP-Server-PSGI/framing.t
--- old/Plack-1.0054/t/HTTP-Server-PSGI/framing.t       1970-01-01 
01:00:00.000000000 +0100
+++ new/Plack-1.0057/t/HTTP-Server-PSGI/framing.t       2026-10-24 
11:01:28.000000000 +0200
@@ -0,0 +1,140 @@
+use strict;
+use warnings;
+
+use HTTP::Server::PSGI;
+use POSIX ();
+use Test::More;
+
+{
+    package FakeSocket;
+
+    # returns each segment in its own read, at most $len bytes at a time
+    sub new {
+        my($class, @segments) = @_;
+        bless { segments => [ @segments ], out => '' }, $class;
+    }
+
+    sub sysread {
+        my $self = shift;
+        my(undef, $len, $off) = @_;
+        my $seg = \$self->{segments}[0];
+        my $chunk = defined $$seg ? substr $$seg, 0, $len, '' : '';
+        shift @{$self->{segments}} if defined $$seg && !length $$seg;
+        $_[0] = '' unless defined $_[0];
+        substr($_[0], $off || 0) = $chunk;
+        return length $chunk;
+    }
+
+    sub syswrite {
+        my($self, $buf, $len, $off) = @_;
+        $self->{out} .= substr $buf, $off || 0, $len;
+        return $len;
+    }
+}
+
+my $server = HTTP::Server::PSGI->new(timeout => 5);
+
+sub run_request {
+    my $sock = FakeSocket->new(@_);
+    my $body;
+    $server->handle_connection({}, $sock, sub {
+        my $env = shift;
+        local $/;
+        my $input = $env->{'psgi.input'};
+        $body = <$input>;
+        [ 200, [ 'Content-Type' => 'text/plain' ], [ 'OK' ] ];
+    });
+    my($status) = $sock->{out} =~ m{^HTTP/1\.\d (\d+)};
+    return ($status, $body);
+}
+
+{
+    my($status, $body) = run_request(
+        "POST / HTTP/1.0\r\nContent-Length: 3\r\n\r\nabcGET /next 
HTTP/1.0\r\n\r\n"
+    );
+    is $status, 200;
+    is $body, 'abc', 'body stops at Content-Length';
+}
+
+{
+    my($status, $body) = run_request(
+        "POST / HTTP/1.0\r\nContent-Length: 5\r\n\r\nab", "c", "de", "GET / 
HTTP/1.0\r\n\r\n",
+    );
+    is $status, 200;
+    is $body, 'abcde', 'body arriving in short reads is read up to 
Content-Length';
+}
+
+{
+    my($status, $body) = run_request(
+        "POST / HTTP/1.0\r\nContent-Length: 10\r\n\r\nab", "c",
+    );
+    is $status, undef, 'no response when the connection closes mid-body';
+    is $body, undef, 'app is not called';
+}
+
+SKIP: {
+    skip 'needs fork', 2 if $^O eq 'MSWin32';
+    # Content-Length beyond UV_MAX used to make substr() take all but the
+    # last byte of the buffer and then spin forever on the rest. Such values
+    # are now rejected as too long before the body is read.
+    for my $cl ('18446744073709551616', '9' x 400) {
+        my $pid = fork;
+        die "fork: $!" unless defined $pid;
+        if ($pid == 0) {
+            run_request("POST / HTTP/1.0\r\nContent-Length: $cl\r\n\r\nhello");
+            POSIX::_exit(0);
+        }
+        my $done;
+        for (1..50) {
+            last if $done = waitpid($pid, POSIX::WNOHANG()) == $pid;
+            select undef, undef, undef, 0.1;
+        }
+        unless ($done) {
+            kill 'KILL', $pid;
+            waitpid $pid, 0;
+        }
+        ok $done, 'huge Content-Length (' . length($cl) . ' digits) does not 
loop';
+    }
+}
+
+for my $cl ('-5', '+5', '5abc', '0x5', '5, 9', '5, 5', '9' x 19, '0' x 18 . 
'5') {
+    my($status, $body) = run_request(
+        "POST / HTTP/1.0\r\nContent-Length: $cl\r\n\r\nabcdefghi"
+    );
+    is $status, 400, "invalid Content-Length '$cl' is rejected";
+    is $body, undef, 'app is not called';
+}
+
+{
+    my($status, $body) = run_request(
+        "POST / HTTP/1.0\r\nContent-Length: 5\r\nContent-Length: 
9\r\n\r\nabcdefghi"
+    );
+    is $status, 400, 'duplicate Content-Length headers are rejected';
+}
+
+for my $cl ('', "Content-Length: 0\r\n") {
+    my($status, $body) = run_request(
+        "GET / HTTP/1.0\r\n$cl\r\ntrailing junk"
+    );
+    is $status, 200;
+    is $body, '', 'no body without Content-Length' . ($cl ? ' (0)' : '');
+}
+
+for my $te ('chunked', 'gzip, chunked', 'identity') {
+    for my $cl ('', "Content-Length: 3\r\n") {
+        my($status, $body) = run_request(
+            "POST / HTTP/1.1\r\nTransfer-Encoding: 
$te\r\n$cl\r\n3\r\nabc\r\n0\r\n\r\n"
+        );
+        is $status, 501, "Transfer-Encoding '$te' is rejected" . ($cl ? ' with 
Content-Length' : '');
+        is $body, undef, 'app is not called';
+    }
+}
+
+for my $cl ('0', '5', '005', '0' x 17 . '5') {
+    my($status, $body) = run_request(
+        "POST / HTTP/1.0\r\nContent-Length: $cl\r\n\r\nabcde"
+    );
+    is $status, 200, "valid Content-Length '$cl' is accepted";
+}
+
+done_testing;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Plack-1.0054/t/HTTP-Server-PSGI/read_size.t 
new/Plack-1.0057/t/HTTP-Server-PSGI/read_size.t
--- old/Plack-1.0054/t/HTTP-Server-PSGI/read_size.t     1970-01-01 
01:00:00.000000000 +0100
+++ new/Plack-1.0057/t/HTTP-Server-PSGI/read_size.t     2026-10-24 
11:01:28.000000000 +0200
@@ -0,0 +1,52 @@
+use strict;
+use warnings;
+
+use HTTP::Server::PSGI;
+use Test::More;
+
+{
+    package FakeSocket;
+
+    # returns each segment in its own read, at most $len bytes at a time
+    sub new {
+        my($class, @segments) = @_;
+        bless { segments => [ @segments ], reads => [], out => '' }, $class;
+    }
+
+    sub sysread {
+        my $self = shift;
+        my(undef, $len, $off) = @_;
+        push @{$self->{reads}}, $len;
+        my $seg = \$self->{segments}[0];
+        my $chunk = defined $$seg ? substr $$seg, 0, $len, '' : '';
+        shift @{$self->{segments}} if defined $$seg && !length $$seg;
+        $_[0] = '' unless defined $_[0];
+        substr($_[0], $off || 0) = $chunk;
+        return length $chunk;
+    }
+
+    sub syswrite {
+        my($self, $buf, $len, $off) = @_;
+        $self->{out} .= substr $buf, $off || 0, $len;
+        return $len;
+    }
+}
+
+my $server = HTTP::Server::PSGI->new(timeout => 5);
+my $app = sub { [ 200, [ 'Content-Type' => 'text/plain' ], [ 'OK' ] ] };
+
+{
+    my $sock = FakeSocket->new(
+        "POST / HTTP/1.0\r\nContent-Length: 100000000000\r\n\r\n",
+        'x' x (200 * 1024),
+    );
+    $server->handle_connection({}, $sock, $app);
+
+    my(undef, @body_reads) = @{$sock->{reads}};
+    cmp_ok scalar(@body_reads), '>', 1, 'body is read in several reads';
+    my($max) = sort { $b <=> $a } @body_reads;
+    cmp_ok $max, '<=', HTTP::Server::PSGI::CHUNKSIZE,
+        'huge Content-Length does not make a huge sysread';
+}
+
+done_testing;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/Plack-1.0054/t/Plack-Middleware/error_document_restore_env.t 
new/Plack-1.0057/t/Plack-Middleware/error_document_restore_env.t
--- old/Plack-1.0054/t/Plack-Middleware/error_document_restore_env.t    
1970-01-01 01:00:00.000000000 +0100
+++ new/Plack-1.0057/t/Plack-Middleware/error_document_restore_env.t    
2026-10-24 11:01:28.000000000 +0200
@@ -0,0 +1,45 @@
+use strict;
+use warnings;
+use FindBin;
+use Test::More;
+use HTTP::Request::Common;
+use Plack::Test;
+use Plack::Builder;
+
+my @lines;
+my $inner_env;
+
+my $handler = builder {
+    enable "AccessLog", format => '%r %>s', logger => sub { push @lines, $_[0] 
};
+    enable sub {
+        my $app = shift;
+        sub { $inner_env = $_[0]; $app->($_[0]) };
+    };
+    enable "ErrorDocument", 404 => "/errors/404.html", subrequest => 1;
+    enable "Static", path => qr{^/errors}, root => $FindBin::Bin;
+
+    sub {
+        my $env = shift;
+        my $status = ($env->{PATH_INFO} =~ m!status/(\d+)!)[0] || 200;
+        [ $status, [ 'Content-Type' => 'text/plain' ], [ "Error: $status" ] ];
+    };
+};
+
+test_psgi app => $handler, client => sub {
+    my $cb = shift;
+
+    my $res = $cb->(POST "http://localhost/status/404?q=1";, [ foo => 'bar' ]);
+    is $res->code, 404;
+    like $res->content, qr/fancy 404/;
+
+    is $inner_env->{REQUEST_METHOD}, 'POST';
+    is $inner_env->{PATH_INFO}, '/status/404';
+    is $inner_env->{QUERY_STRING}, 'q=1';
+    is $inner_env->{REQUEST_URI}, '/status/404?q=1';
+    ok $inner_env->{CONTENT_LENGTH}, 'CONTENT_LENGTH is restored';
+
+    is scalar @lines, 1;
+    like $lines[0], qr{^POST /status/404\?q=1 HTTP/1\.1 404}, 'access log 
records the original request';
+};
+
+done_testing;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Plack-1.0054/t/Plack-Middleware/recursive/leak.t 
new/Plack-1.0057/t/Plack-Middleware/recursive/leak.t
--- old/Plack-1.0054/t/Plack-Middleware/recursive/leak.t        1970-01-01 
01:00:00.000000000 +0100
+++ new/Plack-1.0057/t/Plack-Middleware/recursive/leak.t        2026-10-24 
11:01:28.000000000 +0200
@@ -0,0 +1,27 @@
+use strict;
+use Test::More;
+use Scalar::Util qw(weaken);
+
+use Plack::Middleware::Recursive;
+
+my $app = Plack::Middleware::Recursive->wrap(sub {
+    my $env = shift;
+    if ($env->{PATH_INFO} eq '/include') {
+        return $env->{'plack.recursive.include'}->("/included");
+    }
+    return [ 200, [ 'Content-Type' => 'text/plain' ], [ "ok" ] ];
+});
+
+for my $path ('/', '/include') {
+    my $weak;
+    {
+        my $env = { PATH_INFO => $path, REQUEST_METHOD => 'GET' };
+        my $res = $app->($env);
+        is $res->[0], 200;
+        $weak = $env;
+        weaken $weak;
+    }
+    ok !defined $weak, "env is freed after request to $path";
+}
+
+done_testing;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Plack-1.0054/t/Plack-Middleware/urlmap_port_meta.t 
new/Plack-1.0057/t/Plack-Middleware/urlmap_port_meta.t
--- old/Plack-1.0054/t/Plack-Middleware/urlmap_port_meta.t      1970-01-01 
01:00:00.000000000 +0100
+++ new/Plack-1.0057/t/Plack-Middleware/urlmap_port_meta.t      2026-10-24 
11:01:28.000000000 +0200
@@ -0,0 +1,35 @@
+use strict;
+use Test::More;
+use Plack::App::URLMap;
+
+my $make_app = sub {
+    my $name = shift;
+    sub { [ 200, [ 'Content-Type' => 'text/plain' ], [ $name ] ] };
+};
+
+my $app = Plack::App::URLMap->new;
+$app->map("http://example.com/"; => $make_app->("host"));
+$app->map("/" => $make_app->("default"));
+
+my $env = sub {
+    my($host, $port) = @_;
+    return {
+        HTTP_HOST   => $host,
+        SERVER_NAME => 'localhost',
+        SERVER_PORT => $port,
+        PATH_INFO   => '/',
+        SCRIPT_NAME => '',
+    };
+};
+
+is $app->($env->('example.com:8080', 8080))->[2][0], 'host', 'port is stripped 
from Host';
+
+# SERVER_PORT containing regex metacharacters must be matched literally
+my $res = eval { $app->($env->('example.com:(', '(')) };
+is $@, '', 'regex metacharacters in SERVER_PORT do not die';
+is $res->[2][0], 'host', 'literal port is stripped from Host';
+
+$res = eval { $app->($env->('example.com:80', '.*')) };
+is $res->[2][0], 'default', 'SERVER_PORT is not used as a pattern';
+
+done_testing;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/Plack-1.0054/t/Plack-Request/upload-basename.t 
new/Plack-1.0057/t/Plack-Request/upload-basename.t
--- old/Plack-1.0054/t/Plack-Request/upload-basename.t  2026-05-05 
08:38:14.000000000 +0200
+++ new/Plack-1.0057/t/Plack-Request/upload-basename.t  2026-10-24 
11:01:28.000000000 +0200
@@ -1,9 +1,21 @@
 use strict;
 use warnings;
-use Test::More tests => 1;
+use Test::More;
 use Plack::Request::Upload;
 
 my $upload = Plack::Request::Upload->new(
     filename => '/tmp/foo/bar/hoge.txt',
 );
 is $upload->basename, 'hoge.txt';
+
+for my $filename ('..', '.', '', 'x/', 'x/..', 'x\\..', '../..', '/') {
+    my $upload = Plack::Request::Upload->new(filename => $filename);
+    my $basename = $upload->basename;
+    ok length $basename, "basename for '$filename' is not empty";
+    ok $basename ne '.' && $basename ne '..', "basename for '$filename' is not 
a dot directory";
+}
+
+is( Plack::Request::Upload->new(filename => '..foo')->basename, '..foo' );
+is( Plack::Request::Upload->new(filename => '.htaccess')->basename, 
'.htaccess' );
+
+done_testing;

++++++ _scmsync.obsinfo ++++++
--- /var/tmp/diff_new_pack.Fi8ljl/_old  2026-10-26 14:17:28.735807435 +0100
+++ /var/tmp/diff_new_pack.Fi8ljl/_new  2026-10-26 14:17:28.738807560 +0100
@@ -1,6 +1,6 @@
-mtime: 1777966395
-commit: e965fa2ebab8c289f65dc58f15da74270e07bea67464a5b3169c4e91bdf0dc96
+mtime: 1793012414
+commit: 9538429a1e186f1adfaa027c9624b80c307516101ddd9f37e8d7ffbe76c27de0
 url: https://src.opensuse.org/perl/perl-Plack
-revision: e965fa2ebab8c289f65dc58f15da74270e07bea67464a5b3169c4e91bdf0dc96
+revision: 9538429a1e186f1adfaa027c9624b80c307516101ddd9f37e8d7ffbe76c27de0
 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-10-26 12:00:14.000000000 +0100
@@ -0,0 +1 @@
+.osc

Reply via email to