From 1c9056a27c303170060004c1be93787c6a32dcb6 Mon Sep 17 00:00:00 2001 From: Mark Wells Date: Wed, 25 Mar 2015 11:21:32 -0700 Subject: [PATCH] paymentech: enforce field lengths in raw bytes, #29972 --- FS/FS/Misc.pm | 21 +++++++++++++++++++++ FS/FS/pay_batch/paymentech.pm | 22 ++++++++++++++-------- 2 files changed, 35 insertions(+), 8 deletions(-) diff --git a/FS/FS/Misc.pm b/FS/FS/Misc.pm index f597058ef..9aeff93a6 100644 --- a/FS/FS/Misc.pm +++ b/FS/FS/Misc.pm @@ -22,6 +22,7 @@ use Encode; generate_ps generate_pdf do_print csv_from_fixed ocr_image + bytes_substr ); $DEBUG = 0; @@ -961,6 +962,26 @@ sub ocr_image { @lines; } +=item bytes_substr STRING, OFFSET[, LENGTH[, REPLACEMENT] ] + +A replacement for "substr" that counts raw bytes rather than logical +characters. Unlike "bytes::substr", will suppress fragmented UTF-8 characters +rather than output them. Unlike real "substr", is not an lvalue. + +=cut + +sub bytes_substr { + my ($string, $offset, $length, $repl) = @_; + my $bytes = substr( + Encode::encode('utf8', $string), + $offset, + $length, + Encode::encode('utf8', $repl) + ); + my $chk = $DEBUG ? Encode::FB_WARN : Encode::FB_QUIET; + return Encode::decode('utf8', $bytes, $chk); +} + =back =head1 BUGS diff --git a/FS/FS/pay_batch/paymentech.pm b/FS/FS/pay_batch/paymentech.pm index 1ecf35afd..91abbf273 100644 --- a/FS/FS/pay_batch/paymentech.pm +++ b/FS/FS/pay_batch/paymentech.pm @@ -8,6 +8,7 @@ use Date::Format 'time2str'; use Date::Parse 'str2time'; use Tie::IxHash; use FS::Conf; +use FS::Misc 'bytes_substr'; my $conf; my ($bin, $merchantID, $terminalID, $username, $password, $with_recurringInd); @@ -98,7 +99,13 @@ my %paymentech_countries = map { $_ => 1 } qw( US CA GB UK ); my @cust_pay_batch = @{(shift)}; my $count = 1; my $output; - my $xml = new XML::Writer(OUTPUT => \$output, DATA_MODE => 1, DATA_INDENT => 2); + my $xml = XML::Writer->new( + OUTPUT => \$output, + DATA_MODE => 1, + DATA_INDENT => 2, + ENCODING => 'utf-8' + ); + $xml->xmlDecl(); # it is in the spec $xml->startTag('transRequest', RequestCount => scalar(@cust_pay_batch) + 1); $xml->startTag('batchFileID'); $xml->dataElement(userID => $username); @@ -124,12 +131,12 @@ my %paymentech_countries = map { $_ => 1 } qw( US CA GB UK ); ecpBankAcctType => $paytype{lc($_->cust_main->paytype)}, ecpDelvMethod => 'A', ), - avsZip => substr($_->zip, 0, 10), - avsAddress1 => substr($_->address1, 0, 30), - avsAddress2 => substr($_->address2, 0, 30), - avsCity => substr($_->city, 0, 20), - avsState => substr($_->state, 0, 2), - avsName => substr($_->first. ' '. $_->last, 0, 30), + avsZip => bytes_substr($_->zip, 0, 10), + avsAddress1 => bytes_substr($_->address1, 0, 30), + avsAddress2 => bytes_substr($_->address2, 0, 30), + avsCity => bytes_substr($_->city, 0, 20), + avsState => bytes_substr($_->state, 0, 2), + avsName => bytes_substr($_->first. ' '. $_->last, 0, 30), ( $paymentech_countries{ $_->country } ? ( avsCountryCode => $_->country ) : () @@ -174,4 +181,3 @@ sub _upgrade_gateway { } 1; - -- 2.11.0