EPICS Controls Argonne National Laboratory

Experimental Physics and
Industrial Control System

2002  2003  2004  2005  2006  2007  2008  2009  2010  2011  2012  2013  2014  <20152016  2017  2018  2019  2020  2021  2022  2023  2024  Index 2002  2003  2004  2005  2006  2007  2008  2009  2010  2011  2012  2013  2014  <20152016  2017  2018  2019  2020  2021  2022  2023  2024 
<== Date ==> <== Thread ==>

Subject: Re: Raising the 80 char limit on INP/OUT strings?
From: Michael Davidsaver <[email protected]>
To: [email protected]
Date: Wed, 08 Apr 2015 08:44:11 -0400
On 04/08/2015 08:13 AM, Michael Davidsaver wrote:
> On 04/08/2015 08:02 AM, Ralph Lange wrote:
>> ...
>> So - what to do with 3.15?
>> (I'm afraid waiting for 3.16 is not short-term enough.)
>>
>> I would opt for the simple version: make the buffer statically length 256.
> 
> Or malloc() for a temporary buffer when the static buffer is too short?

Answered my own question, and remembered why I wanted to replace this
code.  Too many return paths.

The attached patch works, but probably leaks the buffer on some code paths.
diff --git a/src/ioc/dbStatic/dbStaticLib.c b/src/ioc/dbStatic/dbStaticLib.c
index dfbf3ab..ffb01ff 100644
--- a/src/ioc/dbStatic/dbStaticLib.c
+++ b/src/ioc/dbStatic/dbStaticLib.c
@@ -2088,7 +2088,7 @@ long dbPutString(DBENTRY *pdbentry,const char *pstring)
     case DBF_FWDLINK: {
 	    DBLINK	*plink;
 	    char	string[80];
-	    char	*pstr = string;
+	    char	*palloc = NULL, *pstr = string;
 
 	    if (!pfield)
 	        return S_dbLib_fieldNotFound;
@@ -2114,12 +2114,17 @@ long dbPutString(DBENTRY *pdbentry,const char *pstring)
                     strcpy(plink->text, pstring);
 	    }
 	    if (strlen(pstring) >= sizeof(string)) {
-	        status = S_dbLib_badField;
-	        errMessage(status,
-			"dbPutString received a string that is too long");
-	        return status;
+            palloc = malloc(strlen(pstring)+1);
+            if(!palloc) {
+                status = S_dbLib_badField;
+                errMessage(status,
+                "dbPutString received a string that is too long");
+                return status;
             }
-	    strcpy(pstr, pstring);
+            strcpy(palloc, pstring);
+            pstr = palloc;
+        } else
+            strcpy(pstr, pstring);
 	    /* Strip leading blanks and tabs */
 	    while (*pstr && (*pstr == ' ' || *pstr == '\t')) pstr++;
 	    /* Strip trailing blanks and tabs */
@@ -2133,10 +2138,10 @@ long dbPutString(DBENTRY *pdbentry,const char *pstring)
 	    }
 	    if (!pstr || !*pstr) {
 		if (plink->type == PV_LINK) dbCvtLinkToConstant(pdbentry);
-		if (plink->type != CONSTANT) return S_dbLib_badField;
+		if (plink->type != CONSTANT) {status = S_dbLib_badField; goto linkcleanup;}
 		free((void *)plink->value.constantStr);
 		plink->value.constantStr = NULL;
-		goto done;
+		goto linkcleanup;
 	    }
 	    switch (plink->type) {
 	    case CONSTANT:
@@ -2162,7 +2167,7 @@ long dbPutString(DBENTRY *pdbentry,const char *pstring)
 				dbCalloc(strlen(pstr) + 1, sizeof(char));
 			}
 			strcpy(plink->value.constantStr, pstr);
-			goto done;
+			break;
 		    }
 
 		    if (plink->type==CONSTANT) dbCvtLinkToPvlink(pdbentry);
@@ -2213,18 +2218,18 @@ long dbPutString(DBENTRY *pdbentry,const char *pstring)
 			}
 		    }
 		    status = putPvLink(pdbentry,ppOpt|msOpt,pstr);
-		    goto done;
+		    break;
 		}
 		/*break; is unnecessary*/
 	    case VME_IO: {
 	    	    char	*end;
 
-		    if (!(end = strchr(pstr,'#'))) return S_dbLib_badField;
+		    if (!(end = strchr(pstr,'#'))) {status = S_dbLib_badField; break;}
 		    pstr = end + 1;
-		    if (!(end = strchr(pstr,'C'))) return S_dbLib_badField;
+		    if (!(end = strchr(pstr,'C'))) {status = S_dbLib_badField; break;}
 		    pstr = end + 1;
                     cvtDecimalOrHexToShort(pstr,&plink->value.vmeio.card);
-		    if (!(end = strchr(pstr,'S'))) return S_dbLib_badField;
+		    if (!(end = strchr(pstr,'S'))) {status = S_dbLib_badField; break;}
 		    pstr = end + 1;
                     cvtDecimalOrHexToShort(pstr, &plink->value.vmeio.signal);
 		    status = putParmString(&plink->value.vmeio.parm, pstr);
@@ -2234,15 +2239,15 @@ long dbPutString(DBENTRY *pdbentry,const char *pstring)
 	    case CAMAC_IO: {
 	    	    char	*end;
 
-		    if (!(end = strchr(pstr,'#'))) return (S_dbLib_badField);
+		    if (!(end = strchr(pstr,'#'))) {status = S_dbLib_badField; break;}
 		    pstr = end + 1;
-		    if (!(end = strchr(pstr,'B'))) return (S_dbLib_badField);
+		    if (!(end = strchr(pstr,'B'))) {status = S_dbLib_badField; break;}
 		    pstr = end + 1;
                     cvtDecimalOrHexToShort(pstr,&plink->value.camacio.b);
-		    if (!(end = strchr(pstr,'C'))) return (S_dbLib_badField);
+		    if (!(end = strchr(pstr,'C'))) {status = S_dbLib_badField; break;}
 		    pstr = end + 1;
                     cvtDecimalOrHexToShort(pstr,&plink->value.camacio.c);
-		    if (!(end = strchr(pstr,'N'))) return (S_dbLib_badField);
+		    if (!(end = strchr(pstr,'N'))) {status = S_dbLib_badField; break;}
 		    pstr = end + 1;
                     cvtDecimalOrHexToShort(pstr,&plink->value.camacio.n);
  		    if (!(end = strchr(pstr,'A')))  {
@@ -2264,18 +2269,18 @@ long dbPutString(DBENTRY *pdbentry,const char *pstring)
 	    case RF_IO: {
 	    	    char	*end;
 
-		    if(!(end = strchr(pstr,'#'))) return (S_dbLib_badField);
+		    if(!(end = strchr(pstr,'#'))) {status = S_dbLib_badField; break;}
 		    pstr = end + 1;
-		    if(!(end = strchr(pstr,'R'))) return (S_dbLib_badField);
+		    if(!(end = strchr(pstr,'R'))) {status = S_dbLib_badField; break;}
 		    pstr = end + 1;
                     cvtDecimalOrHexToShort(pstr,&plink->value.rfio.cryo);
-		    if(!(end = strchr(pstr,'M'))) return (S_dbLib_badField);
+		    if(!(end = strchr(pstr,'M'))) {status = S_dbLib_badField; break;}
 		    pstr = end + 1;
                     cvtDecimalOrHexToShort(pstr,&plink->value.rfio.micro);
-		    if(!(end = strchr(pstr,'D'))) return (S_dbLib_badField);
+		    if(!(end = strchr(pstr,'D'))) {status = S_dbLib_badField; break;}
 		    pstr = end + 1;
                     cvtDecimalOrHexToShort(pstr,&plink->value.rfio.dataset);
-		    if(!(end = strchr(pstr,'E'))) return (S_dbLib_badField);
+		    if(!(end = strchr(pstr,'E'))) {status = S_dbLib_badField; break;}
 		    pstr = end + 1;
                     cvtDecimalOrHexToShort(pstr,&plink->value.rfio.element);
 		}
@@ -2283,18 +2288,18 @@ long dbPutString(DBENTRY *pdbentry,const char *pstring)
 	    case AB_IO: {
 	    	    char	*end;
 
-		    if(!(end = strchr(pstr,'#'))) return (S_dbLib_badField);
+		    if(!(end = strchr(pstr,'#'))) {status = S_dbLib_badField; break;}
 		    pstr = end + 1;
-		    if(!(end = strchr(pstr,'L'))) return (S_dbLib_badField);
+		    if(!(end = strchr(pstr,'L'))) {status = S_dbLib_badField; break;}
 		    pstr = end + 1;
                     cvtDecimalOrHexToShort(pstr,&plink->value.abio.link);
-		    if(!(end = strchr(pstr,'A'))) return (S_dbLib_badField);
+		    if(!(end = strchr(pstr,'A'))) {status = S_dbLib_badField; break;}
 		    pstr = end + 1;
                     cvtDecimalOrHexToShort(pstr,&plink->value.abio.adapter);
-		    if(!(end = strchr(pstr,'C'))) return (S_dbLib_badField);
+		    if(!(end = strchr(pstr,'C'))) {status = S_dbLib_badField; break;}
 		    pstr = end + 1;
                     cvtDecimalOrHexToShort(pstr,&plink->value.abio.card);
-                    if(!(end = strchr(pstr,'S'))) return (S_dbLib_badField);
+                    if(!(end = strchr(pstr,'S'))) {status = S_dbLib_badField; break;}
                     pstr = end + 1;
                     cvtDecimalOrHexToShort(pstr,&plink->value.abio.signal);
                     status = putParmString(&plink->value.abio.parm,pstr);
@@ -2303,12 +2308,12 @@ long dbPutString(DBENTRY *pdbentry,const char *pstring)
             case GPIB_IO: {
                     char *end;
 
-		    if(!(end = strchr(pstr,'#'))) return (S_dbLib_badField);
+		    if(!(end = strchr(pstr,'#'))) {status = S_dbLib_badField; break;}
 		    pstr = end + 1;
-		    if(!(end = strchr(pstr,'L'))) return (S_dbLib_badField);
+		    if(!(end = strchr(pstr,'L'))) {status = S_dbLib_badField; break;}
 		    pstr = end + 1;
                     cvtDecimalOrHexToShort(pstr,&plink->value.gpibio.link);
-		    if(!(end = strchr(pstr,'A'))) return (S_dbLib_badField);
+		    if(!(end = strchr(pstr,'A'))) {status = S_dbLib_badField; break;}
 		    pstr = end + 1;
                     cvtDecimalOrHexToShort(pstr,&plink->value.gpibio.addr);
 		    status = putParmString(&plink->value.gpibio.parm,pstr);
@@ -2321,21 +2326,21 @@ long dbPutString(DBENTRY *pdbentry,const char *pstring)
 	    	    char	*end;
 		    short	tmp_val;
 
-		    if(!(end = strchr(pstr,'#'))) return (S_dbLib_badField);
+		    if(!(end = strchr(pstr,'#'))) {status = S_dbLib_badField; break;}
 		    pstr = end + 1;
-		    if(!(end = strchr(pstr,'L'))) return (S_dbLib_badField);
+		    if(!(end = strchr(pstr,'L'))) {status = S_dbLib_badField; break;}
 		    pstr = end + 1;
                     cvtDecimalOrHexToShort(pstr,&tmp_val);
 		    plink->value.bitbusio.link=(unsigned char)tmp_val;
-		    if(!(end = strchr(pstr,'N'))) return (S_dbLib_badField);
+		    if(!(end = strchr(pstr,'N'))) {status = S_dbLib_badField; break;}
 		    pstr = end + 1;
                     cvtDecimalOrHexToShort(pstr,&tmp_val);
 		    plink->value.bitbusio.node=(unsigned char)tmp_val;
-		    if(!(end = strchr(pstr,'P'))) return (S_dbLib_badField);
+		    if(!(end = strchr(pstr,'P'))) {status = S_dbLib_badField; break;}
 		    pstr = end + 1;
                     cvtDecimalOrHexToShort(pstr,&tmp_val);
 		    plink->value.bitbusio.port=(unsigned char)tmp_val;
-		    if(!(end = strchr(pstr,'S'))) return (S_dbLib_badField);
+		    if(!(end = strchr(pstr,'S'))) {status = S_dbLib_badField; break;}
 		    pstr = end + 1;
                     cvtDecimalOrHexToShort(pstr,&tmp_val);
 		    plink->value.bitbusio.signal=(unsigned char)tmp_val;
@@ -2349,17 +2354,17 @@ long dbPutString(DBENTRY *pdbentry,const char *pstring)
 	    	    char	*end;
 		    short	tmp_val;
 
-		    if(!(end = strchr(pstr,'#'))) return (S_dbLib_badField);
+		    if(!(end = strchr(pstr,'#'))) {status = S_dbLib_badField; break;}
 		    pstr = end + 1;
-		    if(!(end = strchr(pstr,'L'))) return (S_dbLib_badField);
+		    if(!(end = strchr(pstr,'L'))) {status = S_dbLib_badField; break;}
 		    pstr = end + 1;
                     cvtDecimalOrHexToShort(pstr,&tmp_val);
 		    plink->value.bbgpibio.link=(unsigned char)tmp_val;
-		    if(!(end = strchr(pstr,'B'))) return (S_dbLib_badField);
+		    if(!(end = strchr(pstr,'B'))) {status = S_dbLib_badField; break;}
 		    pstr = end + 1;
                     cvtDecimalOrHexToShort(pstr,&tmp_val);
 		    plink->value.bbgpibio.bbaddr=(unsigned char)tmp_val;
-		    if(!(end = strchr(pstr,'G'))) return (S_dbLib_badField);
+		    if(!(end = strchr(pstr,'G'))) {status = S_dbLib_badField; break;}
 		    pstr = end + 1;
                     cvtDecimalOrHexToShort(pstr,&tmp_val);
             plink->value.bbgpibio.gpibaddr=(unsigned char)tmp_val;
@@ -2369,21 +2374,21 @@ long dbPutString(DBENTRY *pdbentry,const char *pstring)
 	    case VXI_IO: {
 	    	    char	*end;
 
-		    if(!(end = strchr(pstr,'#'))) return (S_dbLib_badField);
+		    if(!(end = strchr(pstr,'#'))) {status = S_dbLib_badField; break;}
 		    pstr = end + 1;
 		    memset((char *)&plink->value.vxiio,0,sizeof(struct  vxiio));
 		    plink->value.vxiio.parm = pNullString;
 		    if(!((end = strchr(pstr,'C'))&&(end < strchr(pstr,'@')) )) {
 			plink->value.vxiio.flag = VXISTATIC;
-		        if(!(end = strchr(pstr,'V'))) return (S_dbLib_badField);
+		        if(!(end = strchr(pstr,'V'))) {status = S_dbLib_badField; break;}
 		        pstr = end + 1;
                         cvtDecimalOrHexToShort(pstr,&plink->value.vxiio.la);
 		    } else {
 			plink->value.vxiio.flag = VXIDYNAMIC;
-		        if(!(end = strchr(pstr,'V'))) return (S_dbLib_badField);
+		        if(!(end = strchr(pstr,'V'))) {status = S_dbLib_badField; break;}
 		        pstr = end + 1;
                         cvtDecimalOrHexToShort(pstr,&plink->value.vxiio.frame);
-		        if(!(end = strchr(pstr,'C'))) return (S_dbLib_badField);
+		        if(!(end = strchr(pstr,'C'))) {status = S_dbLib_badField; break;}
 		        pstr = end + 1;
                         cvtDecimalOrHexToShort(pstr,&plink->value.vxiio.slot);
 		    }
@@ -2401,10 +2406,13 @@ long dbPutString(DBENTRY *pdbentry,const char *pstring)
 		}
 		break;
 	    }
+linkcleanup:
+    free(palloc);
 	}
 	break;
     default:
-	return S_dbLib_badField;
+    status = S_dbLib_badField;
+	break;
     }
 done:
     if (!status && strcmp(pflddes->name, "VAL") == 0) {

References:
Raising the 80 char limit on INP/OUT strings? Ralph Lange
Re: Raising the 80 char limit on INP/OUT strings? Ralph Lange
Re: Raising the 80 char limit on INP/OUT strings? Michael Davidsaver

Navigate by Date:
Prev: Re: Raising the 80 char limit on INP/OUT strings? Michael Davidsaver
Next: Re: Raising the 80 char limit on INP/OUT strings? Ralph Lange
Index: 2002  2003  2004  2005  2006  2007  2008  2009  2010  2011  2012  2013  2014  <20152016  2017  2018  2019  2020  2021  2022  2023  2024 
Navigate by Thread:
Prev: Re: Raising the 80 char limit on INP/OUT strings? Michael Davidsaver
Next: Re: Raising the 80 char limit on INP/OUT strings? Ralph Lange
Index: 2002  2003  2004  2005  2006  2007  2008  2009  2010  2011  2012  2013  2014  <20152016  2017  2018  2019  2020  2021  2022  2023  2024 
ANJ, 16 Dec 2015 Valid HTML 4.01! · Home · News · About · Base · Modules · Extensions · Distributions · Download ·
· Search · EPICS V4 · IRMIS · Talk · Bugs · Documents · Links · Licensing ·