dthelp: Avoid undefined behaviour in strcpy
authorFrederic Koehler <f.koehler427@gmail.com>
Fri, 28 Sep 2012 18:21:12 +0000 (14:21 -0400)
committerJon Trulson <jon@radscan.com>
Sun, 30 Sep 2012 01:21:27 +0000 (19:21 -0600)
Technically strcpy's ranges cannot overlap at all,
although in practice this is usually not an issue.
Does quiet a valgrind warning, however.

cde/lib/DtHelp/FormatSDL.c

index d5fa31eee9a9b9e06bb070d5b5797651645e1500..e64072d0b5d970449d318d9c0f0c4877ca7d49fc 100644 (file)
@@ -4354,6 +4354,13 @@ FindSnbEntry(
     return NULL;
 }
 
+/* A little helper function, acts like strcpy
+ * but safe for overlapping regions.
+ */
+static void *strmove(void *dest, const void *src) {
+    memmove(dest, src, strlen(src) + 1);
+}
+
 /******************************************************************************
  * Function:    static int ProcessString(string, int idx);
  *
@@ -4391,7 +4398,7 @@ ProcessString(
 
     if (cpy_str == True)
       {
-        strcpy (string, &string[*idx+1]);
+        strmove (string, &string[*idx+1]);
         *idx = -1;
       }
     return 0;
@@ -4451,7 +4458,7 @@ CompressLinkSeg(
             * the string.
             */
            if (_DtCvIsSegRegChar(p_seg))
-               strcpy(((char *)pChar), &(((char *)pChar)[1]));
+               strmove(((char *)pChar), &(((char *)pChar)[1]));
            else
              {
                int i;
@@ -4496,7 +4503,7 @@ ProcessNonBreakChar(
         return -1;
 
     my_struct->flags = my_struct->flags & ~(_DtCvNON_BREAK);
-    strcpy (string, &string[*idx+1]);
+    strmove (string, &string[*idx+1]);
     *idx = -1;
     return 0;
 }
@@ -6983,6 +6990,7 @@ OnlyOneEach(
 
 } /* End OnlyOneEach */
 
+
 /******************************************************************************
  * Function:    int Cdata (FormatStruct my_struct,
  *                                     int cur_element, exceptions);
@@ -7063,7 +7071,7 @@ Cdata(
     
                 if (string[i] == '&')
                   {
-                    strcpy (&string[i], &string[i+1]);
+                    strmove (&string[i], &string[i+1]);
                     if (string[i] == '\0')
                       {
                         string[i] = BufFileGet(my_struct->my_file);
@@ -7154,7 +7162,7 @@ Cdata(
                         * and copy the rest of the string to after it.
                         */
                        string[j-1] = (char) value;
-                        strcpy (&string[j], &string[i]);
+                        strmove (&string[j], &string[i]);
                        i = j;
                      }
 
@@ -7194,7 +7202,7 @@ Cdata(
                         if (my_struct->last_was_space == False)
                            my_struct->last_was_nl = True;
 
-                        strcpy (&string[i], &string[i+1]);
+                        strmove (&string[i], &string[i+1]);
                       }
                     else
                       {
@@ -7208,7 +7216,7 @@ Cdata(
                             return -1;
                           }
     
-                        strcpy (string, &string[i+1]);
+                        strmove (string, &string[i+1]);
                         i = 0;
                       }
                   }
@@ -7217,7 +7225,7 @@ Cdata(
                     if (False == my_struct->save_blank &&
                        type != SdlTypeLiteral && type != SdlTypeUnlinedLiteral
                                        && my_struct->last_was_space == True)
-                        strcpy (&string[i], &string[i+1]);
+                        strmove (&string[i], &string[i+1]);
                     else
                         i++;
                     my_struct->last_was_space = True;
@@ -7242,7 +7250,7 @@ Cdata(
                    else /* the last was a multibyte character, tighten up */
                      {
                        i--;
-                       strcpy (&string[i], &string[i+1]);
+                       strmove (&string[i], &string[i+1]);
                      }
                  }