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.
This commit is contained in:
Andrew Johnson
2016-02-25 17:50:33 -06:00
parent c7bcb09540
commit 62efa2e96a

View File

@@ -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: