Package: release.debian.org
Severity: normal
Tags: trixie
X-Debbugs-Cc: [email protected], [email protected], 
[email protected], [email protected], [email protected]
Control: affects -1 + src:libdbi-perl
User: [email protected]
Usertags: pu

Hi

[ Reason ]
libdbi-perl in trixie is affected by some CVEs, CVE-2026-111879,
CVE-2026-108518, CVE-2026-88816, CVE-2026-88815 and CVE-2026-78030
which we marked as no-dsa.

[ Impact ]
The CVEs would remain open for time beeing.

[ Tests ]
Automated (extensive) test suite was run. Additionally QA testing
trough debusine was performed via
https://debusine.debian.net/debian/developers/work-request/1600434/ .

[ Risks ]
As in the previous (trixie-securty) update this was done by rebasing
the version. Hopefully we might come back to the backporting approach
but for DBI upstream suggested to rebase for the earlier version. The
import of 1.656 consist mainly of the new security fixes.

[ Checklist ]
  [x] *all* changes are documented in the d/changelog
  [x] I reviewed all changes and I approve them
  [x] attach debdiff against the package in (old)stable
  [x] the issue is verified as fixed in unstable

Regards,
Salvatore
diff -Nru libdbi-perl-1.652/ChangeLog libdbi-perl-1.656/ChangeLog
--- libdbi-perl-1.652/ChangeLog 2026-08-15 10:50:43.000000000 +0200
+++ libdbi-perl-1.656/ChangeLog 2026-10-17 14:46:46.000000000 +0200
@@ -1,3 +1,30 @@
+1.656 - 2026-10-17, H.Merijn Brand & Robert Rothenberg
+    * Re-add conflicts to cpanfile. (WIP)
+    * Remove lock file on end of scope
+    * Prevent dbi_profile crash (CVE-2026-108518) (Henrik Teichmann)
+    * Memory corruption via selectrow_array + SQLite UDF (issue#98)
+    * Fix errstr when dbm_updatable_key attribute for DBD::DBM is set to 2 
(croak) on Perl versions < v5.13.2.
+    * Fix emit warnings when dbm_updatable_key attribute for DBD::DBM is set 
to 1 (carp)
+    * Fix lock file not removed when DBD::DBM check for bad serializer class 
fails. (CVE-2026-111879)
+    * *** WARNING: Next release will require perl-5.14 ***
+      - Main reason: Exception handling
+
+1.655 - 2026-09-30, H.Merijn Brand & Robert Rothenberg
+    * Fix for C89 (Paul Howarth, PR#197)
+    * Ignore invalid handles consistently (detected by Raj)
+
+1.654 - 2026-09-25, H.Merijn Brand & Robert Rothenberg
+    * Fix DBI::sql_type_cast on IV/NV (CVE-2026-88815) (reported by Raj)
+    * Fix FetchHashKeyName   on IV/NV (CVE-2026-88816) (reported by Raj)
+    * Fix provided in META
+
+1.653 - 2026-09-09, H.Merijn Brand & Robert Rothenberg
+    * Fix test for 32bit-perl (report in PR#189)
+    * Fix arbitrary module and file loading via dbm_type/dbm_mldbm 
(CVE-2026-78030)
+    * More META checking/updates
+    * Tighten symlink outside of f_dir (CVE-2026-15392) check (reported by Raj)
+    * CPAN.org does not forward email anymore
+
 1.652 - 2026-08-15, H.Merijn Brand & Robert Rothenberg
     * DBI now requires perl-5.12, driven by CVE's
     * Fix test for perl configured without threads (caught by perl-5.45.1)
diff -Nru libdbi-perl-1.652/DBI.pm libdbi-perl-1.656/DBI.pm
--- libdbi-perl-1.652/DBI.pm    2026-07-24 17:14:05.000000000 +0200
+++ libdbi-perl-1.656/DBI.pm    2026-10-09 15:57:31.000000000 +0200
@@ -16,7 +16,7 @@
 
 our ($XS_VERSION, $VERSION);
 BEGIN {
-$VERSION = "1.652"; # ==> ALSO update the version in the pod text below!
+$VERSION = "1.656"; # ==> ALSO update the version in the pod text below!
 $XS_VERSION = $VERSION;
 $VERSION =~ tr/_//d;
 }
@@ -148,7 +148,7 @@
 
 =head2 NOTES
 
-This is the DBI specification that corresponds to DBI version 1.652
+This is the DBI specification that corresponds to DBI version 1.656
 (see L<DBI::Changes> for details).
 
 The DBI is evolving at a steady pace, so it's good to check that
@@ -7487,7 +7487,7 @@
 
 Using DBI with perl threads is not yet recommended for production
 environments. For more information see
-L<https://www.perlmonks.org/index.pl?node_id=288022>
+https://www.perlmonks.org/index.pl?node_id=288022
 
 =head2 Signal Handling and Canceling Operations
 
@@ -7734,7 +7734,7 @@
 bite you by (in)conveniently creating an unblessed hashref, which your
 method will then return with usually baffling results later on like
 the error "dbih_getcom handle HASH(0xa4451a8) is not a DBI handle (has
-no magic".  It's best to check right after the call and return undef
+no magic)".  It's best to check right after the call and return undef
 immediately on error, just like DBI would and just like the example
 above.
 
@@ -8187,31 +8187,28 @@
  type_info         SQLGetTypeInfo    Page 239
  statistics_info   SQLStatistics
 
-To find documentation on the ODBC function you can use
-the MSDN search facility at:
+To find documentation on the ODBC function you can browse Microsoft's 
documentation at:
 
-    http://msdn.microsoft.com/Search
-
-and search for something like C<"SQLColumns returns">.
+L<https://learn.microsoft.com/en-us/sql/odbc/reference/odbc-programmer-s-reference>
 
 And for SQL/CLI standard information on SQLColumns you'd read page 124 of
 the (very large) SQL/CLI Working Draft available from:
 
-  http://jtc1sc32.org/doc/N0701-0750/32N0744T.pdf
+L<https://web.archive.org/web/20071107215745/http://jtc1sc32.org/doc/N0701-0750/32N0744T.pdf>
 
 =head2 Standards Reference Information
 
 A hyperlinked, browsable version of the BNF syntax for SQL92 (plus
 Oracle 7 SQL and PL/SQL) is available here:
 
-  http://cui.unige.ch/db-research/Enseignement/analyseinfo/SQL92/BNFindex.html
+L<https://web.archive.org/web/20040212094722/http://cui.unige.ch/db-research/Enseignement/analyseinfo/SQL92/BNFindex.html>
 
 You can find more information about SQL standards online by searching for the
 appropriate standard names and numbers. For example, searching for
 "ANSI/ISO/IEC International Standard (IS) Database Language SQL - Part 1:
 SQL/Framework" you'll find a copy at:
 
-  ftp://ftp.iks-jena.de/mitarb/lutz/standards/sql/ansi-iso-9075-1-1999.pdf
+L<ftp://ftp.iks-jena.de/mitarb/lutz/standards/sql/ansi-iso-9075-1-1999.pdf>
 
 =head2 Books and Articles
 
diff -Nru libdbi-perl-1.652/DBI.xs libdbi-perl-1.656/DBI.xs
--- libdbi-perl-1.652/DBI.xs    2026-08-15 10:29:58.000000000 +0200
+++ libdbi-perl-1.656/DBI.xs    2026-10-12 10:08:01.000000000 +0200
@@ -1080,7 +1080,7 @@
         if (!what)
             return NULL;
         if (!hv_fetchs((HV*)ohv,"_NO_DESTRUCT_WARN",0))
-           sv_dump(orv);
+            sv_dump(orv);
         croak("%s handle %s is not a DBI handle (has no magic)",
                 what, neatsvpv(orv,0));
     }
@@ -1925,6 +1925,8 @@
     int cast_ok = 0;
     int grok_flags;
     UV uv;
+    STRLEN len;
+    char *p;
 
     /* do nothing for undef (NULL) or non-string values */
     if (!sv || !SvOK(sv))
@@ -1957,8 +1959,9 @@
     /* else no error and sv is untouched */
     case SQL_NUMERIC:
         /* based on the code in perl's toke.c */
+        p = SvPV(sv, len); /* force stringify, handle magic */
         uv = 0;
-        grok_flags = grok_number(SvPVX(sv), SvCUR(sv), &uv);
+        grok_flags = grok_number(p, len, &uv);
         cast_ok = 1;
         if (grok_flags == IS_NUMBER_IN_UV) { /* +ve int */
             if (uv <= IV_MAX)   /* prefer IV over UV */
@@ -2350,10 +2353,10 @@
                         i = AvFILL(name_av)+1; /* limit for safe iteration 
over array */
                     }
 
-                   if (DBIc_TRACE_LEVEL(imp_sth) >= 10 || (num_fields_mismatch 
&& DBIc_WARN(imp_xxh))) {
-                       PerlIO_printf(DBIc_LOGPIO(imp_sth),"       FETCH 
$h->{%s} from $h->{NAME} with $h->{NUM_OF_FIELDS} = %d"
-                                              " and %ld entries in 
$h->{NAME}%s\n",
-                               neatsvpv(keysv,0), DBIc_NUM_FIELDS(imp_sth), 
AvFILL(name_av)+1,
+                    if (DBIc_TRACE_LEVEL(imp_sth) >= 10 || 
(num_fields_mismatch && DBIc_WARN(imp_xxh))) {
+                        PerlIO_printf(DBIc_LOGPIO(imp_sth),"       FETCH 
$h->{%s} from $h->{NAME} with $h->{NUM_OF_FIELDS} = %d"
+                                               " and %ld entries in 
$h->{NAME}%s\n",
+                                neatsvpv(keysv,0), DBIc_NUM_FIELDS(imp_sth), 
AvFILL(name_av)+1,
                                 (num_fields_mismatch) ? " (possible bug in 
driver)" : "");
                     }
 
@@ -3001,7 +3004,13 @@
                         dbh_outer_hv = DBIc_MY_H(imp_dbh);
                         if (SvTYPE(dbh_outer_hv) != SVt_PVHV)
                             return &PL_sv_undef;        /* presumably global 
destruction - bail */
-                        dbh_inner_hv = (HV*)SvRV(dbih_inner(aTHX_ 
(SV*)dbh_outer_hv, "profile"));
+                        {   /* dbih_inner() returns the inner handle as an RV, 
except when it was
+                             * given a raw inner HV (DBIc_MY_H() is set to the 
inner HV while the
+                             * outer handle is being destroyed): then it 
returns that HV itself,
+                             * and SvRV() on it would return its bucket array 
(HvARRAY). */
+                            SV *irv = dbih_inner(aTHX_ (SV*)dbh_outer_hv, 
"profile");
+                            dbh_inner_hv = (HV*)(SvROK (irv) ? SvRV (irv) : 
irv);
+                        }
                         if (SvTYPE(dbh_inner_hv) != SVt_PVHV)
                             return &PL_sv_undef;        /* presumably global 
destruction - bail */
                     }
@@ -3409,8 +3418,8 @@
         for(i=1; i < items; ++i) {
             if (SvTAINTED(ST(i))) {
                 SV *taint_msg = sv_2mortal(newSVpvf(
-                   "parameter %d of %s->%s method call",
-                   i, SvPV_nolen(h), meth_name));
+                    "parameter %d of %s->%s method call",
+                    i, SvPV_nolen(h), meth_name));
                 PL_tainted = 1; /* needed for TAINT_PROPER to work      */
                 TAINT_PROPER(SvPV_nolen(taint_msg));      /* die's */
             }
@@ -4144,7 +4153,7 @@
         we add support for odbc escape sequences.
 */
     int idx = 1;
-    int sln;
+    STRLEN sln;
 
     char in_quote = '\0';
     char in_comment = '\0';
@@ -4358,7 +4367,7 @@
         else if (isDIGIT(*src)) {   /* :1 */
             const int pln = atoi(src);
 
-            if (pln > 99999 || pln <= 0) {
+            if (strspn(src, "0123456789") > 5 || pln > 99999 || pln <= 0) {
                 char buf[99];
                 sprintf(buf, "preparse found :p%d which is outside the allowed 
range.", pln);
                 set_err_char(dbh, imp_xxh, "1", 1, buf, 0, "preparse");
@@ -5304,7 +5313,7 @@
     if (!keyattrib || !*keyattrib) {
         SV *kn = DBIc_FetchHashKeyName(imp_sth);
         if (kn && SvOK(kn))
-            keyattrib = SvPVX(kn);
+            keyattrib = SvPV_nolen(kn); /* Also force stringification */
         else
             keyattrib = "NAME";
     }
diff -Nru libdbi-perl-1.652/Driver.xst libdbi-perl-1.656/Driver.xst
--- libdbi-perl-1.652/Driver.xst        2026-05-28 14:03:05.000000000 +0200
+++ libdbi-perl-1.656/Driver.xst        2026-10-15 15:30:17.000000000 +0200
@@ -164,12 +164,16 @@
             sth = mg->mg_obj;
     }
     else {
+        MAGIC *mg;
         sth = dbixst_bounce_method("prepare", 3);
         SPAGAIN; SP -= items; /* because stack might have been realloc'd */
         if (!SvROK(sth))
             XSRETURN_UNDEF;
         /* switch to inner handle */
-        sth = mg_find(SvRV(sth),'P')->mg_obj;
+        mg  = mg_find(SvRV(sth),'P');
+        if (!mg)
+            XSRETURN_UNDEF;
+        sth = mg->mg_obj;
     }
     imp_sth = (imp_sth_t*)(DBIh_COM(sth));
     /* --- bind_param --- */
@@ -204,10 +208,14 @@
         MAGIC *mg;
         sth = ST(1);
         /* switch to inner handle if not already */
-        if ( (mg = mg_find(SvRV(sth),'P')) )
-            sth = mg->mg_obj;
+        mg  = mg_find(SvRV(sth),'P');
+        if (!mg) {
+            if (is_selectrow_array) { XSRETURN_EMPTY; } else { XSRETURN_UNDEF; 
}
+        }
+        sth = mg->mg_obj;
     }
     else {
+        MAGIC *mg;
         /* --- prepare --- */
         sth = dbixst_bounce_method("prepare", 3);
         SPAGAIN; SP -= items; /* because stack might have been realloc'd */
@@ -215,7 +223,11 @@
             if (is_selectrow_array) { XSRETURN_EMPTY; } else { XSRETURN_UNDEF; 
}
         }
         /* switch to inner handle */
-        sth = mg_find(SvRV(sth),'P')->mg_obj;
+        mg  = mg_find(SvRV(sth),'P');
+        if (!mg) {
+            if (is_selectrow_array) { XSRETURN_EMPTY; } else { XSRETURN_UNDEF; 
}
+        }
+        sth = mg->mg_obj;
     }
     imp_sth = (imp_sth_t*)(DBIh_COM(sth));
     /* --- bind_param --- */
@@ -229,8 +241,10 @@
     if ( dbd_st_execute(sth, imp_sth) <= -2 ) { /* -2 == error */
         if (is_selectrow_array) { XSRETURN_EMPTY; } else { XSRETURN_UNDEF; }
     }
+    SPAGAIN; SP -= items; /* because stack might have been realloc'd */
     /* --- fetchrow_arrayref --- */
     row_av = dbd_st_fetch(sth, imp_sth);
+    SPAGAIN; SP -= items; /* because stack might have been realloc'd */
     if (!row_av) {
         if (GIMME_V == G_SCALAR)
             PUSHs(&PL_sv_undef);
diff -Nru libdbi-perl-1.652/MANIFEST libdbi-perl-1.656/MANIFEST
--- libdbi-perl-1.652/MANIFEST  2026-08-15 13:29:17.000000000 +0200
+++ libdbi-perl-1.656/MANIFEST  2026-10-18 13:19:48.000000000 +0200
@@ -104,11 +104,13 @@
 t/41prof_dump.t
 t/42prof_data.t
 t/43prof_env.t
+t/44prof_caller.t
 t/48dbi_dbd_sqlengine.t                Tests for DBI::DBD::SqlEngine
 t/49dbd_file.t                 DBD::File API and very basic tests
 t/50dbm_simple.t               simple DBD::DBM tests
 t/51dbm_file.t                 extended DBD::File tests (through DBD::DBM)
 t/52dbm_complex.t              Complex DBD::DBM tests with SQL::Statement
+t/53dbm_module_name.t          dbm_type / dbm_mldbm must name a module, not a 
path
 t/53sqlengine_adv.t
 t/54_dbd_mem.t
 t/60preparse.t
diff -Nru libdbi-perl-1.652/META.json libdbi-perl-1.656/META.json
--- libdbi-perl-1.652/META.json 2026-08-15 13:29:17.000000000 +0200
+++ libdbi-perl-1.656/META.json 2026-10-18 13:19:48.000000000 +0200
@@ -1,67 +1,263 @@
 {
-   "abstract" : "Database independent interface for Perl",
-   "author" : [
-      "DBI team ([email protected])"
-      ],
+   "release_status" : "stable",
    "dynamic_config" : 1,
-   "generated_by" : "ExtUtils::MakeMaker version 7.78, CPAN::Meta::Converter 
version 2.150013",
+   "resources" : {
+      "x_IRC" : "irc://irc.perl.org/#dbi",
+      "bugtracker" : {
+         "web" : "https://github.com/perl5-dbi/dbi/issues";
+         },
+      "repository" : {
+         "url" : "https://github.com/perl5-dbi/dbi";,
+         "type" : "git",
+         "web" : "https://github.com/perl5-dbi/dbi";
+         },
+      "license" : [
+         "http://dev.perl.org/licenses/";
+         ]
+      },
+   "provides" : {
+      "DBD::Gofer::Policy::classic" : {
+         "file" : "lib/DBD/Gofer/Policy/classic.pm",
+         "version" : "0.010088"
+         },
+      "DBD::Gofer::Transport::pipeone" : {
+         "file" : "lib/DBD/Gofer/Transport/pipeone.pm",
+         "version" : "0.010088"
+         },
+      "DBI::Gofer::Serializer::Storable" : {
+         "file" : "lib/DBI/Gofer/Serializer/Storable.pm",
+         "version" : "0.015586"
+         },
+      "DBD::Gofer::Policy::Base" : {
+         "file" : "lib/DBD/Gofer/Policy/Base.pm",
+         "version" : "0.010088"
+         },
+      "DBD::ExampleP" : {
+         "version" : "12.014311",
+         "file" : "lib/DBD/ExampleP.pm"
+         },
+      "DBD::Gofer::Policy::pedantic" : {
+         "file" : "lib/DBD/Gofer/Policy/pedantic.pm",
+         "version" : "0.010088"
+         },
+      "DBI::ProfileDumper" : {
+         "version" : "2.015325",
+         "file" : "lib/DBI/ProfileDumper.pm"
+         },
+      "DBI::Profile" : {
+         "version" : "2.015065",
+         "file" : "lib/DBI/Profile.pm"
+         },
+      "DBD::Gofer::Transport::Base" : {
+         "file" : "lib/DBD/Gofer/Transport/Base.pm",
+         "version" : "0.014121"
+         },
+      "DBI::ProfileSubs" : {
+         "file" : "lib/DBI/ProfileSubs.pm",
+         "version" : "0.009396"
+         },
+      "DBI::Gofer::Serializer::Base" : {
+         "file" : "lib/DBI/Gofer/Serializer/Base.pm",
+         "version" : "0.009950"
+         },
+      "DBI::DBD::SqlEngine" : {
+         "file" : "lib/DBI/DBD/SqlEngine.pm",
+         "version" : "1.656"
+         },
+      "DBI::ProfileDumper::Apache" : {
+         "file" : "lib/DBI/ProfileDumper/Apache.pm",
+         "version" : "2.014121"
+         },
+      "DBD::Gofer::Transport::corostream" : {
+         "file" : "lib/DBD/Gofer/Transport/corostream.pm",
+         "version" : "2.165300"
+         },
+      "DBD::Gofer::Transport::null" : {
+         "file" : "lib/DBD/Gofer/Transport/null.pm",
+         "version" : "0.010088"
+         },
+      "DBI::Gofer::Transport::Base" : {
+         "file" : "lib/DBI/Gofer/Transport/Base.pm",
+         "version" : "0.012537"
+         },
+      "DBD::Gofer::Policy::rush" : {
+         "version" : "0.010088",
+         "file" : "lib/DBD/Gofer/Policy/rush.pm"
+         },
+      "DBI::Gofer::Transport::stream" : {
+         "version" : "0.012537",
+         "file" : "lib/DBI/Gofer/Transport/stream.pm"
+         },
+      "DBI::Gofer::Serializer::DataDumper" : {
+         "file" : "lib/DBI/Gofer/Serializer/DataDumper.pm",
+         "version" : "0.009950"
+         },
+      "DBD::DBM" : {
+         "file" : "lib/DBD/DBM.pm",
+         "version" : "1.656"
+         },
+      "DBD::Proxy" : {
+         "version" : "0.2004",
+         "file" : "lib/DBD/Proxy.pm"
+         },
+      "DBI::PurePerl" : {
+         "version" : "2.014286",
+         "file" : "lib/DBI/PurePerl.pm"
+         },
+      "DBI::SQL::Nano" : {
+         "file" : "lib/DBI/SQL/Nano.pm",
+         "version" : "1.015544"
+         },
+      "DBI::Const::GetInfoReturn" : {
+         "version" : "2.008697",
+         "file" : "lib/DBI/Const/GetInfoReturn.pm"
+         },
+      "DBI::Gofer::Response" : {
+         "file" : "lib/DBI/Gofer/Response.pm",
+         "version" : "0.011566"
+         },
+      "DBD::NullP" : {
+         "file" : "lib/DBD/NullP.pm",
+         "version" : "12.014715"
+         },
+      "DBI::ProxyServer" : {
+         "file" : "lib/DBI/ProxyServer.pm",
+         "version" : "0.3005"
+         },
+      "DBD::File" : {
+         "version" : "1.656",
+         "file" : "lib/DBD/File.pm"
+         },
+      "DBI::Util::CacheMemory" : {
+         "version" : "0.010315",
+         "file" : "lib/DBI/Util/CacheMemory.pm"
+         },
+      "DBD::Gofer::Transport::stream" : {
+         "file" : "lib/DBD/Gofer/Transport/stream.pm",
+         "version" : "0.014599"
+         },
+      "DBI::DBD" : {
+         "version" : "12.015129",
+         "file" : "lib/DBI/DBD.pm"
+         },
+      "DBI" : {
+         "file" : "DBI.pm",
+         "version" : "1.656"
+         },
+      "DBI::Gofer::Execute" : {
+         "version" : "0.014283",
+         "file" : "lib/DBI/Gofer/Execute.pm"
+         },
+      "DBI::Gofer::Transport::pipeone" : {
+         "version" : "0.012537",
+         "file" : "lib/DBI/Gofer/Transport/pipeone.pm"
+         },
+      "DBD::Gofer" : {
+         "file" : "lib/DBD/Gofer.pm",
+         "version" : "0.015327"
+         },
+      "DBI::ProfileData" : {
+         "version" : "2.010008",
+         "file" : "lib/DBI/ProfileData.pm"
+         },
+      "DBD::Mem" : {
+         "version" : "0.001",
+         "file" : "lib/DBD/Mem.pm"
+         },
+      "DBI::DBD::Metadata" : {
+         "file" : "lib/DBI/DBD/Metadata.pm",
+         "version" : "2.014214"
+         },
+      "Bundle::DBI" : {
+         "file" : "lib/Bundle/DBI.pm",
+         "version" : "12.008696"
+         },
+      "DBI::Const::GetInfoType" : {
+         "version" : "2.008697",
+         "file" : "lib/DBI/Const/GetInfoType.pm"
+         },
+      "DBI::Const::GetInfo::ANSI" : {
+         "version" : "2.008697",
+         "file" : "lib/DBI/Const/GetInfo/ANSI.pm"
+         },
+      "DBD::Sponge" : {
+         "file" : "lib/DBD/Sponge.pm",
+         "version" : "12.010003"
+         },
+      "DBI::Gofer::Request" : {
+         "file" : "lib/DBI/Gofer/Request.pm",
+         "version" : "0.012537"
+         },
+      "DBI::Const::GetInfo::ODBC" : {
+         "file" : "lib/DBI/Const/GetInfo/ODBC.pm",
+         "version" : "2.011374"
+         }
+      },
+   "generated_by" : "Author",
    "license" : [
       "perl_5"
       ],
-   "meta-spec" : {
-      "url" : "http://search.cpan.org/perldoc?CPAN::Meta::Spec";,
-      "version" : 2
-      },
-   "name" : "DBI",
-   "no_index" : {
-      "directory" : [
-         "t",
-         "inc"
-         ]
-      },
    "prereqs" : {
       "build" : {
          "requires" : {
-            "ExtUtils::MakeMaker" : "6.48",
-            "Test::Simple" : "0.96"
+            "perl" : "5.008001"
+            }
+         },
+      "runtime" : {
+         "conflicts" : {
+            "DBD::AnyData" : "<= 0.110",
+            "DBD::RAM" : "<= 0.072",
+            "DBD::Amazon" : "<= 0.10",
+            "SQL::Statement" : "<= 1.33",
+            "DBD::Google" : "<= 0.51",
+            "DBD::PO" : "<= 2.10",
+            "DBD::CSV" : "<= 0.36"
+            },
+         "recommends" : {
+            "Encode" : "3.24"
+            },
+         "suggests" : {
+            "Module::Load" : "0.36",
+            "RPC::PlClient" : "0.2020",
+            "SQL::Statement" : "1.414",
+            "Clone" : "0.50",
+            "Net::Daemon" : "0.52",
+            "Params::Util" : "1.102",
+            "MLDBM" : "0",
+            "DB_File" : "0",
+            "RPC::PlServer" : "0.2020"
+            },
+         "requires" : {
+            "XSLoader" : "0",
+            "perl" : "5.012000",
+            "Module::Load" : "0.22"
             }
          },
       "configure" : {
          "requires" : {
-            "ExtUtils::MakeMaker" : "0"
+            "ExtUtils::MakeMaker" : "6.48"
+            },
+         "recommends" : {
+            "ExtUtils::MakeMaker" : "7.78"
             }
          },
-      "runtime" : {
+      "test" : {
          "requires" : {
-            "Module::Load" : "0.22",
-            "perl" : "5.012000"
+            "Test::More" : "0.96"
+            },
+         "recommends" : {
+            "Test::More" : "1.302225"
             }
          }
       },
-   "release_status" : "stable",
-   "resources" : {
-      "bugtracker" : {
-         "web" : "https://github.com/perl5-dbi/dbi/issues";
-         },
-      "homepage" : "http://dbi.perl.org/";,
-      "license" : [
-         "http://dev.perl.org/licenses/";
-         ],
-      "repository" : {
-         "url" : "https://github.com/perl5-dbi/dbi";
-         },
-      "x_IRC" : "irc://irc.perl.org/#dbi",
-      "x_MailingList" : "mailto:[email protected]";
+   "name" : "DBI",
+   "abstract" : "Database independent interface for Perl",
+   "meta-spec" : {
+      "version" : 2,
+      "url" : "http://search.cpan.org/perldoc?CPAN::Meta::Spec";
       },
-   "version" : "1.652",
-   "x_serialization_backend" : "JSON::PP version 4.18",
-   "x_suggests" : {
-      "Clone" : 0.47,
-      "DB_File" : 0,
-      "MLDBM" : 0,
-      "Net::Daemon" : 0,
-      "RPC::PlClient" : 0.202,
-      "RPC::PlServer" : 0.202,
-      "SQL::Statement" : 1.414
-      }
+   "version" : "1.656",
+   "author" : [
+      "DBI team ([email protected])"
+      ]
    }
diff -Nru libdbi-perl-1.652/META.yml libdbi-perl-1.656/META.yml
--- libdbi-perl-1.652/META.yml  2026-08-15 13:29:17.000000000 +0200
+++ libdbi-perl-1.656/META.yml  2026-10-18 13:19:48.000000000 +0200
@@ -1,40 +1,170 @@
 ---
-abstract: 'Database independent interface for Perl'
+abstract: Database independent interface for Perl
 author:
-  - 'DBI team ([email protected])'
+  - DBI team ([email protected])
 build_requires:
-  ExtUtils::MakeMaker: '6.48'
-  Test::Simple: '0.96'
+  perl: '5.008001'
 configure_requires:
-  ExtUtils::MakeMaker: '0'
+  ExtUtils::MakeMaker: '6.48'
+conflicts:
+  DBD::Amazon: <= 0.10
+  DBD::AnyData: <= 0.110
+  DBD::CSV: <= 0.36
+  DBD::Google: <= 0.51
+  DBD::PO: <= 2.10
+  DBD::RAM: <= 0.072
+  SQL::Statement: <= 1.33
 dynamic_config: 1
-generated_by: 'ExtUtils::MakeMaker version 7.78, CPAN::Meta::Converter version 
2.150013'
+generated_by: Author, CPAN::Meta::Converter version 2.150015
 license: perl
 meta-spec:
   url: http://module-build.sourceforge.net/META-spec-v1.4.html
   version: '1.4'
 name: DBI
-no_index:
-  directory:
-    - t
-    - inc
+provides:
+  Bundle::DBI:
+    file: lib/Bundle/DBI.pm
+    version: '12.008696'
+  DBD::DBM:
+    file: lib/DBD/DBM.pm
+    version: '1.656'
+  DBD::ExampleP:
+    file: lib/DBD/ExampleP.pm
+    version: '12.014311'
+  DBD::File:
+    file: lib/DBD/File.pm
+    version: '1.656'
+  DBD::Gofer:
+    file: lib/DBD/Gofer.pm
+    version: '0.015327'
+  DBD::Gofer::Policy::Base:
+    file: lib/DBD/Gofer/Policy/Base.pm
+    version: '0.010088'
+  DBD::Gofer::Policy::classic:
+    file: lib/DBD/Gofer/Policy/classic.pm
+    version: '0.010088'
+  DBD::Gofer::Policy::pedantic:
+    file: lib/DBD/Gofer/Policy/pedantic.pm
+    version: '0.010088'
+  DBD::Gofer::Policy::rush:
+    file: lib/DBD/Gofer/Policy/rush.pm
+    version: '0.010088'
+  DBD::Gofer::Transport::Base:
+    file: lib/DBD/Gofer/Transport/Base.pm
+    version: '0.014121'
+  DBD::Gofer::Transport::corostream:
+    file: lib/DBD/Gofer/Transport/corostream.pm
+    version: '2.165300'
+  DBD::Gofer::Transport::null:
+    file: lib/DBD/Gofer/Transport/null.pm
+    version: '0.010088'
+  DBD::Gofer::Transport::pipeone:
+    file: lib/DBD/Gofer/Transport/pipeone.pm
+    version: '0.010088'
+  DBD::Gofer::Transport::stream:
+    file: lib/DBD/Gofer/Transport/stream.pm
+    version: '0.014599'
+  DBD::Mem:
+    file: lib/DBD/Mem.pm
+    version: '0.001'
+  DBD::NullP:
+    file: lib/DBD/NullP.pm
+    version: '12.014715'
+  DBD::Proxy:
+    file: lib/DBD/Proxy.pm
+    version: '0.2004'
+  DBD::Sponge:
+    file: lib/DBD/Sponge.pm
+    version: '12.010003'
+  DBI:
+    file: DBI.pm
+    version: '1.656'
+  DBI::Const::GetInfo::ANSI:
+    file: lib/DBI/Const/GetInfo/ANSI.pm
+    version: '2.008697'
+  DBI::Const::GetInfo::ODBC:
+    file: lib/DBI/Const/GetInfo/ODBC.pm
+    version: '2.011374'
+  DBI::Const::GetInfoReturn:
+    file: lib/DBI/Const/GetInfoReturn.pm
+    version: '2.008697'
+  DBI::Const::GetInfoType:
+    file: lib/DBI/Const/GetInfoType.pm
+    version: '2.008697'
+  DBI::DBD:
+    file: lib/DBI/DBD.pm
+    version: '12.015129'
+  DBI::DBD::Metadata:
+    file: lib/DBI/DBD/Metadata.pm
+    version: '2.014214'
+  DBI::DBD::SqlEngine:
+    file: lib/DBI/DBD/SqlEngine.pm
+    version: '1.656'
+  DBI::Gofer::Execute:
+    file: lib/DBI/Gofer/Execute.pm
+    version: '0.014283'
+  DBI::Gofer::Request:
+    file: lib/DBI/Gofer/Request.pm
+    version: '0.012537'
+  DBI::Gofer::Response:
+    file: lib/DBI/Gofer/Response.pm
+    version: '0.011566'
+  DBI::Gofer::Serializer::Base:
+    file: lib/DBI/Gofer/Serializer/Base.pm
+    version: '0.009950'
+  DBI::Gofer::Serializer::DataDumper:
+    file: lib/DBI/Gofer/Serializer/DataDumper.pm
+    version: '0.009950'
+  DBI::Gofer::Serializer::Storable:
+    file: lib/DBI/Gofer/Serializer/Storable.pm
+    version: '0.015586'
+  DBI::Gofer::Transport::Base:
+    file: lib/DBI/Gofer/Transport/Base.pm
+    version: '0.012537'
+  DBI::Gofer::Transport::pipeone:
+    file: lib/DBI/Gofer/Transport/pipeone.pm
+    version: '0.012537'
+  DBI::Gofer::Transport::stream:
+    file: lib/DBI/Gofer/Transport/stream.pm
+    version: '0.012537'
+  DBI::Profile:
+    file: lib/DBI/Profile.pm
+    version: '2.015065'
+  DBI::ProfileData:
+    file: lib/DBI/ProfileData.pm
+    version: '2.010008'
+  DBI::ProfileDumper:
+    file: lib/DBI/ProfileDumper.pm
+    version: '2.015325'
+  DBI::ProfileDumper::Apache:
+    file: lib/DBI/ProfileDumper/Apache.pm
+    version: '2.014121'
+  DBI::ProfileSubs:
+    file: lib/DBI/ProfileSubs.pm
+    version: '0.009396'
+  DBI::ProxyServer:
+    file: lib/DBI/ProxyServer.pm
+    version: '0.3005'
+  DBI::PurePerl:
+    file: lib/DBI/PurePerl.pm
+    version: '2.014286'
+  DBI::SQL::Nano:
+    file: lib/DBI/SQL/Nano.pm
+    version: '1.015544'
+  DBI::Util::CacheMemory:
+    file: lib/DBI/Util/CacheMemory.pm
+    version: '0.010315'
+recommends:
+  Encode: '3.24'
+  Test::More: '1.302225'
 requires:
   Module::Load: '0.22'
+  Test::More: '0.96'
+  XSLoader: '0'
   perl: '5.012000'
 resources:
   IRC: irc://irc.perl.org/#dbi
-  MailingList: mailto:[email protected]
   bugtracker: https://github.com/perl5-dbi/dbi/issues
-  homepage: http://dbi.perl.org/
   license: http://dev.perl.org/licenses/
   repository: https://github.com/perl5-dbi/dbi
-version: '1.652'
-x_serialization_backend: 'CPAN::Meta::YAML version 0.020'
-x_suggests:
-  Clone: 0.47
-  DB_File: 0
-  MLDBM: 0
-  Net::Daemon: 0
-  RPC::PlClient: 0.202
-  RPC::PlServer: 0.202
-  SQL::Statement: 1.414
+version: '1.656'
diff -Nru libdbi-perl-1.652/Makefile.PL libdbi-perl-1.656/Makefile.PL
--- libdbi-perl-1.652/Makefile.PL       2026-07-26 15:36:58.000000000 +0200
+++ libdbi-perl-1.656/Makefile.PL       2026-08-25 11:17:10.000000000 +0200
@@ -80,6 +80,7 @@
            "RPC::PlClient"   => 0.2020,
            "RPC::PlServer"   => 0.2020,
            "Net::Daemon"     => 0,
+           "Params::Util"    => '1.100',
            "SQL::Statement"  => 1.414,
            "Clone"           => 0.47,
            "MLDBM"           => 0,
@@ -377,7 +378,7 @@
 ptest:  all
        prove --blib --jobs 8 --shuffle
 
-.PHONY:        doc change changes spellcheck checkpod newdist
+.PHONY:        doc change changes spellcheck checkpod newdist checkmeta 
disttgz tgzdist
 changes:       $(changes_pm1)
 doc:
        perl dbixs_rev.pl
@@ -393,8 +394,14 @@
 # make dist does not remove existing .tar.gz causing questions
 newdist:
        -@rm -f $(DISTVNAME).tar.gz $(DISTVNAME).tgz
-tgzdist:       changes spellcheck newdist dist
-       -@mv -f $(DISTVNAME).tar.gz $(DISTVNAME).tgz
+checkmeta:     changes spellcheck ppport metafile
+       perl sandbox/genMETA.pl -c
+       perl sandbox/genMETA.pl
+# New target without the obsolete parts
+disttgz:       distdir
+       $(TAR) --format=ustar -czf $(DISTVNAME).tgz $(DISTVNAME)
+       $(RM_RF) $(DISTVNAME)
+tgzdist:       checkmeta newdist disttgz distcheck
        -@cpants_lint.pl $(DISTVNAME).tgz
        -@rm -f Debian_CPANTS.txt
 };
diff -Nru libdbi-perl-1.652/cpanfile libdbi-perl-1.656/cpanfile
--- libdbi-perl-1.652/cpanfile  2026-07-26 15:36:47.000000000 +0200
+++ libdbi-perl-1.656/cpanfile  2026-10-18 13:19:47.000000000 +0200
@@ -1,24 +1,34 @@
-requires   "XSLoader";
 requires   "Module::Load"             => "0.22";
+requires   "XSLoader";
 
 recommends "Encode"                   => "3.24";
 
 suggests   "Clone"                    => "0.50";
 suggests   "DB_File";
 suggests   "MLDBM";
+suggests   "Module::Load"             => "0.36";
 suggests   "Net::Daemon"              => "0.52";
+suggests   "Params::Util"             => "1.102";
 suggests   "RPC::PlClient"            => "0.2020";
 suggests   "RPC::PlServer"            => "0.2020";
 suggests   "SQL::Statement"           => "1.414";
 
+conflicts  "DBD::Amazon"              => "<= 0.10";
+conflicts  "DBD::AnyData"             => "<= 0.110";
+conflicts  "DBD::CSV"                 => "<= 0.36";
+conflicts  "DBD::Google"              => "<= 0.51";
+conflicts  "DBD::PO"                  => "<= 2.10";
+conflicts  "DBD::RAM"                 => "<= 0.072";
+conflicts  "SQL::Statement"           => "<= 1.33";
+
 on "configure" => sub {
-    requires   "ExtUtils::MakeMaker"  => "6.48";
+    requires   "ExtUtils::MakeMaker"      => "6.48";
 
-    recommends "ExtUtils::MakeMaker"  => "7.78";
+    recommends "ExtUtils::MakeMaker"      => "7.78";
     };
 
 on "test" => sub {
-    requires   "Test::More"           => "0.96";
+    requires   "Test::More"               => "0.96";
 
-    recommends "Test::More"           => "1.302222";
+    recommends "Test::More"               => "1.302225";
     };
diff -Nru libdbi-perl-1.652/dbixs_rev.h libdbi-perl-1.656/dbixs_rev.h
--- libdbi-perl-1.652/dbixs_rev.h       2026-08-15 13:28:22.000000000 +0200
+++ libdbi-perl-1.656/dbixs_rev.h       2026-10-18 13:19:42.000000000 +0200
@@ -1,4 +1,4 @@
-/* Sat Aug 15 13:28:22 2026 */
+/* Sun Oct 18 13:19:42 2026 */
 #define DBIXS_RELEASE  1
-#define DBIXS_VERSION  652
-#define DBIXS_REVISION 1810
+#define DBIXS_VERSION  656
+#define DBIXS_REVISION 1871
diff -Nru libdbi-perl-1.652/debian/changelog libdbi-perl-1.656/debian/changelog
--- libdbi-perl-1.652/debian/changelog  2026-08-22 22:43:46.000000000 +0200
+++ libdbi-perl-1.656/debian/changelog  2026-11-09 20:37:27.000000000 +0100
@@ -1,3 +1,46 @@
+libdbi-perl (1.656-1~deb13u1) trixie; urgency=medium
+
+  * Team upload.
+  * Rebuild for trixie
+
+ -- Salvatore Bonaccorso <[email protected]>  Mon, 09 Nov 2026 20:37:27 +0100
+
+libdbi-perl (1.656-1) unstable; urgency=medium
+
+  * Import upstream version 1.656.
+    + Prevent dbi_profile crash (CVE-2026-108518) (Henrik Teichmann)
+    + Fix lock file not removed when DBD::DBM check for bad serializer class
+      fails. (CVE-2026-111879)
+    Closes: #1151666
+
+ -- gregor herrmann <[email protected]>  Fri, 23 Oct 2026 01:54:00 +0200
+
+libdbi-perl (1.655-1) unstable; urgency=medium
+
+  * Import upstream version 1.655.
+
+ -- gregor herrmann <[email protected]>  Mon, 05 Oct 2026 21:25:57 +0200
+
+libdbi-perl (1.654-1) unstable; urgency=medium
+
+  * Import upstream version 1.654.
+    - Fix DBI::sql_type_cast on IV/NV (CVE-2026-88815)
+    - Fix FetchHashKeyName   on IV/NV (CVE-2026-88816)
+    Closes: #1149042
+
+ -- gregor herrmann <[email protected]>  Sun, 27 Sep 2026 17:43:29 +0200
+
+libdbi-perl (1.653-1) unstable; urgency=medium
+
+  * Import upstream version 1.653.
+    - Fix arbitrary module and file loading via dbm_type/dbm_mldbm
+      (CVE-2026-78030)
+    - Tighten symlink outside of f_dir (CVE-2026-15392) check
+  * Drop 0001-Fix-test-for-32bit-perl-report-in-PR-189.patch which was
+    taken from upstream Git.
+
+ -- gregor herrmann <[email protected]>  Sat, 12 Sep 2026 02:24:04 +0200
+
 libdbi-perl (1.652-2~deb13u1) trixie-security; urgency=high
 
   * Team upload.
diff -Nru 
libdbi-perl-1.652/debian/patches/0001-Fix-test-for-32bit-perl-report-in-PR-189.patch
 
libdbi-perl-1.656/debian/patches/0001-Fix-test-for-32bit-perl-report-in-PR-189.patch
--- 
libdbi-perl-1.652/debian/patches/0001-Fix-test-for-32bit-perl-report-in-PR-189.patch
        2026-08-22 22:43:46.000000000 +0200
+++ 
libdbi-perl-1.656/debian/patches/0001-Fix-test-for-32bit-perl-report-in-PR-189.patch
        1970-01-01 01:00:00.000000000 +0100
@@ -1,37 +0,0 @@
-From acc903db3086a737936643a5dbbc0e22f9d5c421 Mon Sep 17 00:00:00 2001
-From: "H.Merijn Brand - Tux" <[email protected]>
-Date: Mon, 17 Aug 2026 09:49:56 +0200
-Subject: [PATCH] Fix test for 32bit-perl (report in PR#189)
-
-Origin: 
https://github.com/perl5-dbi/dbi/commit/acc903db3086a737936643a5dbbc0e22f9d5c421
-Bug-Debian: https://bugs.debian.org/1144851
-Bug: https://github.com/perl5-dbi/dbi/pull/189
-
----
- ChangeLog          |  3 +++
- DBI.pm             |  4 ++--
- dbixs_rev.h        |  4 ++--
- doc/DBI.3          |  4 ++--
- doc/DBI.html       |  2 +-
- doc/DBI.man        |  4 ++--
- doc/DBI.md         |  2 +-
- lib/DBI/Changes.pm | 10 ++++++++++
- t/60preparse.t     |  2 +-
- 9 files changed, 24 insertions(+), 11 deletions(-)
-
-diff --git a/t/60preparse.t b/t/60preparse.t
-index 92bdc89..eff39be 100755
---- a/t/60preparse.t
-+++ b/t/60preparse.t
-@@ -148,7 +148,7 @@ ok( $DBI::err );
- is( $DBI::errstr, "preparse found :p100000 which is outside the allowed 
range.");
- is( pp($dbh, 'a = :2147483648', DBIpp_ph_qm, DBIpp_ph_cs|DBIpp_ph_cn), undef, 
'exceeds limit');
- ok( $DBI::err );
--is( $DBI::errstr, "preparse found :p-2147483648 which is outside the allowed 
range.");
-+like( $DBI::errstr, qr{^preparse found :p(?:-2147483648|2147483647) which is 
outside the allowed range.$});
- is( pp($dbh, 'a = :12345678987654321', DBIpp_ph_qm, DBIpp_ph_cs|DBIpp_ph_cn), 
undef, 'exceeds limit');
- ok( $DBI::err );
- like( $DBI::errstr, qr{^preparse found :p\d+ which is outside the allowed 
range.$});
--- 
-2.55.0
-
diff -Nru libdbi-perl-1.652/debian/patches/series 
libdbi-perl-1.656/debian/patches/series
--- libdbi-perl-1.652/debian/patches/series     2026-08-22 22:43:46.000000000 
+0200
+++ libdbi-perl-1.656/debian/patches/series     2026-11-09 20:37:27.000000000 
+0100
@@ -1,4 +1,3 @@
 t__06attrs.t__localefix.patch
 t__40profile.t__NTP.patch
 t__80proxy.t___syslogd.patch
-0001-Fix-test-for-32bit-perl-report-in-PR-189.patch
diff -Nru libdbi-perl-1.652/lib/DBD/DBM.pm libdbi-perl-1.656/lib/DBD/DBM.pm
--- libdbi-perl-1.652/lib/DBD/DBM.pm    2026-08-15 10:50:43.000000000 +0200
+++ libdbi-perl-1.656/lib/DBD/DBM.pm    2026-10-17 14:40:29.000000000 +0200
@@ -25,7 +25,7 @@
 #################
 use base qw( DBD::File );
 our ($drh,$methods_already_installed);
-our $VERSION     = '0.08';
+our $VERSION     = '1.656';
 our $ATTRIBUTION = 'DBD::DBM by Jens Rehsack';
 
 # no need to have driver() unless you need private methods
@@ -59,6 +59,21 @@
     undef $drh;
 }
 
+if (eval { require Params::Util; }) {
+    Params::Util->import ("_CLASS");
+} else {
+    # SPDX-SnippetBegin
+    # SPDX-SnippetCopyrightText: 2005-2012 Adam Kennedy. 2020 Jens Rehsack.
+    # SPDX-License-Identifier: Artistic-1.0-Perl
+    # SPDX-PackageName: pkg:cpan/[email protected]
+    # SPDX-Description: taken from Params::Util::PP 1.102
+    *_CLASS = sub {
+        my $arg = $_[0];
+        return (defined $arg and not ref $arg and $arg =~ 
m/^[^\W\d]\w*(?:::\w+)*\z/s) ? $arg : undef;
+    };
+    # SPDX-SnippetEnd
+}
+
 #####################
 package DBD::DBM::dr;
 #####################
@@ -77,7 +92,8 @@
 our $imp_data_size = 0;
 our @ISA           = qw(DBD::File::db);
 
-use Carp qw/carp/;
+use Carp;
+use Module::Load ();
 
 sub validate_STORE_attr
 {
@@ -190,10 +206,9 @@
         };
         eval {
             my $ser_class = "MLDBM::Serializer::" . $meta->{dbm_mldbm};
-            my $ser_mod   = $ser_class;
-            $ser_mod =~ s|::|/|g;
-            $ser_mod .= ".pm";
-            require $ser_mod;
+            DBD::DBM::_CLASS($ser_class)
+                or croak "Invalid dbm_mldbm '$ser_class': expected a module 
name";
+            Module::Load::load $ser_class;
             $dver = $ser_class->VERSION();
             $dtype .= ' + ' . $ser_class;    # (*)
             $dver and $dtype .= " ($dver)";  # (*)
@@ -254,6 +269,7 @@
 ########################
 use Carp;
 use Fcntl;
+use Module::Load ();
 
 our @ISA = qw(DBD::File::Table);
 
@@ -318,12 +334,14 @@
     unless ( defined( $meta->{dbm_tietype} ) )
     {
         my $tie_type = $meta->{dbm_type};
-        $INC{"$tie_type.pm"} or require "$tie_type.pm";
+        DBD::DBM::_CLASS($tie_type)
+            or croak "Invalid dbm_type '$tie_type': expected a module name";
+        Module::Load::load $tie_type;
         $tie_type eq 'BerkeleyDB' and $tie_type = 'BerkeleyDB::Hash';
 
         if ( $meta->{dbm_mldbm} )
         {
-            $INC{"MLDBM.pm"} or require "MLDBM.pm";
+            Module::Load::load "MLDBM";
             $meta->{dbm_usedb} = $tie_type;
             $tie_type = 'MLDBM';
         }
@@ -354,6 +372,17 @@
 sub open_data
 {
     my ( $className, $meta, $attrs, $flags ) = @_;
+
+    # Validate dbm_mldbm BEFORE SUPER::open_data creates and flock()s the
+    # lock file.  A croak after that point leaves $meta->{lockfh} holding an
+    # exclusive lock for as long as the table meta data lives, and the next
+    # open of the same table in this process blocks on it forever.
+    if ( $meta->{dbm_mldbm} and not $flags->{dropMode} )
+    {
+        DBD::DBM::_CLASS( $meta->{dbm_mldbm} )
+            or croak "Invalid dbm_mldbm '$meta->{dbm_mldbm}': expected a 
module name";
+    }
+
     $className->SUPER::open_data( $meta, $attrs, $flags );
 
     unless ( $flags->{dropMode} )
@@ -399,8 +428,15 @@
         $meta->{hash} = {};
         my $tie_class = $meta->{dbm_tietype};
         eval { tie %{ $meta->{hash} }, $tie_class, @tie_args };
-        $@ and croak "Cannot tie(\%h $tie_class @tie_args): $@";
-        -f $meta->{f_fqfn} or croak( "No such file: '" . $meta->{f_fqfn} . "'" 
);
+        if ( $@ or not -f $meta->{f_fqfn} )
+        {
+            # Release the lock SUPER::open_data took, or it outlives this
+            # failure (see above).
+            my $err = $@ ? "Cannot tie(\%h $tie_class @tie_args): $@"
+                         : "No such file: '" . $meta->{f_fqfn} . "'";
+            $className->_release_lock($meta);
+            croak $err;
+        }
     }
 
     unless ( $flags->{createMode} )
@@ -576,7 +612,10 @@
     return unless ( defined $key );
 
     if ( my $mode = $meta->{dbm_updatable_key} ) {
-        my $method = $mode == 1 ? \&carp : \&croak;
+        my $method = $mode == 1 ? \&carp : sub {
+            warn $_[0] if  $] < 5.013002;
+            croak $_[0];
+        };
         my $exists;
         eval { $exists = $key ne $newkey && exists( $meta->{hash}->{$newkey} 
); };
         $exists and $method->("Row with PK '$newkey' already exists");
@@ -1446,7 +1485,7 @@
 
 If you need enhancements quickly, you can get commercial support as
 described at L<http://dbi.perl.org/support/> or you can contact Jens Rehsack
-at [email protected] for commercial support in Germany.
+at [email protected] for commercial support in Germany.
 
 Please don't bother Jochen Wiedmann or Jeff Zucker for support - they
 handed over further maintenance to H.Merijn Brand and Jens Rehsack.
diff -Nru libdbi-perl-1.652/lib/DBD/File/Developers.pod 
libdbi-perl-1.656/lib/DBD/File/Developers.pod
--- libdbi-perl-1.652/lib/DBD/File/Developers.pod       2026-07-13 
10:44:58.000000000 +0200
+++ libdbi-perl-1.656/lib/DBD/File/Developers.pod       2026-09-02 
15:06:59.000000000 +0200
@@ -636,7 +636,7 @@
 
 The module DBD::File is currently maintained by
 
-H.Merijn Brand < hmbrand at cpan.org > and
+H.Merijn Brand < perl5 at tux.freedom.nl > and
 Jens Rehsack  < rehsack at googlemail.com >
 
 The original author is Jochen Wiedmann.
diff -Nru libdbi-perl-1.652/lib/DBD/File/HowTo.pod 
libdbi-perl-1.656/lib/DBD/File/HowTo.pod
--- libdbi-perl-1.652/lib/DBD/File/HowTo.pod    2026-05-29 11:45:56.000000000 
+0200
+++ libdbi-perl-1.656/lib/DBD/File/HowTo.pod    2026-09-02 15:07:15.000000000 
+0200
@@ -160,7 +160,7 @@
 
 The module DBD::File is currently maintained by
 
-H.Merijn Brand < hmbrand at cpan.org > and
+H.Merijn Brand < perl5 at tux.freedom.nl > and
 Jens Rehsack  < rehsack at googlemail.com >
 
 =head1 COPYRIGHT AND LICENSE
diff -Nru libdbi-perl-1.652/lib/DBD/File.pm libdbi-perl-1.656/lib/DBD/File.pm
--- libdbi-perl-1.652/lib/DBD/File.pm   2026-07-14 13:20:05.000000000 +0200
+++ libdbi-perl-1.656/lib/DBD/File.pm   2026-10-17 14:42:24.000000000 +0200
@@ -35,7 +35,7 @@
 use base qw( DBI::DBD::SqlEngine );
 use Carp;
 
-our $VERSION = "0.45";
+our $VERSION = "1.656";
 
 our $drh = undef;              # holds driver handle(s) once initialized
 
@@ -483,7 +483,7 @@
 my $locking = eval {
     my $fh;
     my $nulldevice = File::Spec->devnull ();
-    open $fh, ">", $nulldevice or croak "Can't open $nulldevice: $!";
+    open  $fh, ">", $nulldevice or croak "Can't open $nulldevice: $!";
     flock $fh, 0;
     close $fh;
     1;
@@ -697,7 +697,7 @@
 
     if (-l $fqfn) {
        my $real = Cwd::abs_path ($fqfn);
-       unless (List::Util::any { $real =~ m{^\Q$_\E} } @bases) {
+       unless (List::Util::any { $real =~ m{^\Q$_\E(?:$|/)} } @bases) {
             croak "Data file $fqfn is a outside of f_dir f_and f_dir_search\n";
            }
        }
@@ -916,18 +916,24 @@
 sub drop ($) {
     my ($self, $data) = @_;
     my $meta = $self->{meta};
-    # We have to close the file before unlinking it: Some OS'es will
-    # refuse the unlink otherwise.
-    $meta->{fh} and $meta->{fh}->close ();
-    $meta->{lockfh} and $meta->{lockfh}->close ();
-    undef $meta->{fh};
-    undef $meta->{lockfh};
+    $self->_release_lock($meta);
     $meta->{f_fqfn} and unlink $meta->{f_fqfn}; # XXX ==> sql_data_source
     $meta->{f_fqln} and unlink $meta->{f_fqln}; # XXX ==> sql_data_source
     delete $data->{Database}{sql_meta}{$self->{table}};
     return 1;
     } # drop
 
+sub _release_lock {
+    my ($self, $meta) = @_;
+    # We have to close the file before unlinking it: Some OS'es will
+    # refuse the unlink otherwise.
+    $meta->{fh}     and $meta->{fh}->close ();
+    $meta->{lockfh} and eval { flock $meta->{lockfh}, 0 };
+    $meta->{lockfh} and $meta->{lockfh}->close ();
+    undef $meta->{fh};
+    undef $meta->{lockfh};
+    } # _release_lock
+
 sub seek ($$$$) {
     my ($self, $data, $pos, $whence) = @_;
     my $meta = $self->{meta};
@@ -953,10 +959,7 @@
 sub DESTROY {
     my $self = shift;
     my $meta = $self->{meta};
-    $meta->{fh} and $meta->{fh}->close ();
-    $meta->{lockfh} and $meta->{lockfh}->close ();
-    undef $meta->{fh};
-    undef $meta->{lockfh};
+    $self->_release_lock($meta);
 
     $self->SUPER::DESTROY();
     } # DESTROY
@@ -1432,7 +1435,7 @@
 
 This module is currently maintained by
 
-H.Merijn Brand < hmbrand at cpan.org > and
+H.Merijn Brand < perl5 at tux.freedom.nl > and
 Jens Rehsack < rehsack at googlemail.com >
 
 The original author is Jochen Wiedmann.
diff -Nru libdbi-perl-1.652/lib/DBD/Gofer/Transport/corostream.pm 
libdbi-perl-1.656/lib/DBD/Gofer/Transport/corostream.pm
--- libdbi-perl-1.652/lib/DBD/Gofer/Transport/corostream.pm     2013-04-05 
08:08:36.000000000 +0200
+++ libdbi-perl-1.656/lib/DBD/Gofer/Transport/corostream.pm     2026-09-09 
17:16:08.000000000 +0200
@@ -3,6 +3,8 @@
 use strict;
 use warnings;
 
+our $VERSION = "2.165300";
+
 use Carp;
 
 use Coro::Select; #  a slow but coro-aware replacement for CORE::select 
(global effect!)
diff -Nru libdbi-perl-1.652/lib/DBD/Mem.pm libdbi-perl-1.656/lib/DBD/Mem.pm
--- libdbi-perl-1.652/lib/DBD/Mem.pm    2026-07-14 13:17:10.000000000 +0200
+++ libdbi-perl-1.656/lib/DBD/Mem.pm    2026-09-02 15:13:11.000000000 +0200
@@ -350,11 +350,11 @@
 
 If you need enhancements quickly, you can get commercial support as
 described at L<http://dbi.perl.org/support/> or you can contact Jens Rehsack
-at [email protected] for commercial support.
+at [email protected] for commercial support.
 
 =head1 AUTHOR AND COPYRIGHT
 
-This module is written by Jens Rehsack < rehsack AT cpan.org >.
+This module is written by Jens Rehsack < rehsack AT googlemail.com >.
 
  Copyright (c) 2016- by Jens Rehsack, all rights reserved.
 
diff -Nru libdbi-perl-1.652/lib/DBI/Changes.pm 
libdbi-perl-1.656/lib/DBI/Changes.pm
--- libdbi-perl-1.652/lib/DBI/Changes.pm        2026-08-15 10:50:43.000000000 
+0200
+++ libdbi-perl-1.656/lib/DBI/Changes.pm        2026-10-17 14:47:28.000000000 
+0200
@@ -12,6 +12,103 @@
 
 =encoding UTF-8
 
+=head2 Changes in DBI 1.656 - 17 Oct 2026
+
+=over 2
+
+=item *
+
+Re-add conflicts to cpanfile. (WIP)
+
+=item *
+
+Remove lock file on end of scope
+
+=item *
+
+Prevent dbi_profile crash (CVE-2026-108518) (Henrik Teichmann)
+
+=item *
+
+Memory corruption via selectrow_array + SQLite UDF (issue#98)
+
+=item *
+
+Fix errstr when dbm_updatable_key attribute for DBD::DBM is set to 2 (croak) 
on Perl versions < v5.13.2.
+
+=item *
+
+Fix emit warnings when dbm_updatable_key attribute for DBD::DBM is set to 1 
(carp)
+
+=item *
+
+Fix lock file not removed when DBD::DBM check for bad serializer class fails. 
(CVE-2026-111879)
+
+=item *
+
+*** WARNING: Next release will require perl-5.14 ***
+- Main reason: Exception handling
+
+=back
+
+=head2 Changes in DBI 1.655 - 30 Sep 2026
+
+=over 2
+
+=item *
+
+Fix for C89 (Paul Howarth, PR#197)
+
+=item *
+
+Ignore invalid handles consistently (detected by Raj)
+
+=back
+
+=head2 Changes in DBI 1.654 - 25 Sep 2026
+
+=over 2
+
+=item *
+
+Fix DBI::sql_type_cast on IV/NV (CVE-2026-88815) (reported by Raj)
+
+=item *
+
+Fix FetchHashKeyName   on IV/NV (CVE-2026-88816) (reported by Raj)
+
+=item *
+
+Fix provided in META
+
+=back
+
+=head2 Changes in DBI 1.653 - 09 Sep 2026
+
+=over 2
+
+=item *
+
+Fix test for 32bit-perl (report in PR#189)
+
+=item *
+
+Fix arbitrary module and file loading via dbm_type/dbm_mldbm (CVE-2026-78030)
+
+=item *
+
+More META checking/updates
+
+=item *
+
+Tighten symlink outside of f_dir (CVE-2026-15392) check (reported by Raj)
+
+=item *
+
+CPAN.org does not forward email anymore
+
+=back
+
 =head2 Changes in DBI 1.652 - 15 Aug 2026
 
 =over 2
diff -Nru libdbi-perl-1.652/lib/DBI/DBD/SqlEngine/Developers.pod 
libdbi-perl-1.656/lib/DBI/DBD/SqlEngine/Developers.pod
--- libdbi-perl-1.652/lib/DBI/DBD/SqlEngine/Developers.pod      2026-05-29 
11:48:43.000000000 +0200
+++ libdbi-perl-1.656/lib/DBI/DBD/SqlEngine/Developers.pod      2026-09-02 
15:08:15.000000000 +0200
@@ -827,7 +827,7 @@
 
 The module DBI::DBD::SqlEngine is currently maintained by
 
-H.Merijn Brand < hmbrand at cpan.org > and
+H.Merijn Brand < perl5 at tux.freedom.nl > and
 Jens Rehsack  < rehsack at googlemail.com >
 
 =head1 COPYRIGHT AND LICENSE
diff -Nru libdbi-perl-1.652/lib/DBI/DBD/SqlEngine/HowTo.pod 
libdbi-perl-1.656/lib/DBI/DBD/SqlEngine/HowTo.pod
--- libdbi-perl-1.652/lib/DBI/DBD/SqlEngine/HowTo.pod   2026-07-13 
10:45:37.000000000 +0200
+++ libdbi-perl-1.656/lib/DBI/DBD/SqlEngine/HowTo.pod   2026-09-02 
15:08:19.000000000 +0200
@@ -298,7 +298,7 @@
 
 The module DBI::DBD::SqlEngine is currently maintained by
 
-H.Merijn Brand < hmbrand at cpan.org > and
+H.Merijn Brand < perl5 at tux.freedom.nl > and
 Jens Rehsack  < rehsack at googlemail.com >
 
 =head1 COPYRIGHT AND LICENSE
diff -Nru libdbi-perl-1.652/lib/DBI/DBD/SqlEngine.pm 
libdbi-perl-1.656/lib/DBI/DBD/SqlEngine.pm
--- libdbi-perl-1.652/lib/DBI/DBD/SqlEngine.pm  2026-08-15 10:50:43.000000000 
+0200
+++ libdbi-perl-1.656/lib/DBI/DBD/SqlEngine.pm  2026-10-16 16:10:08.000000000 
+0200
@@ -34,7 +34,7 @@
 use Carp;
 our %methods_installed;
 
-our $VERSION = "0.06";
+our $VERSION = "1.656";
 
 our $drh = undef;    # holds driver handle(s) once initialized
 
@@ -1272,6 +1272,8 @@
         return;
     }
 
+    warn $_ for @err;
+
     if ( $stmt->{NUM_OF_FIELDS} )
     {    # is a SELECT statement
         $sth->STORE( Active => 1 );
@@ -2192,7 +2194,7 @@
 
 This module is currently maintained by
 
-H.Merijn Brand < hmbrand at cpan.org > and
+H.Merijn Brand < perl5 at tux.freedom.nl > and
 Jens Rehsack  < rehsack at googlemail.com >
 
 The original authors are Jochen Wiedmann and Jeff Zucker.
diff -Nru libdbi-perl-1.652/lib/DBI/PurePerl.pm 
libdbi-perl-1.656/lib/DBI/PurePerl.pm
--- libdbi-perl-1.652/lib/DBI/PurePerl.pm       2026-07-14 13:27:03.000000000 
+0200
+++ libdbi-perl-1.656/lib/DBI/PurePerl.pm       2026-10-15 15:45:56.000000000 
+0200
@@ -778,7 +778,7 @@
 
 sub _err_hash {
     return 1 unless defined $_[0]->{err};
-    return "$_[0]->{err} $_[0]->{errstr}"
+    return join " " => $_[0]->{err}, $_[0]->{errstr} // "?";
 }
 
 
diff -Nru libdbi-perl-1.652/lib/DBI/SQL/Nano.pm 
libdbi-perl-1.656/lib/DBI/SQL/Nano.pm
--- libdbi-perl-1.652/lib/DBI/SQL/Nano.pm       2026-07-14 13:25:45.000000000 
+0200
+++ libdbi-perl-1.656/lib/DBI/SQL/Nano.pm       2026-10-09 13:51:08.000000000 
+0200
@@ -2,7 +2,7 @@
 #
 #  DBI::SQL::Nano - a very tiny SQL engine
 #
-#  Copyright (c) 2010 by Jens Rehsack < rehsack AT cpan.org >
+#  Copyright (c) 2010 by Jens Rehsack < rehsack AT googlemail.com >
 #  Copyright (c) 2004 by Jeff Zucker < jzucker AT cpan.org >
 #
 #  All rights reserved.
@@ -1001,7 +1001,7 @@
 
 This module is originally written by Jeff Zucker < jzucker AT cpan.org >
 
-This module is currently maintained by Jens Rehsack < jrehsack AT cpan.org >
+This module is currently maintained by Jens Rehsack < jrehsack AT 
googlemail.com >
 
 Copyright (C) 2010 by Jens Rehsack, all rights reserved.
 Copyright (C) 2004 by Jeff Zucker, all rights reserved.
diff -Nru libdbi-perl-1.652/t/02dbidrv.t libdbi-perl-1.656/t/02dbidrv.t
--- libdbi-perl-1.652/t/02dbidrv.t      2025-01-17 10:49:51.000000000 +0100
+++ libdbi-perl-1.656/t/02dbidrv.t      2026-08-28 14:47:56.000000000 +0200
@@ -42,6 +42,7 @@
     use warnings;
 
     my $drh = undef;
+    DESTROY { $drh = undef; }
 
     sub driver {
         return $drh if $drh;
@@ -75,7 +76,7 @@
 
     Test::More::cmp_ok($DBD::Test::dr::imp_data_size, '==', 0, '... check 
DBD::Test::dr::imp_data_size to avoid typo');
 
-    sub DESTROY { undef }
+    sub DESTROY { undef; }
 
     sub data_sources {
         my ($h) = @_;
@@ -140,7 +141,7 @@
     }
 
     sub disconnect {
-    shift->STORE(Active => 0);
+       shift->STORE(Active => 0);
     }
 }
 
@@ -258,7 +259,11 @@
     ok($name, '... used FETCH returned from can to fetch the Name attribute');
     is($name, "Test", '... the Name attribute is equal to Test');
 
-    ok(!$drh->can('disconnect_all'), '... ');
+    ok(!$drh->can('disconnect_all'), '... no disconnect_all');
 }
 
+# Suppress "(in cleanup) dbih_getcom handle DBI::dr=HASH(0x39db90e8) is not a 
DBI handle (has no magic) during global destruction."
+$SIG{__WARN__} = sub { $@ = "" };
+$SIG{__DIE__}  = sub { $@ = "" };
+
 1;
diff -Nru libdbi-perl-1.652/t/06attrs.t libdbi-perl-1.656/t/06attrs.t
--- libdbi-perl-1.652/t/06attrs.t       2026-07-13 10:46:31.000000000 +0200
+++ libdbi-perl-1.656/t/06attrs.t       2026-09-10 11:22:26.000000000 +0200
@@ -328,6 +328,17 @@
 
 }
 
+{   # CVE-2026-88816
+    my $h = DBI->connect("dbi:ExampleP:", "", "", { RaiseError => 0, 
PrintError => 0 });
+    $dbh->{FetchHashKeyName} = 42;
+    my $s = $dbh->prepare("select mode,size,name from .");
+    $s->execute;
+    my @err;
+    local $SIG{__DIE__} = sub { push @err => @_ };
+    eval { $s->fetchrow_hashref; };
+    like($err[0], qr{Can't use (?:attribute '42'|an undefined)}, "Invalid 
HashKeyName");
+}
+
 done_testing();
 
 1;
diff -Nru libdbi-perl-1.652/t/40profile.t libdbi-perl-1.656/t/40profile.t
--- libdbi-perl-1.652/t/40profile.t     2026-07-22 14:22:24.000000000 +0200
+++ libdbi-perl-1.656/t/40profile.t     2026-10-09 15:56:56.000000000 +0200
@@ -489,6 +489,20 @@
 
 };
 
+# The DESTROY of a database handle must be profiled when the Path has {attr} 
elements.
+# While the outer handle is being destroyed DBIc_MY_H() holds the raw inner 
HV; dbi_profile() used to
+# call SvRV() on the (raw HV) result of dbih_inner() and so used the hash's 
bucket array as an HV.
+{
+    my $prof = DBI::Profile->new(Path => [ '{Username}', '!MethodName' ]);
+    my $dbh = DBI->connect("dbi:ExampleP:", 'usrnam', '', { RaiseError => 1, 
Profile => $prof });
+    $dbh->ping;
+    undef $dbh; # DESTROY of the database handle
+    my $node = $prof->{Data}{usrnam};
+    ok $node && $node->{DESTROY}, 'DESTROY of a database handle is profiled 
with a {Username} path element';
+    is $node && $node->{DESTROY} ? $node->{DESTROY}[0] : undef, 1, 'exactly 
one DESTROY call profiled';
+    $prof->{Data} = undef; # no report at exit
+}
+
 done_testing;
 
 exit 0;
diff -Nru libdbi-perl-1.652/t/44prof_caller.t 
libdbi-perl-1.656/t/44prof_caller.t
--- libdbi-perl-1.652/t/44prof_caller.t 1970-01-01 01:00:00.000000000 +0100
+++ libdbi-perl-1.656/t/44prof_caller.t 2026-08-15 10:29:58.000000000 +0200
@@ -0,0 +1,58 @@
+#!perl -w
+$|=1;
+
+#
+# test that DBI::Profile !Caller2 still reports the caller's caller when
+# $^P is set but &DB::sub is not defined, as happens under tools such as
+# Devel::Cover (GH #177)
+#
+
+use strict;
+
+use DBI;
+use File::Basename qw(basename);
+
+use Test::More;
+
+BEGIN {
+    plan skip_all => "profiling not supported for DBI::PurePerl"
+        if $DBI::PurePerl;
+
+    plan tests => 2;
+}
+
+# log file to store profile results
+my $LOG_FILE = "test_output_profile$$.log";
+my $orig_dbi_debug = $DBI::dbi_debug;
+DBI->trace($DBI::dbi_debug, $LOG_FILE);
+END {
+    return if $orig_dbi_debug;
+    1 while unlink $LOG_FILE;
+}
+
+# simulate a tool like Devel::Cover: the debugger API is initialised
+# because $^P is set, but &DB::sub is not defined
+$^P |= 0x100;
+
+our $dbh = DBI->connect("dbi:ExampleP:", '', '', { RaiseError=>1 });
+$dbh->{Profile} = "!MethodName:!Caller2";
+
+# the "via ..." part of !Caller2 needs the profiled call to be made
+# inside a sub, eval or do FILE, so call $dbh->do from a helper file
+my $helper_file = "test_output_dbsub$$.pl";
+END { 1 while defined $helper_file && unlink $helper_file }
+open my $fh, ">", $helper_file or die "Can't create $helper_file: $!";
+print $fh qq{\$main::dbh->do("set foo=1");\n1;\n};
+close $fh or die "Can't close $helper_file: $!";
+
+do "./$helper_file" or die $@ || $!; my $line = __LINE__;
+
+my @keys = keys %{ $dbh->{Profile}{Data}{do} };
+is scalar @keys, 1, 'one profile leaf for do';
+my $this_file = basename(__FILE__);
+is $keys[0], "$helper_file line 1 via $this_file line $line",
+    '!Caller2 includes the "via" caller when $^P is set';
+
+$dbh->{Profile} = 0;
+
+1;
diff -Nru libdbi-perl-1.652/t/50dbm_simple.t libdbi-perl-1.656/t/50dbm_simple.t
--- libdbi-perl-1.652/t/50dbm_simple.t  2026-08-15 10:50:43.000000000 +0200
+++ libdbi-perl-1.656/t/50dbm_simple.t  2026-10-16 16:10:08.000000000 +0200
@@ -317,14 +317,19 @@
 
                 $sth->{PrintError} = 0;
 
+                my @warn;
+
+                local $SIG{__WARN__} = sub { push @warn, @_ };
                 my $n = $sth->execute();
 
                 if ( $mode == 2 ) {
                     ok( !$n, 'execute failed' );
-                    like $sth->errstr, qr/^Row with PK '1' already exists/, 
'execpted error';
+                    like $sth->errstr, qr/^Row with PK '1' already exists/, 
'expected error';
                 }
                 else {
-                    # TODO: trap warnings to test when $mode == 1
+                    if ( $mode == 1) {
+                        like $warn[0], qr/^Row with PK '1' already exists/, 
'expected warning';
+                    }
                     is( $n, 1, 'execute' ) or diag( $sth->errstr || 'unknown 
error' );
                 }
 
diff -Nru libdbi-perl-1.652/t/53dbm_module_name.t 
libdbi-perl-1.656/t/53dbm_module_name.t
--- libdbi-perl-1.652/t/53dbm_module_name.t     1970-01-01 01:00:00.000000000 
+0100
+++ libdbi-perl-1.656/t/53dbm_module_name.t     2026-10-17 14:40:29.000000000 
+0200
@@ -0,0 +1,136 @@
+#!perl -w
+# dbm_type and dbm_mldbm name a Perl module, never a file path.
+#
+# Both attributes reach require(). require() treats a path-shaped string as a
+# literal file and never consults @INC, so without a grammar check a caller
+# who influences either attribute can make the process load -- and therefore
+# execute -- a .pm from anywhere on the filesystem.
+#
+# The two "rejected" cases below fail on an unvalidated DBD::DBM: the planted
+# module gets loaded and sets the flag. The two "still works" cases pin the
+# behaviour the check must not break.
+
+use strict;
+use warnings;
+
+require DBD::DBM;
+
+use DBI;
+use File::Path qw(mkpath);
+use File::Spec;
+use File::Temp qw(tempdir);
+use Test::More;
+use Fcntl qw(:flock);
+
+my $dir = tempdir( CLEANUP => 1 );
+my $dbdir = File::Spec->catdir( $dir, 'db' );
+mkpath($dbdir);
+
+# A module planted outside @INC. Loading it is observable and can happen for
+# exactly one reason: something required this path.
+my $plant = File::Spec->catfile( $dir, 'DbmPlant.pm' );
+open( my $fh, '>', $plant ) or plan skip_all => "cannot write $plant: $!";
+print {$fh} "\$::DBM_PLANT_LOADED = 1;\n1;\n";
+close($fh);
+
+( my $plant_noext = $plant ) =~ s/\.pm\z//;
+
+my $have_mldbm = eval { require 'MLDBM.pm'; 1 };
+
+# --- dbm_type must not name a path --------------------------------------
+{
+    local $::DBM_PLANT_LOADED = 0;
+    my $dbh = DBI->connect( "dbi:DBM:f_dir=$dbdir", undef, undef,
+                            { RaiseError => 0, PrintError => 0,
+                              dbm_type => $plant_noext } );
+    #$dbh->{dbm_type} = $plant_noext;
+    eval { $dbh->do("CREATE TABLE t_reject (id INT, v CHAR(8))"); 1 };
+    ok( !$::DBM_PLANT_LOADED,
+        "a path-shaped dbm_type does not load the file it names" );
+    eval { $dbh->do( "DROP TABLE t_reject" ); 1 };
+    $dbh->disconnect;
+}
+
+# The same path with its ".pm" suffix left on. This is the case a loader
+# swap alone does not cover: Module::Load treats anything outside [\w:'] as a
+# filename and requires it verbatim, so "/path/Evil" fails only because no
+# such file exists -- "/path/Evil.pm" loads.
+{
+    local $::DBM_PLANT_LOADED = 0;
+    my $dbh = DBI->connect( "dbi:DBM:f_dir=$dbdir", undef, undef,
+                            { RaiseError => 0, PrintError => 0,
+                              dbm_type => $plant_noext } );
+    #$dbh->{dbm_type} = $plant;
+    eval { $dbh->do("CREATE TABLE t_reject_pm (id INT, v CHAR(8))"); 1 };
+    ok( !$::DBM_PLANT_LOADED,
+        "a dbm_type naming a .pm file directly does not load it" );
+    eval { $dbh->do( "DROP TABLE t_reject_pm" ); 1 };
+    $dbh->disconnect;
+}
+
+# --- dbm_type still accepts a real DBM implementation -------------------
+{
+    my $dbh = DBI->connect( "dbi:DBM:f_dir=$dbdir;dbm_type=SDBM_File", undef, 
undef,
+                            { RaiseError => 1, PrintError => 0 } );
+    ok( $dbh->do("CREATE TABLE t_ok (id INT, v CHAR(8))"), "CREATE" );
+    ok( $dbh->do("INSERT INTO t_ok VALUES (1, 'hello')"), "INSERT" );
+    my ($v) = $dbh->selectrow_array("SELECT v FROM t_ok WHERE id = 1");
+    is( $v, 'hello', "dbm_type=SDBM_File still round-trips a row" );
+    ok( $dbh->do("DROP TABLE t_ok"), "DROP" );
+    $dbh->disconnect;
+}
+
+# --- dbm_mldbm must not escape the MLDBM::Serializer:: prefix ------------
+SKIP: {
+    skip "MLDBM not installed", 1 unless $have_mldbm;
+
+    # "MLDBM::Serializer::" only looks like containment. s|::|/|g rewrites
+    # "::" and leaves a literal "/" alone, and MLDBM ships MLDBM/Serializer/
+    # into @INC, so every component of a traversal out of it exists.
+    my ($inc) = grep { -d File::Spec->catdir( $_, 'MLDBM', 'Serializer' ) } 
@INC;
+    skip "no \@INC entry holds MLDBM/Serializer/", 1 unless defined $inc;
+
+    my @up = File::Spec->splitdir( File::Spec->canonpath($inc) );
+    shift(@up) while ( @up && $up[0] eq '' );
+    my $escape = ( '../' x ( scalar(@up) + 2 ) ) . substr( $plant_noext, 1 );
+
+    local $::DBM_PLANT_LOADED = 0;
+    my $dbh = DBI->connect( "dbi:DBM:f_dir=$dbdir;dbm_type=SDBM_File", undef, 
undef,
+                            { RaiseError => 0, PrintError => 0,
+                              dbm_mldbm   => $escape } );
+    eval {
+        $dbh->do("CREATE TABLE t_ser (id INT, v CHAR(8))");
+        $dbh->func( 't_ser', 'dbm_versions' );
+        1;
+    };
+    ok( !$::DBM_PLANT_LOADED,
+        "a dbm_mldbm that traverses out of MLDBM::Serializer:: does not load 
the file it names" );
+
+    # The rejection must happen before the table's lock file is created and
+    # flock()ed.  Otherwise the lock outlives the failed CREATE and every
+    # later open of the table in this process blocks on it: the DROP below
+    # hung under DBI_AUTOPROXY=dbi:Gofer:transport=null, where the dbh that
+    # serves the DROP is not the one holding the stale lock.
+    my $lck  = File::Spec->catfile( $dbdir, "t_ser.lck" );
+    my $free = 1;
+    if ( -f $lck and open( my $lfh, "<", $lck ) )
+    {
+        $free = flock( $lfh, LOCK_EX | LOCK_NB ) ? 1 : 0;
+        close($lfh);
+    }
+    ok( $free, "a rejected dbm_mldbm does not leave the table's lock file 
locked" );
+    eval { $dbh->do( "DROP TABLE t_ser" ); 1 };
+    $dbh->disconnect;
+}
+
+# --- dbm_mldbm still accepts a real serializer name ---------------------
+{
+    my $dbh = DBI->connect( "dbi:DBM:f_dir=$dbdir;dbm_type=SDBM_File", undef, 
undef,
+                            { RaiseError => 0, PrintError => 0 } );
+    my $versions = eval { $dbh->func( 'dbm_versions' ) };
+    ok( defined $versions && length $versions,
+        "dbm_versions() still reports for an unmodified handle" );
+    $dbh->disconnect;
+}
+
+done_testing;
diff -Nru libdbi-perl-1.652/t/60preparse.t libdbi-perl-1.656/t/60preparse.t
--- libdbi-perl-1.652/t/60preparse.t    2026-08-11 14:17:09.000000000 +0200
+++ libdbi-perl-1.656/t/60preparse.t    2026-08-17 09:01:55.000000000 +0200
@@ -148,7 +148,7 @@
 is( $DBI::errstr, "preparse found :p100000 which is outside the allowed 
range.");
 is( pp($dbh, 'a = :2147483648', DBIpp_ph_qm, DBIpp_ph_cs|DBIpp_ph_cn), undef, 
'exceeds limit');
 ok( $DBI::err );
-is( $DBI::errstr, "preparse found :p-2147483648 which is outside the allowed 
range.");
+like( $DBI::errstr, qr{^preparse found :p(?:-2147483648|2147483647) which is 
outside the allowed range.$});
 is( pp($dbh, 'a = :12345678987654321', DBIpp_ph_qm, DBIpp_ph_cs|DBIpp_ph_cn), 
undef, 'exceeds limit');
 ok( $DBI::err );
 like( $DBI::errstr, qr{^preparse found :p\d+ which is outside the allowed 
range.$});
diff -Nru libdbi-perl-1.652/t/70callbacks.t libdbi-perl-1.656/t/70callbacks.t
--- libdbi-perl-1.652/t/70callbacks.t   2025-01-17 10:49:51.000000000 +0100
+++ libdbi-perl-1.656/t/70callbacks.t   2026-10-15 16:17:33.000000000 +0200
@@ -254,8 +254,7 @@
 
 # with plain assignment to $_
 $_ = LeakDetect->new;
-if ($] >= 5.008002) {
-    is $LeakDetect::count, 1, "[plain] live object count is 1 after new()";
+{   is $LeakDetect::count, 1, "[plain] live object count is 1 after new()";
     my $obj = $_;
     $dbh->ping;
     is $_, $obj, '[plain] $_ still holds an object reference after the 
callback';
@@ -265,8 +264,7 @@
 is $LeakDetect::count, 0, "[plain] live object count is 0 after all object 
references are gone";
 
 # with localized $_
-if ($] >= 5.008002) {
-    local $_ = LeakDetect->new;
+{   local $_ = LeakDetect->new;
     is $LeakDetect::count, 1, "[local] live object count is 1 after new()";
     my $obj = $_;
     $dbh->ping;
@@ -279,7 +277,6 @@
 for (LeakDetect->new) {
     is $LeakDetect::count, 1, "[foreach] live object count is 1 after new()";
     my $obj = $_;
-    $] >= 5.008002 or next;
     $dbh->ping;
     is $_, $obj, '[foreach] $_ still holds an object reference after the 
callback';
 }
diff -Nru libdbi-perl-1.652/t/90sql_type_cast.t 
libdbi-perl-1.656/t/90sql_type_cast.t
--- libdbi-perl-1.652/t/90sql_type_cast.t       2026-07-22 14:24:41.000000000 
+0200
+++ libdbi-perl-1.656/t/90sql_type_cast.t       2026-09-10 10:54:46.000000000 
+0200
@@ -49,6 +49,22 @@
      "aa",         SQL_NUMERIC, 0,               NO_CAST_NO_STRICT, q{["aa"]}],
     ['non numeric cast to numeric (strict)',
      "aa",         SQL_NUMERIC, DBIstcf_STRICT,  NO_CAST_STRICT,    q{["aa"]}],
+    # CVE-2026-88815
+    ['invalid sql type',
+     99,           123456789,   0,               INVALID_TYPE,      q{[99]}],
+    ['small int cast to int',
+     99,           SQL_INTEGER, 0,               CAST_OK,           q{[99]}],
+    ['2 byte max signed int cast to int',
+     32767,        SQL_INTEGER, 0,               CAST_OK,           
q{[32767]}],
+    ['2 byte max unsigned int cast to int',
+     65535,        SQL_INTEGER, 0,               CAST_OK,           
q{[65535]}],
+    ['4 byte max signed int cast to int',
+     2147483647,   SQL_INTEGER, 0,               CAST_OK,           
q{[2147483647]}],
+    ['4 byte max unsigned int cast to int',
+     4294967295,   SQL_INTEGER, 0,               CAST_OK,           
q{[4294967295]}],
+    ['small int cast to int (discard)',
+     99,           SQL_INTEGER, DBIstcf_DISCARD_STRING,
+                                                 CAST_OK,           q{[99]}],
    );
 
 unless ($pp) {

Reply via email to