More strcpy() strcat() sprintf() squashing
[fw/sdcc] / src / SDCCmacro.c
index eb2b49c107229aa515cd3b35daccb2bc779f5855..9691c0bdce6d5f5f1d879feabddd69f6fc0a3d06 100644 (file)
 
 enum 
   {
-    MAX_STRING_LENGTH  = PATH_MAX,
+    MAX_STRING_LENGTH    = 2048,
     MAX_MACRO_NAME_LENGTH = 128
   };
 
 void
-_evalMacros(char *apinto, hTab *pvals, const char *pfrom)
+_evalMacros(char *apinto, hTab *pvals, const char *pfrom, size_t alen)
 {
-  bool fdidsomething = FALSE;
-  char *pinto = apinto;
+  bool  fdidsomething = FALSE;
+  char  *pinto = apinto;
+  size_t plen = alen;
 
-  assert(pinto && pvals && pfrom);
+  assert(pinto);
+  assert(pvals);
+  assert(pfrom);
 
-  while (*pfrom)
+  while (plen && *pfrom)
     {
       if (*pfrom == '{')
         {
@@ -55,6 +58,11 @@ _evalMacros(char *apinto, hTab *pvals, const char *pfrom)
               wassertl(0, "Unterminated macro expansion");
             }
           /* Pull out the macro name */
+         if (pend - pfrom >= MAX_MACRO_NAME_LENGTH)
+         {
+             wassertl(0, "macro name too long");
+         }
+           
           strncpy(name, pfrom, pend-pfrom);
           name[pend-pfrom] = '\0';
 
@@ -68,8 +76,9 @@ _evalMacros(char *apinto, hTab *pvals, const char *pfrom)
             }
 
           /* Replace */
-          strcpy(pinto, pval);
+          strncpy(pinto, pval, plen);
           pinto += strlen(pval);
+         plen -= plen > strlen(pval) ? strlen(pval) : plen;
           fdidsomething = TRUE;
 
           pfrom = pend+1;
@@ -78,17 +87,23 @@ _evalMacros(char *apinto, hTab *pvals, const char *pfrom)
         {
           /* Pass through */
           *pinto++ = *pfrom++;
+         plen--;
         }
     }
 
+  if (!plen)
+  {
+      wassertl(0, "macro expansion too long");
+  }
+    
   *pinto = '\0';
 
   /* If we did something then recursivly expand any expanded macros */
   if (fdidsomething)
     {
       char ainto[MAX_STRING_LENGTH];
-      _evalMacros(ainto, pvals, apinto);
-      strcpy(apinto, ainto);
+      _evalMacros(ainto, pvals, apinto, MAX_STRING_LENGTH);
+      strncpyz(apinto, ainto, alen);
     }
 }
 
@@ -99,11 +114,28 @@ mvsprintf(hTab *pvals, const char *pformat, va_list ap)
   char atmp[MAX_STRING_LENGTH];
 
   /* Recursivly evaluate all the macros in the string */
-  _evalMacros(ainto, pvals, pformat);
+  _evalMacros(ainto, pvals, pformat, MAX_STRING_LENGTH);
   /* Evaluate all the arguments */
-  vsprintf(atmp, ainto, ap);
+#if defined(HAVE_VSNPRINTF)
+    if (vsnprintf(atmp, MAX_STRING_LENGTH, ainto, ap) >= MAX_STRING_LENGTH)
+    {
+       fprintf(stderr, "Internal error: mvsprintf output truncated.\n");
+    }
+#else    
+    {  
+       int wlen; 
+       
+       wlen = vsprintf(atmp, ainto, ap);
+       
+       if (wlen < 0 || wlen >= MAX_STRING_LENGTH)
+       {
+           wassertl(0, "mvsprintf overflowed.");
+       }
+    }
+#endif    
+    
   /* Recursivly evaluate any macros that were used as arguments */
-  _evalMacros(ainto, pvals, atmp);
+  _evalMacros(ainto, pvals, atmp, MAX_STRING_LENGTH);
 
   /* Return a copy of the evaluated string. */
   return Safe_strdup(ainto);
@@ -122,3 +154,19 @@ char *msprintf(hTab *pvals, const char *pformat, ...)
 
   return pret;
 }
+
+void
+mfprintf(FILE *fp, hTab *pvals, const char *pformat, ...)
+{
+  va_list ap;
+  char *p;
+
+  va_start(ap, pformat);
+
+  p = mvsprintf(pvals, pformat, ap);
+
+  va_end(ap);
+
+  fputs(p, fp);
+  Safe_free(p);
+}