From dc030e8fbc67937e0fa1812f6ce4a8ab728d092c Mon Sep 17 00:00:00 2001 From: Adam Dickmeiss Date: Fri, 29 Apr 2005 18:38:50 +0000 Subject: [PATCH] Fixed bug #305: Scan with preferredPositionInResponse <= -2 crashes. --- index/zrpn.c | 102 ++++++++++++++++++++++++++++++++++------------------------ 1 file changed, 60 insertions(+), 42 deletions(-) diff --git a/index/zrpn.c b/index/zrpn.c index 87190e1..325c066 100644 --- a/index/zrpn.c +++ b/index/zrpn.c @@ -1,4 +1,4 @@ -/* $Id: zrpn.c,v 1.182 2005-04-29 10:54:45 adam Exp $ +/* $Id: zrpn.c,v 1.183 2005-04-29 18:38:50 adam Exp $ Copyright (C) 1995-2005 Index Data ApS @@ -2598,6 +2598,7 @@ static int scan_handle (char *name, const char *info, int pos, void *client) idx = scan_info->after - pos + scan_info->before; else idx = - pos - 1; + if (idx < 0) return 0; scan_info->list[idx].term = (char *) @@ -2818,19 +2819,17 @@ ZEBRA_RES rpn_scan(ZebraHandle zh, ODR stream, Z_AttributesPlusTerm *zapt, return ZEBRA_OK; } /* prepare dictionary scanning */ - if (pos < 1 || pos > num) - { - zh->errCode = YAZ_BIB1_SCAN_UNSUPP_VALUE_OF_POSITION_IN_RESPONSE; - *num_entries = 0; - return ZEBRA_FAIL; - } if (num < 1) { *num_entries = 0; return ZEBRA_OK; } before = pos-1; + if (before < 0) + before = 0; after = 1+num-pos; + if (after < 0) + after = 0; yaz_log(YLOG_DEBUG, "rpn_scan pos=%d num=%d before=%d " "after=%d before+after=%d", pos, num, before, after, before+after); @@ -2880,8 +2879,10 @@ ZEBRA_RES rpn_scan(ZebraHandle zh, ODR stream, Z_AttributesPlusTerm *zapt, int j, j0 = -1; const char *mterm = NULL; const char *tst; - RSET rset; - + RSET rset = 0; + int lo = i + pos-1; /* offset in result list */ + + /* find: j0 is the first of the minimal values */ for (j = 0; j < ord_no; j++) { if (ptr[j] < before+after && ptr[j] >= 0 && @@ -2893,45 +2894,61 @@ ZEBRA_RES rpn_scan(ZebraHandle zh, ODR stream, Z_AttributesPlusTerm *zapt, } } if (j0 == -1) - break; - scan_term_untrans(zh, stream->mem, reg_id, - &glist[i+before].term, mterm); - rset = rset_trunc(zh, &scan_info_array[j0].list[ptr[j0]].isam_p, 1, - glist[i+before].term, strlen(glist[i+before].term), - NULL, 0, zapt->term->which, rset_nmem, - key_it_ctrl,key_it_ctrl->scope); - ptr[j0]++; + break; /* no value found, stop */ + + /* get result set for first one , but only if it's within bounds */ + if (lo >= 0) + { + /* get result set for first term */ + scan_term_untrans(zh, stream->mem, reg_id, + &glist[lo].term, mterm); + rset = rset_trunc(zh, &scan_info_array[j0].list[ptr[j0]].isam_p, 1, + glist[lo].term, strlen(glist[lo].term), + NULL, 0, zapt->term->which, rset_nmem, + key_it_ctrl,key_it_ctrl->scope); + } + ptr[j0]++; /* move index for this set .. */ + /* get result set for remaining scan terms */ for (j = j0+1; j= 0 && (tst = scan_info_array[j].list[ptr[j]].term) && !strcmp (tst, mterm)) { - RSET rsets[2]; - - rsets[0] = rset; - rsets[1] = - rset_trunc(zh, &scan_info_array[j].list[ptr[j]].isam_p, 1, - glist[i+before].term, - strlen(glist[i+before].term), NULL, 0, - zapt->term->which,rset_nmem, - key_it_ctrl, key_it_ctrl->scope); - rset = rsmulti_or_create(rset_nmem, key_it_ctrl, - 2, key_it_ctrl->scope, rsets); + if (lo >= 0) + { + RSET rsets[2]; + + rsets[0] = rset; + rsets[1] = + rset_trunc( + zh, &scan_info_array[j].list[ptr[j]].isam_p, 1, + glist[lo].term, + strlen(glist[lo].term), NULL, 0, + zapt->term->which,rset_nmem, + key_it_ctrl, key_it_ctrl->scope); + rset = rsmulti_or_create(rset_nmem, key_it_ctrl, + 2, key_it_ctrl->scope, rsets); + } ptr[j]++; } } - if (limit_set) + if (lo >= 0) { - RSET rsets[2]; - rsets[0] = rset; - rsets[1] = rset_dup(limit_set); - - rset = rsmulti_and_create(rset_nmem, key_it_ctrl, - key_it_ctrl->scope, 2, rsets); + /* merge with limit_set if given */ + if (limit_set) + { + RSET rsets[2]; + rsets[0] = rset; + rsets[1] = rset_dup(limit_set); + + rset = rsmulti_and_create(rset_nmem, key_it_ctrl, + key_it_ctrl->scope, 2, rsets); + } + /* count it */ + count_set(rset, &glist[lo].occurrences); + rset_delete(rset); } - count_set(rset, &glist[i+before].occurrences); - rset_delete(rset); } if (i < after) { @@ -2948,6 +2965,7 @@ ZEBRA_RES rpn_scan(ZebraHandle zh, ODR stream, Z_AttributesPlusTerm *zapt, const char *mterm = NULL; const char *tst; RSET rset; + int lo = before-1-i; /* offset in result list */ for (j = 0; j mem, reg_id, - &glist[before-1-i].term, mterm); + &glist[lo].term, mterm); rset = rset_trunc (zh, &scan_info_array[j0].list[before-1-ptr[j0]].isam_p, 1, - glist[before-1-i].term, strlen(glist[before-1-i].term), + glist[lo].term, strlen(glist[lo].term), NULL, 0, zapt->term->which,rset_nmem, key_it_ctrl,key_it_ctrl->scope); @@ -2985,8 +3003,8 @@ ZEBRA_RES rpn_scan(ZebraHandle zh, ODR stream, Z_AttributesPlusTerm *zapt, rsets[1] = rset_trunc( zh, &scan_info_array[j].list[before-1-ptr[j]].isam_p, 1, - glist[before-1-i].term, - strlen(glist[before-1-i].term), NULL, 0, + glist[lo].term, + strlen(glist[lo].term), NULL, 0, zapt->term->which, rset_nmem, key_it_ctrl, key_it_ctrl->scope); rset = rsmulti_or_create(rset_nmem, key_it_ctrl, @@ -3004,7 +3022,7 @@ ZEBRA_RES rpn_scan(ZebraHandle zh, ODR stream, Z_AttributesPlusTerm *zapt, rset = rsmulti_and_create(rset_nmem, key_it_ctrl, key_it_ctrl->scope, 2, rsets); } - count_set (rset, &glist[before-1-i].occurrences); + count_set (rset, &glist[lo].occurrences); rset_delete (rset); } i = before-i; -- 1.7.10.4