X-Git-Url: http://git.indexdata.com/?p=yaz-moved-to-github.git;a=blobdiff_plain;f=src%2Fmarcdisp.c;h=4e4230bb62805801f0ad1106295a6317a9b75ebd;hp=6c7ba4c8286a1b89d1057524493e097a33cc49e2;hb=84d7b06c13daa609e93f353e655c4b02f936d65c;hpb=60a702f390f7e2addfdab79f2328db3ba2897c8b diff --git a/src/marcdisp.c b/src/marcdisp.c index 6c7ba4c..4e4230b 100644 --- a/src/marcdisp.c +++ b/src/marcdisp.c @@ -2,7 +2,7 @@ * Copyright (C) 1995-2005, Index Data ApS * See the file LICENSE for details. * - * $Id: marcdisp.c,v 1.16 2005-02-08 13:51:30 adam Exp $ + * $Id: marcdisp.c,v 1.21 2005-04-20 13:17:51 adam Exp $ */ /** @@ -86,6 +86,7 @@ int yaz_marc_decode_wrbuf (yaz_marc_t mt, const char *buf, int bsize, WRBUF wr) int record_length; int indicator_length; int identifier_length; + int end_of_directory; int base_address; int length_data_entry; int length_starting; @@ -99,18 +100,12 @@ int yaz_marc_decode_wrbuf (yaz_marc_t mt, const char *buf, int bsize, WRBUF wr) || mt->xml == YAZ_MARC_MARCXML || mt->xml == YAZ_MARC_XCHANGE) produce_warnings = 1; - wrbuf_rewind(wr); - record_length = atoi_n (buf, 5); if (record_length < 25) { if (mt->debug) - { - char str[40]; - wrbuf_printf(wr, "\n", record_length); - } return -1; } memcpy(lead, buf, 24); /* se can modify the header for output */ @@ -219,8 +214,7 @@ int yaz_marc_decode_wrbuf (yaz_marc_t mt, const char *buf, int bsize, WRBUF wr) { char str[40]; - if (mt->xml) - wrbuf_puts (wr, "\n"); + wrbuf_puts (wr, "-->\n"); } /* first pass. determine length of directory & base of data */ for (entry_p = 24; buf[entry_p] != ISO2709_FS; ) { - entry_p += 3+length_data_entry+length_starting; - if (entry_p >= record_length) + /* length of directory entry */ + int l = 3 + length_data_entry + length_starting; + if (entry_p + l >= record_length) + { + wrbuf_printf (wr, "\n", entry_p); return -1; + } + if (mt->debug) + wrbuf_printf (wr, "\n", + entry_p, buf+entry_p); + /* check for digits in length info */ + while (--l >= 3) + if (!isdigit(*(const unsigned char *) (buf + entry_p+l))) + break; + if (l >= 3) + { + /* not all digits, so stop directory scan */ + wrbuf_printf (wr, "\n", entry_p); + break; + } + entry_p += 3 + length_data_entry + length_starting; } - if (mt->debug && base_address != entry_p+1) + end_of_directory = entry_p; + if (base_address != entry_p+1) { if (produce_warnings) - wrbuf_printf (wr," \n", base_address, entry_p+1); + wrbuf_printf (wr,"\n", base_address, entry_p+1); } - base_address = entry_p+1; - if (mt->xml == YAZ_MARC_ISO2709) { WRBUF wr_head = wrbuf_alloc(); @@ -262,7 +274,7 @@ int yaz_marc_decode_wrbuf (yaz_marc_t mt, const char *buf, int bsize, WRBUF wr) int data_p = 0; /* second pass. create directory for ISO2709 output */ - for (entry_p = 24; buf[entry_p] != ISO2709_FS; ) + for (entry_p = 24; entry_p != end_of_directory; ) { int data_length, data_offset, end_offset; int i, sz1, sz2; @@ -277,8 +289,11 @@ int yaz_marc_decode_wrbuf (yaz_marc_t mt, const char *buf, int bsize, WRBUF wr) i = data_offset + base_address; end_offset = i+data_length-1; - while (buf[i] != ISO2709_RS && buf[i] != ISO2709_FS && - i < end_offset) + if (data_length <= 0 || data_offset < 0 || end_offset >= record_length) + return -1; + + while (i < end_offset && + buf[i] != ISO2709_RS && buf[i] != ISO2709_FS) i++; sz1 = 1+i - (data_offset + base_address); if (mt->iconv_cd) @@ -306,7 +321,7 @@ int yaz_marc_decode_wrbuf (yaz_marc_t mt, const char *buf, int bsize, WRBUF wr) wrbuf_free(wr_tmp, 1); } /* third pass. create data output */ - for (entry_p = 24; buf[entry_p] != ISO2709_FS; ) + for (entry_p = 24; entry_p != end_of_directory; ) { int data_length; int data_offset; @@ -314,11 +329,10 @@ int yaz_marc_decode_wrbuf (yaz_marc_t mt, const char *buf, int bsize, WRBUF wr) int i, j; char tag[4]; int identifier_flag = 0; - int entry_p0; + int entry_p0 = entry_p; memcpy (tag, buf+entry_p, 3); entry_p += 3; - entry_p0 = entry_p; tag[3] = '\0'; data_length = atoi_n (buf+entry_p, length_data_entry); entry_p += length_data_entry; @@ -326,12 +340,23 @@ int yaz_marc_decode_wrbuf (yaz_marc_t mt, const char *buf, int bsize, WRBUF wr) entry_p += length_starting; i = data_offset + base_address; end_offset = i+data_length-1; + + if (data_length <= 0 || data_offset < 0) + break; if (mt->debug) { - wrbuf_printf(wr, "\n", + wrbuf_printf(wr, "\n", entry_p0, data_length, data_offset); } + if (end_offset >= record_length) + { + wrbuf_printf (wr,"\n", + entry_p0, end_offset, record_length); + break; + } if (memcmp (tag, "00", 2)) identifier_flag = 1; /* if not 00X assume subfields */ @@ -353,8 +378,6 @@ int yaz_marc_decode_wrbuf (yaz_marc_t mt, const char *buf, int bsize, WRBUF wr) switch(mt->xml) { case YAZ_MARC_LINE: - if (mt->debug) - wrbuf_puts (wr, "Tag: "); wrbuf_puts (wr, tag); wrbuf_puts (wr, " "); break; @@ -392,8 +415,6 @@ int yaz_marc_decode_wrbuf (yaz_marc_t mt, const char *buf, int bsize, WRBUF wr) wrbuf_putc(wr, buf[i]); break; case YAZ_MARC_LINE: - if (mt->debug) - wrbuf_puts (wr, " Ind: "); wrbuf_putc(wr, buf[i]); break; case YAZ_MARC_SIMPLEXML: @@ -421,14 +442,10 @@ int yaz_marc_decode_wrbuf (yaz_marc_t mt, const char *buf, int bsize, WRBUF wr) if (identifier_flag) wrbuf_puts (wr, "\n"); } - if (mt->xml == YAZ_MARC_LINE) - { - if (mt->debug) - wrbuf_puts (wr, " Fields: "); - } if (identifier_flag) { - while (buf[i] != ISO2709_RS && buf[i] != ISO2709_FS && i < end_offset) + while (i < end_offset && + buf[i] != ISO2709_RS && buf[i] != ISO2709_FS) { int i0; i++; @@ -467,8 +484,9 @@ int yaz_marc_decode_wrbuf (yaz_marc_t mt, const char *buf, int bsize, WRBUF wr) break; } i0 = i; - while (buf[i] != ISO2709_RS && buf[i] != ISO2709_IDFS && - buf[i] != ISO2709_FS && i < end_offset) + while (i < end_offset && + buf[i] != ISO2709_RS && buf[i] != ISO2709_IDFS && + buf[i] != ISO2709_FS) i++; marc_cdata(mt, buf + i0, i - i0, wr); @@ -485,7 +503,8 @@ int yaz_marc_decode_wrbuf (yaz_marc_t mt, const char *buf, int bsize, WRBUF wr) else { int i0 = i; - while (buf[i] != ISO2709_RS && buf[i] != ISO2709_FS && i < end_offset) + while (i < end_offset && + buf[i] != ISO2709_RS && buf[i] != ISO2709_FS) i++; marc_cdata(mt, buf + i0, i - i0, wr); if (mt->xml == YAZ_MARC_ISO2709) @@ -494,9 +513,9 @@ int yaz_marc_decode_wrbuf (yaz_marc_t mt, const char *buf, int bsize, WRBUF wr) if (mt->xml == YAZ_MARC_LINE) wrbuf_puts (wr, mt->endline_str); if (i < end_offset) - wrbuf_printf(wr, " \n", data_length); + wrbuf_printf(wr, "\n", data_length); if (buf[i] != ISO2709_RS && buf[i] != ISO2709_FS) - wrbuf_printf(wr, " \n", data_length); + wrbuf_printf(wr, "\n", data_length); switch(mt->xml) { case YAZ_MARC_SIMPLEXML: @@ -543,13 +562,10 @@ int yaz_marc_decode_buf (yaz_marc_t mt, const char *buf, int bsize, char **result, int *rsize) { int r = yaz_marc_decode_wrbuf(mt, buf, bsize, mt->m_wr); - if (r > 0) - { - if (result) - *result = wrbuf_buf(mt->m_wr); - if (rsize) - *rsize = wrbuf_len(mt->m_wr); - } + if (result) + *result = wrbuf_buf(mt->m_wr); + if (rsize) + *rsize = wrbuf_len(mt->m_wr); return r; }