Version in base suite: 1.652-2~deb13u1 Base version: libdbi-perl_1.652-2~deb13u1 Target version: libdbi-perl_1.656-1~deb13u1 Base file: /srv/ftp-master.debian.org/ftp/pool/main/libd/libdbi-perl/libdbi-perl_1.652-2~deb13u1.dsc Target file: /srv/ftp-master.debian.org/policy/pool/main/libd/libdbi-perl/libdbi-perl_1.656-1~deb13u1.dsc ChangeLog | 27 DBI.pm | 21 DBI.xs | 33 - Driver.xst | 22 MANIFEST | 2 META.json | 290 ++++++++-- META.yml | 174 +++++- Makefile.PL | 13 cpanfile | 20 dbixs_rev.h | 6 debian/changelog | 43 + debian/patches/0001-Fix-test-for-32bit-perl-report-in-PR-189.patch | 37 - debian/patches/series | 1 lib/DBD/DBM.pm | 63 +- lib/DBD/File.pm | 31 - lib/DBD/File/Developers.pod | 2 lib/DBD/File/HowTo.pod | 2 lib/DBD/Gofer/Transport/corostream.pm | 2 lib/DBD/Mem.pm | 4 lib/DBI/Changes.pm | 97 +++ lib/DBI/DBD/SqlEngine.pm | 6 lib/DBI/DBD/SqlEngine/Developers.pod | 2 lib/DBI/DBD/SqlEngine/HowTo.pod | 2 lib/DBI/PurePerl.pm | 2 lib/DBI/SQL/Nano.pm | 4 t/02dbidrv.t | 11 t/06attrs.t | 11 t/40profile.t | 14 t/44prof_caller.t | 58 ++ t/50dbm_simple.t | 9 t/53dbm_module_name.t | 136 ++++ t/60preparse.t | 2 t/70callbacks.t | 7 t/90sql_type_cast.t | 16 34 files changed, 976 insertions(+), 194 deletions(-) dpkg-source: warning: cannot verify inline signature for /srv/release.debian.org/tmp/tmp082g6kh3/libdbi-perl_1.652-2~deb13u1.dsc: no acceptable signature found dpkg-source: warning: cannot verify inline signature for /srv/release.debian.org/tmp/tmp082g6kh3/libdbi-perl_1.656-1~deb13u1.dsc: no acceptable signature found diff -Nru libdbi-perl-1.652/ChangeLog libdbi-perl-1.656/ChangeLog --- libdbi-perl-1.652/ChangeLog 2026-08-15 08:50:43.000000000 +0000 +++ libdbi-perl-1.656/ChangeLog 2026-10-17 12:46:46.000000000 +0000 @@ -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 15:14:05.000000000 +0000 +++ libdbi-perl-1.656/DBI.pm 2026-10-09 13:57:31.000000000 +0000 @@ -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 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 =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 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 =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 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 =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 08:29:58.000000000 +0000 +++ libdbi-perl-1.656/DBI.xs 2026-10-12 08:08:01.000000000 +0000 @@ -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 12:03:05.000000000 +0000 +++ libdbi-perl-1.656/Driver.xst 2026-10-15 13:30:17.000000000 +0000 @@ -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 11:29:17.000000000 +0000 +++ libdbi-perl-1.656/MANIFEST 2026-10-18 11:19:48.000000000 +0000 @@ -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 11:29:17.000000000 +0000 +++ libdbi-perl-1.656/META.json 2026-10-18 11:19:48.000000000 +0000 @@ -1,67 +1,263 @@ { - "abstract" : "Database independent interface for Perl", - "author" : [ - "DBI team (dbi-users@perl.org)" - ], + "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:dbi-dev@perl.org" + "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 (dbi-users@perl.org)" + ] } diff -Nru libdbi-perl-1.652/META.yml libdbi-perl-1.656/META.yml --- libdbi-perl-1.652/META.yml 2026-08-15 11:29:17.000000000 +0000 +++ libdbi-perl-1.656/META.yml 2026-10-18 11:19:48.000000000 +0000 @@ -1,40 +1,170 @@ --- -abstract: 'Database independent interface for Perl' +abstract: Database independent interface for Perl author: - - 'DBI team (dbi-users@perl.org)' + - DBI team (dbi-users@perl.org) 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:dbi-dev@perl.org 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 13:36:58.000000000 +0000 +++ libdbi-perl-1.656/Makefile.PL 2026-08-25 09:17:10.000000000 +0000 @@ -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 13:36:47.000000000 +0000 +++ libdbi-perl-1.656/cpanfile 2026-10-18 11:19:47.000000000 +0000 @@ -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 11:28:22.000000000 +0000 +++ libdbi-perl-1.656/dbixs_rev.h 2026-10-18 11:19:42.000000000 +0000 @@ -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 20:43:46.000000000 +0000 +++ libdbi-perl-1.656/debian/changelog 2026-11-09 19:37:27.000000000 +0000 @@ -1,3 +1,46 @@ +libdbi-perl (1.656-1~deb13u1) trixie; urgency=medium + + * Team upload. + * Rebuild for trixie + + -- Salvatore Bonaccorso 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 Fri, 23 Oct 2026 01:54:00 +0200 + +libdbi-perl (1.655-1) unstable; urgency=medium + + * Import upstream version 1.655. + + -- gregor herrmann 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 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 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 20:43:46.000000000 +0000 +++ libdbi-perl-1.656/debian/patches/0001-Fix-test-for-32bit-perl-report-in-PR-189.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,37 +0,0 @@ -From acc903db3086a737936643a5dbbc0e22f9d5c421 Mon Sep 17 00:00:00 2001 -From: "H.Merijn Brand - Tux" -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 20:43:46.000000000 +0000 +++ libdbi-perl-1.656/debian/patches/series 2026-11-09 19:37:27.000000000 +0000 @@ -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 08:50:43.000000000 +0000 +++ libdbi-perl-1.656/lib/DBD/DBM.pm 2026-10-17 12:40:29.000000000 +0000 @@ -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/Params-Util@1.102 + # 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 or you can contact Jens Rehsack -at rehsack@cpan.org for commercial support in Germany. +at rehsack@googlemail.com 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 08:44:58.000000000 +0000 +++ libdbi-perl-1.656/lib/DBD/File/Developers.pod 2026-09-02 13:06:59.000000000 +0000 @@ -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 09:45:56.000000000 +0000 +++ libdbi-perl-1.656/lib/DBD/File/HowTo.pod 2026-09-02 13:07:15.000000000 +0000 @@ -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 11:20:05.000000000 +0000 +++ libdbi-perl-1.656/lib/DBD/File.pm 2026-10-17 12:42:24.000000000 +0000 @@ -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 06:08:36.000000000 +0000 +++ libdbi-perl-1.656/lib/DBD/Gofer/Transport/corostream.pm 2026-09-09 15:16:08.000000000 +0000 @@ -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 11:17:10.000000000 +0000 +++ libdbi-perl-1.656/lib/DBD/Mem.pm 2026-09-02 13:13:11.000000000 +0000 @@ -350,11 +350,11 @@ If you need enhancements quickly, you can get commercial support as described at L or you can contact Jens Rehsack -at rehsack@cpan.org for commercial support. +at rehsack@googlemail.com 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 08:50:43.000000000 +0000 +++ libdbi-perl-1.656/lib/DBI/Changes.pm 2026-10-17 12:47:28.000000000 +0000 @@ -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 09:48:43.000000000 +0000 +++ libdbi-perl-1.656/lib/DBI/DBD/SqlEngine/Developers.pod 2026-09-02 13:08:15.000000000 +0000 @@ -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 08:45:37.000000000 +0000 +++ libdbi-perl-1.656/lib/DBI/DBD/SqlEngine/HowTo.pod 2026-09-02 13:08:19.000000000 +0000 @@ -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 08:50:43.000000000 +0000 +++ libdbi-perl-1.656/lib/DBI/DBD/SqlEngine.pm 2026-10-16 14:10:08.000000000 +0000 @@ -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 11:27:03.000000000 +0000 +++ libdbi-perl-1.656/lib/DBI/PurePerl.pm 2026-10-15 13:45:56.000000000 +0000 @@ -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 11:25:45.000000000 +0000 +++ libdbi-perl-1.656/lib/DBI/SQL/Nano.pm 2026-10-09 11:51:08.000000000 +0000 @@ -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 09:49:51.000000000 +0000 +++ libdbi-perl-1.656/t/02dbidrv.t 2026-08-28 12:47:56.000000000 +0000 @@ -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 08:46:31.000000000 +0000 +++ libdbi-perl-1.656/t/06attrs.t 2026-09-10 09:22:26.000000000 +0000 @@ -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 12:22:24.000000000 +0000 +++ libdbi-perl-1.656/t/40profile.t 2026-10-09 13:56:56.000000000 +0000 @@ -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 00:00:00.000000000 +0000 +++ libdbi-perl-1.656/t/44prof_caller.t 2026-08-15 08:29:58.000000000 +0000 @@ -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 08:50:43.000000000 +0000 +++ libdbi-perl-1.656/t/50dbm_simple.t 2026-10-16 14:10:08.000000000 +0000 @@ -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 00:00:00.000000000 +0000 +++ libdbi-perl-1.656/t/53dbm_module_name.t 2026-10-17 12:40:29.000000000 +0000 @@ -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 12:17:09.000000000 +0000 +++ libdbi-perl-1.656/t/60preparse.t 2026-08-17 07:01:55.000000000 +0000 @@ -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 09:49:51.000000000 +0000 +++ libdbi-perl-1.656/t/70callbacks.t 2026-10-15 14:17:33.000000000 +0000 @@ -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 12:24:41.000000000 +0000 +++ libdbi-perl-1.656/t/90sql_type_cast.t 2026-09-10 08:54:46.000000000 +0000 @@ -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) {