[Koha-patches] [PATCH] Bug 11032: Check a valid MARC::Record passed to Biblio
Colin Campbell
colin.campbell at ptfs-europe.com
Fri Oct 11 11:30:54 CEST 2013
Intermittently problems in the calling environment
cause a C4::Biblio to be called with and undefined
MARC::Record object. This results in the process
dieing and returning to the enduser a low level
message such as 'cannot call method x on an undefined
object'
For exported subroutines taking a MARC::Record object
check that object is defined otherwise return a logical
return value and log a stack trace to the error log.
A couple of cases were checking but dieing, this may have
unwelcome results in a persistent environment so croak has
been downgraded to carp
---
C4/Biblio.pm | 110 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++---
t/Biblio.t | 82 ++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 187 insertions(+), 5 deletions(-)
create mode 100755 t/Biblio.t
diff --git a/C4/Biblio.pm b/C4/Biblio.pm
index cf83ae6..508e3bf 100644
--- a/C4/Biblio.pm
+++ b/C4/Biblio.pm
@@ -252,6 +252,10 @@ sub AddBiblio {
my $frameworkcode = shift;
my $options = @_ ? shift : undef;
my $defer_marc_save = 0;
+ if (!$record) {
+ carp('AddBiblio called with undefined record');
+ return;
+ }
if ( defined $options and exists $options->{'defer_marc_save'} and $options->{'defer_marc_save'} ) {
$defer_marc_save = 1;
}
@@ -301,11 +305,16 @@ in the C<biblio> and C<biblioitems> tables, as well as
which fields are used to store embedded item, biblioitem,
and biblionumber data for indexing.
+Returns 1 on success 0 on failure
+
=cut
sub ModBiblio {
my ( $record, $biblionumber, $frameworkcode ) = @_;
- croak "No record" unless $record;
+ if (!$record) {
+ carp 'No record passed to ModBiblio';
+ return 0;
+ }
if ( C4::Context->preference("CataloguingLog") ) {
my $newrecord = GetMarcBiblio($biblionumber);
@@ -475,11 +484,17 @@ sub DelBiblio {
Automatically links headings in a bib record to authorities.
+Returns the number of headings changed
+
=cut
sub BiblioAutoLink {
my $record = shift;
my $frameworkcode = shift;
+ if (!$record) {
+ carp('Undefined record passed to BiblioAutoLink');
+ return 0;
+ }
my ( $num_headings_changed, %results );
my $linker_module =
@@ -487,7 +502,7 @@ sub BiblioAutoLink {
unless ( can_load( modules => { $linker_module => undef } ) ) {
$linker_module = 'C4::Linker::Default';
unless ( can_load( modules => { $linker_module => undef } ) ) {
- return 0, 0;
+ return 0;
}
}
@@ -524,6 +539,10 @@ sub LinkBibHeadingsToAuthorities {
my $frameworkcode = shift;
my $allowrelink = shift;
my %results;
+ if (!$bib) {
+ carp 'LinkBibHeadingsToAuthorities called on undefined bib record';
+ return ( 0, {});
+ }
require C4::Heading;
require C4::AuthoritiesMarc;
@@ -673,6 +692,11 @@ Get MARC fields from a keyword defined in fieldmapping table.
sub GetRecordValue {
my ( $field, $record, $frameworkcode ) = @_;
+
+ if (!$record) {
+ carp 'GetRecordValue called with undefined record';
+ return;
+ }
my $dbh = C4::Context->dbh;
my $sth = $dbh->prepare('SELECT fieldcode, subfieldcode FROM fieldmapping WHERE frameworkcode = ? AND field = ?');
@@ -1304,7 +1328,8 @@ sub GetCOinSBiblio {
# get the coin format
if ( ! $record ) {
- return;
+ carp 'GetCOinSBiblio called with undefined record';
+ return;
}
my $pos7 = substr $record->leader(), 7, 1;
my $pos6 = substr $record->leader(), 6, 1;
@@ -1445,10 +1470,20 @@ sub GetCOinSBiblio {
=head2 GetMarcPrice
return the prices in accordance with the Marc format.
+
+returns 0 if no price found
+returns undef if called without a marc record or with
+an unrecognized marc format
+
=cut
sub GetMarcPrice {
my ( $record, $marcflavour ) = @_;
+ if (!$record) {
+ carp 'GetMarcPrice called on undefined record';
+ return;
+ }
+
my @listtags;
my $subfield;
@@ -1520,10 +1555,19 @@ sub MungeMarcPrice {
return the quantity of a book. Used in acquisition only, when importing a file an iso2709 from a bookseller
Warning : this is not really in the marc standard. In Unimarc, Electre (the most widely used bookseller) use the 969$a
+returns 0 if no quantity found
+returns undef if called without a marc record or with
+an unrecognized marc format
+
=cut
sub GetMarcQuantity {
my ( $record, $marcflavour ) = @_;
+ if (!$record) {
+ carp 'GetMarcQuantity called on undefined record';
+ return;
+ }
+
my @listtags;
my $subfield;
@@ -1610,6 +1654,10 @@ Get the control number / record Identifier from the MARC record and return it.
sub GetMarcControlnumber {
my ( $record, $marcflavour ) = @_;
+ if (!$record) {
+ carp 'GetMarcControlnumber called on undefined record';
+ return;
+ }
my $controlnumber = "";
# Control number or Record identifier are the same field in MARC21, UNIMARC and NORMARC
# Keep $marcflavour for possible later use
@@ -1633,6 +1681,10 @@ ISBNs stored in different fields depending on MARC flavour
sub GetMarcISBN {
my ( $record, $marcflavour ) = @_;
+ if (!$record) {
+ carp 'GetMarcISBN called on undefined record';
+ return;
+ }
my $scope;
if ( $marcflavour eq "UNIMARC" ) {
$scope = '010';
@@ -1674,6 +1726,10 @@ ISSNs are stored in different fields depending on MARC flavour
sub GetMarcISSN {
my ( $record, $marcflavour ) = @_;
+ if (!$record) {
+ carp 'GetMarcISSN called on undefined record';
+ return;
+ }
my $scope;
if ( $marcflavour eq "UNIMARC" ) {
$scope = '011';
@@ -1699,6 +1755,10 @@ The note are stored in different fields depending on MARC flavour
sub GetMarcNotes {
my ( $record, $marcflavour ) = @_;
+ if (!$record) {
+ carp 'GetMarcNotes called on undefined record';
+ return;
+ }
my $scope;
if ( $marcflavour eq "UNIMARC" ) {
$scope = '3..';
@@ -1743,6 +1803,10 @@ The subjects are stored in different fields depending on MARC flavour
sub GetMarcSubjects {
my ( $record, $marcflavour ) = @_;
+ if (!$record) {
+ carp 'GetMarcSubjects called on undefined record';
+ return;
+ }
my ( $mintag, $maxtag, $fields_filter );
if ( $marcflavour eq "UNIMARC" ) {
$mintag = "600";
@@ -1828,6 +1892,10 @@ The authors are stored in different fields depending on MARC flavour
sub GetMarcAuthors {
my ( $record, $marcflavour ) = @_;
+ if (!$record) {
+ carp 'GetMarcAuthors called on undefined record';
+ return;
+ }
my ( $mintag, $maxtag, $fields_filter );
# tagslib useful for UNIMARC author reponsabilities
@@ -1916,6 +1984,10 @@ Assumes web resources (not uncommon in MARC21 to omit resource type ind)
sub GetMarcUrls {
my ( $record, $marcflavour ) = @_;
+ if (!$record) {
+ carp 'GetMarcUrls called on undefined record';
+ return;
+ }
my @marcurls;
for my $field ( $record->field('856') ) {
@@ -1971,6 +2043,11 @@ The series are stored in different fields depending on MARC flavour
sub GetMarcSeries {
my ( $record, $marcflavour ) = @_;
+ if (!$record) {
+ carp 'GetMarcSeries called on undefined record';
+ return;
+ }
+
my ( $mintag, $maxtag, $fields_filter );
if ( $marcflavour eq "UNIMARC" ) {
$mintag = "225";
@@ -2040,6 +2117,11 @@ Get all host records (773s MARC21, 461 UNIMARC) from the MARC record and returns
sub GetMarcHosts {
my ( $record, $marcflavour ) = @_;
+ if (!$record) {
+ carp 'GetMarcHosts called on undefined record';
+ return;
+ }
+
my ( $tag,$title_subf,$bibnumber_subf,$itemnumber_subf);
$marcflavour ||="MARC21";
if ( $marcflavour eq "MARC21" || $marcflavour eq "NORMARC" ) {
@@ -2483,12 +2565,19 @@ our $inverted_field_map;
Extract data from a MARC bib record into a hashref representing
Koha biblio, biblioitems, and items fields.
+If passed an undefined record will log the error and return an empty
+hash_ref
+
=cut
sub TransformMarcToKoha {
my ( $dbh, $record, $frameworkcode, $limit_table ) = @_;
- my $result;
+ my $result = {};
+ if (!defined $record) {
+ carp('TransformMarcToKoha called with undefined record');
+ return $result;
+ }
$limit_table = $limit_table || 0;
$frameworkcode = '' unless defined $frameworkcode;
@@ -2801,7 +2890,10 @@ if $itemnumbers is defined, only specified itemnumbers are embedded
sub EmbedItemsInMarcBiblio {
my ($marc, $biblionumber, $itemnumbers) = @_;
- croak "No MARC record" unless $marc;
+ if ( !$marc ) {
+ carp 'EmbedItemsInMarcBiblio: No MARC record passed';
+ return;
+ }
$itemnumbers = [] unless defined $itemnumbers;
@@ -3264,6 +3356,10 @@ sub ModBiblioMarc {
# pass the MARC::Record to this function, and it will create the records in
# the marc field
my ( $record, $biblionumber, $frameworkcode ) = @_;
+ if ( !$record ) {
+ carp 'ModBiblioMarc passed an undefined record';
+ return;
+ }
# Clone record as it gets modified
$record = $record->clone();
@@ -3625,6 +3721,10 @@ Removes all nsb/nse chars from a record
sub RemoveAllNsb {
my $record = shift;
+ if (!$record) {
+ carp 'RemoveAllNsb called with undefined record';
+ return;
+ }
SetUTF8Flag($record);
diff --git a/t/Biblio.t b/t/Biblio.t
new file mode 100755
index 0000000..9a1b8f4
--- /dev/null
+++ b/t/Biblio.t
@@ -0,0 +1,82 @@
+#!/usr/bin/perl
+#
+use strict;
+use warnings;
+
+use Test::More tests => 22;
+
+BEGIN {
+ use_ok('C4::Biblio');
+}
+
+# test returns if undef record passed
+# carp messages appear on stdout
+
+my @arr = AddBiblio(undef, q{});
+my $elements = @arr;
+
+is($elements, 0, 'Add Biblio returns empty array for undef record');
+
+my $ret = ModBiblio(undef, 0, '');
+
+is( $ret, 0, 'ModBiblio returns zero if not passed rec');
+
+$ret = BiblioAutoLink(undef, q{});
+
+is( $ret, 0, 'BiblioAutoLink returns zero if not passed rec');
+
+$ret = GetRecordValue('100', undef, q{});
+ok( !defined $ret, 'GetRecordValue returns undef if not passed rec');
+
+ at arr = LinkBibHeadingsToAuthorities(q{}, q{});
+is($arr[0], 0, 'LinkBibHeadingsToAuthorities correct error return');
+
+$ret = GetCOinSBiblio();
+ok( !defined $ret, 'GetCOinSBiblio returns undef if not passed rec');
+
+$ret = GetMarcPrice(undef, 'MARC21');
+ok( !defined $ret, 'GetMarcPrice returns undef if not passed rec');
+
+$ret = GetMarcQuantity(undef, 'MARC21');
+ok( !defined $ret, 'GetMarcQuantity returns undef if not passed rec');
+
+$ret = GetMarcControlnumber();
+ok( !defined $ret, 'GetMarcControlnumber returns undef if not passed rec');
+
+$ret = GetMarcISBN();
+ok( !defined $ret, 'GetMarcISBN returns undef if not passed rec');
+
+$ret = GetMarcISSN();
+ok( !defined $ret, 'GetMarcISSN returns undef if not passed rec');
+
+$ret = GetMarcNotes();
+ok( !defined $ret, 'GetMarcNotes returns undef if not passed rec');
+
+$ret = GetMarcSubjects();
+ok( !defined $ret, 'GetMarcSubjects returns undef if not passed rec');
+
+$ret = GetMarcAuthors();
+ok( !defined $ret, 'GetMarcAuthors returns undef if not passed rec');
+
+$ret = GetMarcUrls();
+ok( !defined $ret, 'GetMarcUrls returns undef if not passed rec');
+
+$ret = GetMarcSeries();
+ok( !defined $ret, 'GetMarcSeries returns undef if not passed rec');
+
+$ret = GetMarcHosts();
+ok( !defined $ret, 'GetMarcHosts returns undef if not passed rec');
+
+my $hash_ref = TransformMarcToKoha(undef, undef);
+
+isa_ok( $hash_ref, 'HASH');
+
+$elements = keys %{$hash_ref};
+
+is($elements, 0, 'Empty hashref returned for undefined record in TransformMarcToKoha');
+
+$ret = ModBiblioMarc();
+ok( !defined $ret, 'ModBiblioMarc returns undef if not passed rec');
+
+$ret = RemoveAllNsb();
+ok( !defined $ret, 'RemoveAllNsb returns undef if not passed rec');
--
1.8.3.1
More information about the Koha-patches
mailing list