From 0d213e206fa7fc82b26e273ff509441e4860c534 Mon Sep 17 00:00:00 2001
From: Frederic Koehler <f.koehler427@gmail.com>
Date: Fri, 28 Sep 2012 14:21:12 -0400
Subject: [PATCH 1/2] dthelp: Avoid undefined behaviour in strcpy

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 | 26 +++++++++++++++++---------
 1 file changed, 17 insertions(+), 9 deletions(-)

diff --git a/cde/lib/DtHelp/FormatSDL.c b/cde/lib/DtHelp/FormatSDL.c
index d5fa31e..e64072d 100644
--- a/cde/lib/DtHelp/FormatSDL.c
+++ b/cde/lib/DtHelp/FormatSDL.c
@@ -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]);
 		      }
 		  }
 
-- 
1.7.11.4

