From 39c8d5619a7cba9e95495cc99be9c25ab514f05c Mon Sep 17 00:00:00 2001 From: Dirk Zimoch Date: Thu, 13 Feb 2020 22:06:44 +0100 Subject: [PATCH] bugfix: dbGet should not crash because of empty array requests --- modules/database/src/ioc/db/dbAccess.c | 5 +++++ modules/database/src/ioc/db/dbDbLink.c | 31 ++++++++++---------------- 2 files changed, 17 insertions(+), 19 deletions(-) diff --git a/modules/database/src/ioc/db/dbAccess.c b/modules/database/src/ioc/db/dbAccess.c index da8467a0c..5d63c51d4 100644 --- a/modules/database/src/ioc/db/dbAccess.c +++ b/modules/database/src/ioc/db/dbAccess.c @@ -1001,6 +1001,11 @@ long dbGet(DBADDR *paddr, short dbrType, } else { DBADDR localAddr = *paddr; /* Structure copy */ + if (pfl->no_elements < 1) { + status = S_db_badField; + goto done; + } + localAddr.field_type = pfl->field_type; localAddr.field_size = pfl->field_size; localAddr.no_elements = pfl->no_elements; diff --git a/modules/database/src/ioc/db/dbDbLink.c b/modules/database/src/ioc/db/dbDbLink.c index f3335f4ba..c8452fd86 100644 --- a/modules/database/src/ioc/db/dbDbLink.c +++ b/modules/database/src/ioc/db/dbDbLink.c @@ -101,12 +101,6 @@ long dbDbInitLink(struct link *plink, short dbfType) precord = dbChannelRecord(chan); - if (dbChannelFinalElements(chan) < 1) { - errlogPrintf("Warning: %s.%s=%s has %ld elements. This will not work.\n", - plink->precord->name, dbLinkFieldName(plink), - dbChannelName(chan), dbChannelFinalElements(chan)); - } - plink->lset = &dbDb_lset; plink->type = DB_LINK; plink->value.pv_link.pvt = chan; @@ -122,12 +116,6 @@ long dbDbInitLink(struct link *plink, short dbfType) void dbDbAddLink(struct dbLocker *locker, struct link *plink, short dbfType, dbChannel *chan) { - if (dbChannelFinalElements(chan) < 1) { - errlogPrintf("Warning: %s.%s=%s has %ld elements. This will not work.\n", - plink->precord->name, dbLinkFieldName(plink), - dbChannelName(chan), dbChannelFinalElements(chan)); - } - plink->lset = &dbDb_lset; plink->type = DB_LINK; plink->value.pv_link.pvt = chan; @@ -197,15 +185,20 @@ static long dbDbGetValue(struct link *plink, short dbrType, void *pbuffer, fl.ctx = dbfl_context_read; fl.type = dbfl_type_rec; - if (dbChannelFinalElements(chan) < 1) + /* For the moment, empty arrays are not supported by EPICS */ + if (dbChannelFinalElements(chan) > 0) { - recGblSetSevr(precord, LINK_ALARM, UDF_ALARM); - return S_db_badField; + dbChannelRunPreChain(chan, &fl); + dbChannelRunPostChain(chan, &fl); + status = dbChannelGet(chan, dbrType, pbuffer, &options, pnRequest, &fl); + if (!status && pnRequest && *pnRequest <= 0) + status = S_db_badField; + } else { + status = S_db_badField; + } + if (status) { + recGblSetSevr(precord, LINK_ALARM, UDF_ALARM); } - - dbChannelRunPreChain(chan, &fl); - dbChannelRunPostChain(chan, &fl); - status = dbChannelGet(chan, dbrType, pbuffer, &options, pnRequest, &fl); } else if (ppv_link->getCvt && ppv_link->lastGetdbrType == dbrType) { status = ppv_link->getCvt(dbChannelField(chan), pbuffer, paddr); } else {