From 62efa2e96a4145e79c6c3032172ce39d57bb0c3f Mon Sep 17 00:00:00 2001 From: Andrew Johnson Date: Thu, 25 Feb 2016 17:50:33 -0600 Subject: [PATCH] Fix the dbGet() array with field-log bug. This also fixes a problem where the array is used in circular buffer mode and the request has an offset, but the array is not actually full at the time; to copy the data out of the array the convert() routine needs to know the capacity of the array to know when to wrap around, but we were passing it the current length instead. --- src/ioc/db/dbAccess.c | 49 +++++++++++++++++++------------------------ 1 file changed, 22 insertions(+), 27 deletions(-) diff --git a/src/ioc/db/dbAccess.c b/src/ioc/db/dbAccess.c index b7a650282..50fd5a7f3 100644 --- a/src/ioc/db/dbAccess.c +++ b/src/ioc/db/dbAccess.c @@ -812,11 +812,10 @@ long dbGet(DBADDR *paddr, short dbrType, void *pbuffer, long *options, long *nRequest, void *pflin) { char *pbuf = pbuffer; - void *pfieldsave; + void *pfieldsave = paddr->pfield; db_field_log *pfl = (db_field_log *)pflin; short field_type; - long no_elements; - long offset; + long capacity, no_elements, offset; struct rset *prset; long status = 0; @@ -826,11 +825,20 @@ long dbGet(DBADDR *paddr, short dbrType, return 0; if (!pfl || pfl->type == dbfl_type_rec) { - field_type = paddr->field_type; - no_elements = paddr->no_elements; + field_type = paddr->field_type; + no_elements = capacity = paddr->no_elements; + + /* Update field info from record */ + if (paddr->pfldDes->special == SPC_DBADDR && + (prset = dbGetRset(paddr)) && + prset->get_array_info) { + status = prset->get_array_info(paddr, &no_elements, &offset); + } else + offset = 0; } else { - field_type = pfl->field_type; - no_elements = pfl->no_elements; + field_type = pfl->field_type; + no_elements = capacity = pfl->no_elements; + offset = 0; } if (field_type >= DBF_INLINK && field_type <= DBF_FWDLINK) @@ -848,23 +856,9 @@ long dbGet(DBADDR *paddr, short dbrType, return S_db_badDbrtype; } - /* For SPC_DBADDR fields, the rset function - * get_array_info() is allowed to modify - * paddr->pfield. So we store the original - * value and restore it later. - */ - pfieldsave = paddr->pfield; - - /* Update field info */ - if (paddr->pfldDes->special == SPC_DBADDR && - (prset = dbGetRset(paddr)) && - prset->get_array_info) { - status = prset->get_array_info(paddr, &no_elements, &offset); - } else - offset = 0; - if (offset == 0 && (!nRequest || no_elements == 1)) { - if (nRequest) *nRequest = 1; + if (nRequest) + *nRequest = 1; if (!pfl || pfl->type == dbfl_type_rec) { status = dbFastGetConvertRoutine[field_type][dbrType] (paddr->pfield, pbuf, paddr); @@ -886,7 +880,8 @@ long dbGet(DBADDR *paddr, short dbrType, long (*convert)(); if (nRequest) { - if (no_elements<(*nRequest)) *nRequest = no_elements; + if (no_elements < *nRequest) + *nRequest = no_elements; n = *nRequest; } else { n = 1; @@ -901,11 +896,11 @@ long dbGet(DBADDR *paddr, short dbrType, status = S_db_badDbrtype; goto done; } - /* convert database field and place it in the buffer */ + /* convert data into the caller's buffer */ if (n <= 0) { ;/*do nothing*/ } else if (!pfl || pfl->type == dbfl_type_rec) { - status = convert(paddr, pbuf, n, no_elements, offset); + status = convert(paddr, pbuf, n, capacity, offset); } else { DBADDR localAddr = *paddr; /* Structure copy */ @@ -916,7 +911,7 @@ long dbGet(DBADDR *paddr, short dbrType, localAddr.pfield = (char *) &pfl->u.v.field; else localAddr.pfield = (char *) pfl->u.r.field; - status = convert(&localAddr, pbuf, n, no_elements, offset); + status = convert(&localAddr, pbuf, n, capacity, offset); } } done: