Skip to content

Commit f26a19b

Browse files
committed
Fix segmentation fault when trying to save invalid long strings
This can occur if you have something like the following: ``` record(waveform, "foo") { field(FTVL, "CHAR") field(NELM, "10") info(autosaveFields, "VAL VAL$") } ``` The `VAL$` field will cause a segmentation fault when it tries to save it to disk. The reason this seems to happen is that on one hand, `VAL$` is regarded by autosave as a valid field (it is a field, but with a `$` at the end). On the other hand, when connecting a monitor, the connection fails as the `VAL` field is not of the correcct type as defined in `dbChannelCreate` from EPICS base. This means that autosave will try to save the date from an unconnected array, with uninitialised pArray, causing a segmentation fault.
1 parent 606903e commit f26a19b

File tree

1 file changed

+18
-3
lines changed

1 file changed

+18
-3
lines changed

asApp/src/dbrestore.c

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1522,7 +1522,8 @@ void makeAutosaveFileFromDbInfo(char *fileBaseName, char *info_name)
15221522
const char *info_value, *pbegin, *pend;
15231523
char *fname, *falloc=NULL, field[MAX_FIELD_SIZE], realfield[MAX_FIELD_SIZE];
15241524
FILE *out_fd;
1525-
int searchRecord, flen;
1525+
int searchRecord, flen
1526+
int long_string = 0;
15261527

15271528
if (!pdbbase) {
15281529
errlogPrintf("autosave:makeAutosaveFileFromDbInfo: No Database Loaded\n");
@@ -1574,9 +1575,23 @@ void makeAutosaveFileFromDbInfo(char *fileBaseName, char *info_name)
15741575
memcpy(field, pbegin, flen);
15751576
field[flen]='\0';
15761577
strNcpy(realfield, field, MAX_FIELD_SIZE-1);
1577-
if (realfield[strlen(realfield)-1] == '$') realfield[strlen(realfield)-1] = '\0';
1578+
if (realfield[strlen(realfield)-1] == '$') {
1579+
realfield[strlen(realfield)-1] = '\0';
1580+
long_string = 1;
1581+
}
15781582

1579-
if (dbFindField(pdbentry, realfield) == 0) {
1583+
/*
1584+
* To be clear: This checks that /if/ something is a long
1585+
* string, then we have to match it against a valid field
1586+
* type; see dbChannelCreate in dbChannel.c from EPICS
1587+
* base.
1588+
*/
1589+
if ((dbFindField(pdbentry, realfield) == 0) &&
1590+
(!long_string ||
1591+
(pdbentry->pflddes->field_type == DBF_STRING ||
1592+
(pdbentry->pflddes->field_type >= DBF_INLINK &&
1593+
pdbentry->pflddes->field_type <= DBF_FWDLINK))))
1594+
{
15801595
fprintf(out_fd, "%s.%s\n", dbGetRecordName(pdbentry), field);
15811596
} else {
15821597
printf("makeAutosaveFileFromDbInfo: %s.%s not found\n", dbGetRecordName(pdbentry), field);

0 commit comments

Comments
 (0)