in reply to Re^6: Recalcitrant placeholders
in thread Recalcitrant placeholders
Sorry for the late reply.
I addressed this in the original question: Things I have tried...Forcing array context my ($crid) = $crm->db->selectrow_array - no change
I missed that, sorry about that.
Some testing has proved that it is about tainted data being passed to the placeholders and only with selectrow_array, not execute and fetchrow_array. With taint mode on, if I pass a value to the placeholder that has come from STDIN then it fails silently. But if I pass the same value assigned to the variable in my script and pass that to the placeholder, it works.
Thanks for the further information, that does somewhat make sense. Unfortunately, I still haven't been able to reproduce it. What version of MySQL, DBI, DBD::mysql, etc. are you using? Does the code below produce the incorrect results for you?
This behaviour makes sense but it would also make sense for it to throw an error when I try to do it rather than failing silently.
The DBI docs say that as of v1.31, you can turn on the TaintIn option, which works for me in that it causes DBI to die with tainted arguments.
#!/usr/bin/perl -T use warnings; use strict; use feature 'say'; use Scalar::Util qw/tainted/; use DBI; use DBI::Const::GetInfoType; my $dbh = DBI->connect( "DBI:mysql:database=testing;host=127.0.0.1", $ENV{USER}, 'barfoo', { RaiseError=>1, AutoCommit=>1, TaintIn=>0 }); say "Perl: $]"; say "Database: ", $dbh->get_info( $GetInfoType{SQL_DBMS_NAME} ), " ", $dbh->get_info( $GetInfoType{SQL_DBMS_VER} ); say "Driver: ", $dbh->{Driver}->{Name}; say "DBI Ver: ", $DBI::VERSION; say "DBD::mysql Ver: ", $DBD::mysql::VERSION; $dbh->do('DROP TABLE IF EXISTS Person'); $dbh->do(<<'ENDSQL'); CREATE TABLE Person ( idPerson VARCHAR(256), email VARCHAR(256), altEmail VARCHAR(256) ); ENDSQL $dbh->do('INSERT INTO Person (idPerson, email, altEmail) VALUES ("hell +o","foo@bar.com","foo@bar.com");'); die "run me with an empty string as the first argument" unless @ARGV && !length $ARGV[0]; my %data = ( email => 'foo@bar.com'.shift(@ARGV) ); die unless tainted($data{'email'}); my $query = $dbh->prepare("SELECT idPerson FROM Person WHERE email = ? + OR altEmail = ?"); $query->execute($data{'email'}, $data{'email'}); my ($crid) = $query->fetchrow_array; say "CRID: $crid"; my ($test) = $dbh->selectrow_array("SELECT idPerson FROM Person WHERE +email = ? OR altEmail = ?", undef, $data{'email'}, $data{'email'}); say "TEST: $test"; __END__ Perl: 5.032001 Database: MySQL 5.7.33 Driver: mysql DBI Ver: 1.643 DBD::mysql Ver: 4.050 CRID: hello TEST: hello
I spun up the test database with Docker as I showed in this node.
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re^8: Recalcitrant placeholders
by Bod (Parson) on Jul 25, 2021 at 14:31 UTC | |
by haukex (Archbishop) on Jul 28, 2021 at 09:17 UTC | |
by Bod (Parson) on Aug 05, 2021 at 19:07 UTC | |
by pryrt (Abbot) on Aug 05, 2021 at 20:27 UTC | |
by Bod (Parson) on Aug 05, 2021 at 23:24 UTC | |
| |
by haukex (Archbishop) on Aug 06, 2021 at 17:20 UTC | |
by Bod (Parson) on Aug 08, 2021 at 18:52 UTC | |
| |
by Bod (Parson) on Aug 02, 2021 at 22:36 UTC |