diff --git a/SOURCES/DBD-mysql-4.023-Tests-for-little-endian-platform.patch b/SOURCES/DBD-mysql-4.023-Tests-for-little-endian-platform.patch new file mode 100644 index 0000000..39521e0 --- /dev/null +++ b/SOURCES/DBD-mysql-4.023-Tests-for-little-endian-platform.patch @@ -0,0 +1,182 @@ +From b6e3965aa874cd3391eb01b106af3aa2716f1b1b Mon Sep 17 00:00:00 2001 +From: Vladimir Marek +Date: Wed, 2 Mar 2016 11:14:06 +0100 +Subject: [PATCH] Tests for little-endian platform +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Ported to 4.023: + +commit 55363b41ea077778b723ee5600316141e2785541 +Author: Vladimir Marek +Date: Wed Mar 2 11:14:06 2016 +0100 + + Tests for little-endian platform + + https://rt.cpan.org/Public/Bug/Display.html?id=57266 + +Signed-off-by: Petr Písař +--- + t/41int_min_max.t | 149 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 149 insertions(+) + create mode 100644 t/41int_min_max.t + +diff --git a/t/41int_min_max.t b/t/41int_min_max.t +new file mode 100644 +index 0000000..fbb622c +--- /dev/null ++++ b/t/41int_min_max.t +@@ -0,0 +1,149 @@ ++use strict; ++use warnings; ++use bigint; ++ ++use DBI; ++use DBI::Const::GetInfoType; ++use Test::More; ++use lib 't', '.'; ++use Data::Dumper; ++require 'lib.pl'; ++use vars qw($test_dsn $test_user $test_password); ++ ++my $dbh; ++eval {$dbh= DBI->connect($test_dsn, $test_user, $test_password, ++ { RaiseError => 1, PrintError => 1, AutoCommit => 1 });}; ++if ($@) { ++ plan skip_all => "no database connection"; ++} ++ ++if ($dbh->get_info($GetInfoType{SQL_DBMS_VER}) lt "4.1") { ++ plan skip_all => "ERROR: $DBI::errstr. Can't continue test"; ++ plan skip_all => ++ "SKIP TEST: You must have MySQL version 4.1 and greater for this test to run"; ++} ++# nostrict tests + strict tests + init/tear down commands ++plan tests => 19*8 + 17*8 + 4; ++ ++my $table = 'dbd_mysql_t41minmax'; # name of the table we will be using ++my $mode; # 'strict' or 'nostrict' corresponds to strict SQL mode ++ ++sub test_int_type ($$$$) { ++ my ($perl_type, $mysql_type, $min, $max) = @_; ++ ++ # Disable the warning text clobbering our output ++ local $SIG{__WARN__} = sub { 1; }; ++ ++ # Create the table ++ ok($dbh->do(qq{DROP TABLE IF EXISTS $table}), "removing $table"); ++ ok($dbh->do(qq{ ++ CREATE TABLE `$table` ( ++ `id` int not null auto_increment, ++ `val` $mysql_type, ++ primary key (id) ++ ) ++ }), "creating minmax table for type $mysql_type"); ++ ++ my ($store, $retrieve); # statements ++ my $read_value; # retrieved value ++ ok($store = $dbh->prepare("INSERT INTO $table (val) VALUES (?)")); ++ ok($retrieve = $dbh->prepare("SELECT val from $table where id=(SELECT MAX(id) FROM $table)")); ++ ++ ######################################## ++ # Insert allowed min value ++ ######################################## ++ ok($store->bind_param( 1, $min->bstr(), $perl_type ), "binding minimal $mysql_type, mode=$mode"); ++ ok($store->execute(), "inserting min data for type $mysql_type, mode=$mode"); ++ ++ ######################################## ++ # Read it back and compare ++ ######################################## ++ ok{$retrieve->execute()}; ++ ($read_value) = $retrieve->fetchrow_array(); ++ cmp_ok($read_value, 'eq', $min, "retrieved minimal value for $mysql_type, mode=$mode"); ++ ++ ######################################## ++ # Insert allowed max value ++ ######################################## ++ ok($store->bind_param( 1, $max->bstr(), $perl_type ), "binding maximal $mysql_type, mode=$mode"); ++ ok($store->execute(), "inserting max data for type $mysql_type, mode=$mode"); ++ ++ ######################################## ++ # Read it back and compare ++ ######################################## ++ ok{$retrieve->execute()}; ++ ($read_value) = $retrieve->fetchrow_array(); ++ cmp_ok($read_value, 'eq', $max, "retrieved maximal value for $mysql_type, mode=$mode"); ++ ++ ######################################## ++ # Try to insert under the limit value ++ ######################################## ++ ok($store->bind_param( 1, ($min-1)->bstr(), $perl_type ), "binding less than minimal $mysql_type, mode=$mode"); ++ if ($mode eq 'strict') { ++ $@ = ''; ++ eval{$store->execute()}; ++ like($@, qr/Out of range value for column 'val'/, "Error, you stored ".($min-1)." into $mysql_type, mode=$mode\n". ++ Data::Dumper->Dump([$dbh->selectall_arrayref("SELECT * FROM $table")]). ++ Data::Dumper->Dump([$dbh->selectall_arrayref("describe $table")]) ++ ); ++ } else { ++ ok{$store->execute()}; ++ ######################################## ++ # Check that it was rounded correctly ++ ######################################## ++ ok{$retrieve->execute()}; ++ ($read_value) = $retrieve->fetchrow_array(); ++ cmp_ok($read_value, 'eq', $min, "retrieved minimal value for type $mysql_type, mode=$mode"); ++ }; ++ ++ ######################################## ++ # Try to insert over the limit value ++ ######################################## ++ ok($store->bind_param( 1, ($max+1)->bstr(), $perl_type ), "binding more than maximal $mysql_type, mode=$mode"); ++ if ($mode eq 'strict') { ++ $@ = ''; ++ eval{$store->execute()}; ++ like($@, qr/Out of range value for column 'val'/, "Error, you stored ".($max+1)." into $mysql_type, mode=$mode\n". ++ Data::Dumper->Dump([$dbh->selectall_arrayref("SELECT * FROM $table")]). ++ Data::Dumper->Dump([$dbh->selectall_arrayref("describe $table")]) ++ ); ++ } else { ++ ok{$store->execute()}; ++ ######################################## ++ # Check that it was rounded correctly ++ ######################################## ++ ok{$retrieve->execute()}; ++ ($read_value) = $retrieve->fetchrow_array(); ++ cmp_ok($read_value, 'eq', $max, "retrieved maximal value for type $mysql_type, mode=$mode"); ++ }; ++} ++ ++# Set strict SQL mode ++ok($dbh->do("SET SQL_MODE='STRICT_ALL_TABLES'"),"Enter strict SQL mode."); ++$mode = 'strict'; ++ ++test_int_type(DBI::SQL_TINYINT, 'tinyint signed', -2**7, 2**7-1); ++test_int_type(DBI::SQL_TINYINT, 'tinyint unsigned', 0, 2**8-1); ++test_int_type(DBI::SQL_SMALLINT, 'smallint signed', -2**15, 2**15-1); ++test_int_type(DBI::SQL_SMALLINT, 'smallint unsigned', 0, 2**16-1); ++test_int_type(DBI::SQL_INTEGER, 'int signed', -2**31, 2**31-1); ++test_int_type(DBI::SQL_INTEGER, 'int unsigned', 0, 2**32-1); ++test_int_type(DBI::SQL_BIGINT, 'bigint signed', -2**63, 2**63-1); ++test_int_type(DBI::SQL_BIGINT, 'bigint unsigned', 0, 2**64-1); ++ ++# Do not use strict SQL mode ++ok($dbh->do("SET SQL_MODE=''"),"Leave strict SQL mode."); ++$mode = 'nostrict'; ++ ++test_int_type(DBI::SQL_TINYINT, 'tinyint signed', -2**7, 2**7-1); ++test_int_type(DBI::SQL_TINYINT, 'tinyint unsigned', 0, 2**8-1); ++test_int_type(DBI::SQL_SMALLINT, 'smallint signed', -2**15, 2**15-1); ++test_int_type(DBI::SQL_SMALLINT, 'smallint unsigned', 0, 2**16-1); ++test_int_type(DBI::SQL_INTEGER, 'int signed', -2**31, 2**31-1); ++test_int_type(DBI::SQL_INTEGER, 'int unsigned', 0, 2**32-1); ++test_int_type(DBI::SQL_BIGINT, 'bigint signed', -2**63, 2**63-1); ++test_int_type(DBI::SQL_BIGINT, 'bigint unsigned', 0, 2**64-1); ++ ++ok ($dbh->do("DROP TABLE $table")); ++ ++ok $dbh->disconnect; +-- +2.7.4 + diff --git a/SOURCES/DBD-mysql-4.033_02-Fix-transferring-MYSQL_TYPE_LONG-values-on-64-bit-bi.patch b/SOURCES/DBD-mysql-4.033_02-Fix-transferring-MYSQL_TYPE_LONG-values-on-64-bit-bi.patch new file mode 100644 index 0000000..93786f0 --- /dev/null +++ b/SOURCES/DBD-mysql-4.033_02-Fix-transferring-MYSQL_TYPE_LONG-values-on-64-bit-bi.patch @@ -0,0 +1,120 @@ +From 604af7c0622261342929dd5087838af7d067976f Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Petr=20P=C3=ADsa=C5=99?= +Date: Fri, 26 Feb 2016 13:32:31 +0100 +Subject: [PATCH] Fix transferring MYSQL_TYPE_LONG values on 64-bit big endian + systems +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +t/40server_prepare.t test failed on s390x platform. Server-prepared +values of types int, smallint, and tinyint are passed to application +as 32-bit integer. The same buffer was interpreted as long integer +by DBD::MySQL. This caused missaligned read/write and bogus +interpretation of the values. + +https://rt.cpan.org/Public/Bug/Display.html?id=57266 +https://bugzilla.redhat.com/show_bug.cgi?id=1311646 +http://dev.mysql.com/doc/refman/5.7/en/mysql-stmt-fetch.html +Signed-off-by: Petr Písař +Signed-off-by: Michiel Beijen +--- + dbdimp.c | 20 +++++++++++++------- + dbdimp.h | 5 +++-- + 2 files changed, 16 insertions(+), 9 deletions(-) + +diff --git a/dbdimp.c b/dbdimp.c +index acdfee8..091df7d 100644 +--- a/dbdimp.c ++++ b/dbdimp.c +@@ -18,6 +18,7 @@ + #endif + + #include "dbdimp.h" ++#include /* for PRId32 */ + + #if defined(WIN32) && defined(WORD) + #undef WORD +@@ -3752,8 +3753,8 @@ int dbd_describe(SV* sth, imp_sth_t* imp_sth) + + if (DBIc_TRACE_LEVEL(imp_xxh) >= 2) + { +- PerlIO_printf(DBIc_LOGPIO(imp_xxh),"\t\ti %d col_type %d fbh->length %d\n", +- i, col_type, (int) fbh->length); ++ PerlIO_printf(DBIc_LOGPIO(imp_xxh),"\t\ti %d col_type %d fbh->length %lu\n", ++ i, col_type, fbh->length); + PerlIO_printf(DBIc_LOGPIO(imp_xxh), + "\t\tfields[i].length %lu fields[i].max_length %lu fields[i].type %d fields[i].charsetnr %d\n", + (long unsigned int) fields[i].length, (long unsigned int) fields[i].max_length, fields[i].type, +@@ -4014,8 +4015,8 @@ process: + + case MYSQL_TYPE_LONG: + if (DBIc_TRACE_LEVEL(imp_xxh) >= 2) +- PerlIO_printf(DBIc_LOGPIO(imp_xxh), "\t\tst_fetch int data %d, unsigned? %d\n", +- (int) fbh->ldata, buffer->is_unsigned); ++ PerlIO_printf(DBIc_LOGPIO(imp_xxh), "\t\tst_fetch int data %"PRId32", unsigned? %d\n", ++ fbh->ldata, buffer->is_unsigned); + if (buffer->is_unsigned) + sv_setuv(sv, fbh->ldata); + else +@@ -4786,6 +4787,7 @@ int dbd_bind_ph(SV *sth, imp_sth_t *imp_sth, SV *param, SV *value, + int buffer_is_null= 0; + int buffer_length= slen; + unsigned int buffer_type= 0; ++ IV tmp; + #endif + + D_imp_dbh_from_sth; +@@ -4873,12 +4875,16 @@ int dbd_bind_ph(SV *sth, imp_sth_t *imp_sth, SV *param, SV *value, + if (!SvIOK(imp_sth->params[idx].value) && DBIc_TRACE_LEVEL(imp_xxh) >= 2) + PerlIO_printf(DBIc_LOGPIO(imp_xxh), "\t\tTRY TO BIND AN INT NUMBER\n"); + buffer_length = sizeof imp_sth->fbind[idx].numeric_val.lval; +- imp_sth->fbind[idx].numeric_val.lval= SvIV(imp_sth->params[idx].value); ++ ++ tmp = SvIV(imp_sth->params[idx].value); ++ if (tmp > INT32_MAX) ++ croak("Could not bind %ld: Integer too large for MYSQL_TYPE_LONG", tmp); ++ imp_sth->fbind[idx].numeric_val.lval= tmp; + buffer=(void*)&(imp_sth->fbind[idx].numeric_val.lval); + if (DBIc_TRACE_LEVEL(imp_xxh) >= 2) + PerlIO_printf(DBIc_LOGPIO(imp_xxh), +- " SCALAR type %d ->%ld<- IS A INT NUMBER\n", +- (int) sql_type, (long) (*buffer)); ++ " SCALAR type %d ->%"PRId32"<- IS A INT NUMBER\n", ++ (int) sql_type, *(int32_t *)buffer); + break; + + case MYSQL_TYPE_DOUBLE: +diff --git a/dbdimp.h b/dbdimp.h +index 8723bcc..1ef5d72 100644 +--- a/dbdimp.h ++++ b/dbdimp.h +@@ -22,6 +22,7 @@ + #include /* Comes MySQL */ + + #include /* Comes with MySQL-devel */ ++#include /* For int32_t */ + + /* For now, we hardcode this, but in the future, + * we can detect capabilities of the MySQL libraries +@@ -212,7 +213,7 @@ typedef struct imp_sth_ph_st { + typedef struct imp_sth_phb_st { + union + { +- long lval; ++ int32_t lval; + double dval; + } numeric_val; + unsigned long length; +@@ -233,7 +234,7 @@ typedef struct imp_sth_fbh_st { + char *data; + int charsetnr; + double ddata; +- long ldata; ++ int32_t ldata; + #if MYSQL_VERSION_ID < FIELD_CHARSETNR_VERSION + unsigned int flags; + #endif +-- +2.7.4 + diff --git a/SPECS/perl-DBD-MySQL.spec b/SPECS/perl-DBD-MySQL.spec index fa6f2d3..e13b38a 100644 --- a/SPECS/perl-DBD-MySQL.spec +++ b/SPECS/perl-DBD-MySQL.spec @@ -1,11 +1,17 @@ Name: perl-DBD-MySQL Version: 4.023 -Release: 5%{?dist} +Release: 6%{?dist} Summary: A MySQL interface for Perl Group: Development/Libraries License: GPL+ or Artistic URL: http://search.cpan.org/dist/DBD-mysql/ Source0: http://www.cpan.org/authors/id/C/CA/CAPTTOFU/DBD-mysql-%{version}.tar.gz +# Fix transferring MYSQL_TYPE_LONG values on 64-bit big endian systems, +# bug #1311646, CPAN RT#57266, in upstream 4.033_03. +Patch0: DBD-mysql-4.033_02-Fix-transferring-MYSQL_TYPE_LONG-values-on-64-bit-bi.patch +# Tests for transferring MYSQL_TYPE_LONG, bug #1311646, CPAN RT#57266, +# in upstream 4.035_02. +Patch1: DBD-mysql-4.023-Tests-for-little-endian-platform.patch BuildRequires: mariadb, mariadb-devel, zlib-devel BuildRequires: perl BuildRequires: perl(Carp) @@ -34,6 +40,8 @@ management system. %prep %setup -q -n DBD-mysql-%{version} +%patch0 -p1 +%patch1 -p1 # Correct file permissions find . -type f | xargs chmod -x @@ -65,6 +73,10 @@ find %{buildroot} -type f -name '*.bs' -empty -exec rm -f {} ';' %{_mandir}/man3/*.3* %changelog +* Thu Oct 06 2016 Petr Pisar - 4.023-6 +- Fix transferring MYSQL_TYPE_LONG values on 64-bit big endian systems + (bug #1311646) + * Fri Jan 24 2014 Daniel Mach - 4.023-5 - Mass rebuild 2014-01-24