diff --git a/asApp/src/dbrestore.c b/asApp/src/dbrestore.c index f8b3bbac..9aae4877 100644 --- a/asApp/src/dbrestore.c +++ b/asApp/src/dbrestore.c @@ -755,7 +755,7 @@ long SR_array_restore(int pass, FILE *inp_fd, char *PVname, char *value_string, */ int reboot_restore(char *filename, initHookState init_state) { - char PVname[PV_NAME_LEN + 1]; /* Must be greater than max field width ("%80s") in the sscanf format below */ + char PVname[PV_NAME_LEN + 1]; /* Must be PV_NAME_LEN + 1 so that we can detect names that are too long. */ char bu_filename[PATH_SIZE + 1], fname[PATH_SIZE + 1] = ""; char buffer[BUF_SIZE], *bp; char ebuffer[EBUF_SIZE]; /* make room for macro expansion */ @@ -770,7 +770,7 @@ int reboot_restore(char *filename, initHookState init_state) int n, write_backup, num_errors, is_scalar; long *pStatusVal = 0; char *statusStr = 0; - char realName[64]; /* name without trailing '$' */ + char realName[PV_NAME_LEN+1]; /* name without trailing '$' */ int is_long_string; struct restoreFileListItem *pLI; /* macrostring */ @@ -858,6 +858,7 @@ int reboot_restore(char *filename, initHookState init_state) /* restore from data file */ num_errors = 0; while ((bp = fgets(buffer, BUF_SIZE, inp_fd))) { + int name_len = 0; if (handle && pairs) { ebuffer[0] = '\0'; macExpandString(handle, buffer, ebuffer, EBUF_SIZE); @@ -882,8 +883,16 @@ int reboot_restore(char *filename, initHookState init_state) */ PVname[0] = '\0'; value_string[0] = '\0'; - n = sscanf(bp, "%80s%c%[^\n\r]", PVname, &c, value_string); - if (n < 3) *value_string = 0; + n = sscanf(bp, "%*s%n%c%[^\n\r]", &name_len, &c, value_string); + /* PVname can store one more character than PV_NAME_LEN. */ + if (name_len <= PV_NAME_LEN) { + strncpy(PVname, bp, name_len); + PVname[name_len] = '\0'; + } else { + strncpy(PVname, bp, PV_NAME_LEN); + PVname[PV_NAME_LEN] = '\0'; + } + if (n < 2) *value_string = 0; if ((n < 1) || (PVname[0] == '\0')) { if (save_restoreDebug >= 10) { ERRLOG("line (fragment) '%s' ignored.\n", bp); @@ -900,7 +909,7 @@ int reboot_restore(char *filename, initHookState init_state) } continue; } - if (strlen(PVname) >= 80) { + if (strlen(PVname) >= PV_NAME_LEN) { /* must be a munged input line */ ERRLOG("'%s' is too long to be a PV name.\n", PVname); continue; @@ -930,7 +939,7 @@ int reboot_restore(char *filename, initHookState init_state) /* dbStatic doesn't know about long-string fields (PV name with appended '$'). */ is_long_string = 0; - strNcpy(realName, PVname, 63); + strNcpy(realName, PVname, PV_NAME_LEN); if (realName[strlen(realName) - 1] == '$') { realName[strlen(realName) - 1] = '\0'; is_long_string = 1; diff --git a/asApp/src/save_restore.c b/asApp/src/save_restore.c index 1e0141c7..18d27ddf 100644 --- a/asApp/src/save_restore.c +++ b/asApp/src/save_restore.c @@ -261,7 +261,7 @@ struct chlist { /* save set list element */ struct channel { /* database channel list element */ struct channel *pnext; /* next channel */ - char name[64]; /* channel name */ + char name[PV_NAME_LEN + 1]; /* channel name */ chid chid; /* channel access id */ char value[64]; /* value string */ short enum_val; /* short value of an enumerated field */ @@ -3126,7 +3126,7 @@ STATIC int do_manual_restore(char *filename, int file_type, char *macrostring) struct channel *pchannel; struct chlist *plist; int found, is_scalar; - char PVname[80]; + char PVname[PV_NAME_LEN + 1]; char restoreFile[MAX_PATH_LEN + 1] = ""; char bu_filename[MAX_PATH_LEN + 1] = ""; char buffer[BUF_SIZE], *bp, c; @@ -3238,6 +3238,7 @@ STATIC int do_manual_restore(char *filename, int file_type, char *macrostring) /* restore from data file */ while ((bp = fgets(buffer, BUF_SIZE, inp_fd))) { + int name_len = 0; if (handle && pairs) { ebuffer[0] = '\0'; macExpandString(handle, buffer, ebuffer, EBUF_SIZE); @@ -3248,8 +3249,16 @@ STATIC int do_manual_restore(char *filename, int file_type, char *macrostring) /* (value may be a string with leading whitespace; it may be */ /* entirely whitespace; the number of spaces may be crucial; */ /* it might also consist of zero characters) */ - n = sscanf(bp, "%s%c%[^\n]", PVname, &c, value_string); - if (n < 3) *value_string = 0; + n = sscanf(bp, "%*s%n%c%[^\n]", &name_len, &c, value_string); + if (n < 2) *value_string = 0; + /* PVname can store one more character than PV_NAME_LEN. */ + if (name_len <= PV_NAME_LEN) { + strncpy(PVname, bp, name_len); + PVname[name_len] = '\0'; + } else { + strncpy(PVname, bp, PV_NAME_LEN); + PVname[PV_NAME_LEN] = '\0'; + } if (strncmp(PVname, "", 5) == 0) { break; } if (save_restoreDebug >= 5) { printf("save_restore:do_manual_restore: PVname='%s'\n", PVname); } if (isValid1stPVChar((int)PVname[0])) { @@ -3466,7 +3475,7 @@ STATIC int readReqFile(const char *reqFile, struct chlist *plist, char *macrostr { struct channel *pchannel = NULL; FILE *inp_fd = NULL; - char name[80] = "", *t = NULL, line[BUF_SIZE] = "", eline[EBUF_SIZE] = ""; + char name[PV_NAME_LEN] = "", *t = NULL, line[BUF_SIZE] = "", eline[EBUF_SIZE] = ""; char templatefile[MAX_PATH_LEN + 1] = ""; char new_macro[BUF_SIZE] = ""; int i = 0; @@ -3597,7 +3606,7 @@ STATIC int readReqFile(const char *reqFile, struct chlist *plist, char *macrostr } plist->plast_chan = pchannel; #endif - strNcpy(pchannel->name, name, 64); + strNcpy(pchannel->name, name, PV_NAME_LEN); strNcpy(pchannel->value, "Not Connected", 64); pchannel->enum_val = -1; pchannel->max_elements = 0; @@ -3616,16 +3625,16 @@ STATIC int readReqFile(const char *reqFile, struct chlist *plist, char *macrostr * this can only be done when the list is defined. */ if (handle) { - if (macGetValue(handle, "SAVEPATHPV", name, 80) > 0) { + if (macGetValue(handle, "SAVEPATHPV", name, PV_NAME_LEN) > 0) { plist->do_backups = 0; strNcpy(plist->savePathPV, name, PV_NAME_LEN); } - if (macGetValue(handle, "SAVENAMEPV", name, 80) > 0) { + if (macGetValue(handle, "SAVENAMEPV", name, PV_NAME_LEN) > 0) { plist->do_backups = 0; strNcpy(plist->saveNamePV, name, PV_NAME_LEN); } - if (macGetValue(handle, "CONFIG", name, 80) > 0) { strNcpy(plist->config, name, PV_NAME_LEN); } - if (macGetValue(handle, "CONFIGMENU", name, 80) > 0) { plist->do_backups = 0; } + if (macGetValue(handle, "CONFIG", name, PV_NAME_LEN) > 0) { strNcpy(plist->config, name, PV_NAME_LEN); } + if (macGetValue(handle, "CONFIGMENU", name, PV_NAME_LEN) > 0) { plist->do_backups = 0; } macDeleteHandle(handle); if (pairs) free(pairs); } diff --git a/asApp/src/save_restore.h b/asApp/src/save_restore.h index 239faf44..9a4c711a 100644 --- a/asApp/src/save_restore.h +++ b/asApp/src/save_restore.h @@ -1,5 +1,6 @@ /* save_restore.h */ +#include /* PVNAME_STRINGSZ for PV length*/ #include /* pass0List, pass1List */ #include #include "save_restore_common.h" @@ -51,7 +52,9 @@ #define FN_LEN 80 /* filename length */ #define STRING_LEN MAX_STRING_SIZE /* EPICS max length for string PV */ #define STATUS_STR_LEN 300 -#define PV_NAME_LEN 80 /* string containing a PV name */ +/* PV_NAME_LENGTH was historcially at least 80, so we ensure it is at least that and otherwise use +PVNAME_STRINGSZ from EPICS base dbDefs.h */ +#define PV_NAME_LEN ((PVNAME_SZ > 80) ? (PVNAME_SZ) : (80)) /* string containing a PV name */ #define MAXSTRING 300 struct restoreFileListItem { diff --git a/asApp/src/verify.c b/asApp/src/verify.c index 0973758b..d3e45eff 100644 --- a/asApp/src/verify.c +++ b/asApp/src/verify.c @@ -17,9 +17,6 @@ #include "save_restore.h" -#ifndef PVNAME_STRINGSZ -#define PVNAME_STRINGSZ 61 /* includes terminating null */ -#endif #define PEND_TIME 5.0 #define FSMALL 1.e-6 @@ -122,6 +119,7 @@ int do_asVerify_fp(FILE *fp, int verbose, int debug, int write_restore_file, cha } while ((bp = fgets(s, BUF_SIZE, fp))) { + int name_len = 0; if (debug > 3) printf("\nasVerify: buffer '%s'\n", bp); if (bp[0] == '#') { /* A PV to which autosave could not connect, or just a comment in the file. */ @@ -130,11 +128,19 @@ int do_asVerify_fp(FILE *fp, int verbose, int debug, int write_restore_file, cha continue; } /* NOTE value_string must have room for nearly BUF_SIZE characters */ - n = sscanf(bp, "%80s%c%[^\n\r]", PVname, &c, value_string); + n = sscanf(bp, "%*s%n%c%[^\n\r]", &name_len, &c, value_string); + /* PVname can store one more character than PV_NAME_LEN. */ + if (name_len <= PV_NAME_LEN) { + strncpy(PVname, bp, name_len); + PVname[name_len] = '\0'; + } else { + strncpy(PVname, bp, PV_NAME_LEN); + PVname[PV_NAME_LEN] = '\0'; + } if (debug > 3) printf("\nasVerify: PVname='%s', value_string[%d]='%s'\n", PVname, (int)strlen(value_string), value_string); - if (n < 3) *value_string = 0; - if (strlen(PVname) >= PVNAME_STRINGSZ) { + if (n < 2) *value_string = 0; + if (strlen(PVname) >= PV_NAME_LEN + 1) { /* Impossible PV name */ if (write_restore_file) fprintf(fr, "#? %s", bp); continue;