OSDN Git Service

2008-07-02 Jeff Johnston <jjohnstn@redhat.com>
authorjjohnstn <jjohnstn>
Wed, 2 Jul 2008 18:17:47 +0000 (18:17 +0000)
committerjjohnstn <jjohnstn>
Wed, 2 Jul 2008 18:17:47 +0000 (18:17 +0000)
        * libc/machine/mips/strncpy.c (strncpy): Fix logic so unaligned
        source data is taken care of before loop unrolling.

newlib/ChangeLog
newlib/libc/machine/mips/strncpy.c

index bc11fe1..1b24d01 100644 (file)
@@ -1,3 +1,8 @@
+2008-07-02  Jeff Johnston  <jjohnstn@redhat.com>
+
+       * libc/machine/mips/strncpy.c (strncpy): Fix logic so unaligned
+       source data is taken care of before loop unrolling.
+
 2008-06-25  Hans-Peter Nilsson  <hp@axis.com>
 
        Fix strict-aliasing issues with _strtod_r and Storeinc.
index a2ceb2c..324c452 100644 (file)
@@ -82,6 +82,26 @@ strncpy (char *dst0, const char *src0, size_t count)
 
   dst = (unsigned char *)dst0;
   src = (unsigned const char *)src0;
+  /* Take care of any odd bytes in the source data because we
+   * want to unroll where we read ahead 2 or 4 bytes at a time and then
+   * check each byte for the null terminator.  This can result in
+   * a segfault for the case where the source pointer is unaligned,
+   * the null terminator is in valid memory, but reading 2 or 4 bytes at a
+   * time blindly eventually goes outside of valid memory. */
+  while ((src & (UNROLL_FACTOR - 1)) != 0 && count > 0)
+    {
+      *dst++ = ch = *src++;
+      --count;
+      if (ch == '\0')
+       {
+          end = dst + count;
+         while (dst != end)
+           *dst++ = '\0';
+
+         return dst0;
+       }
+    }
+
   if (__builtin_expect (count >= 4, 1))
     {
       odd_bytes = (count & (UNROLL_FACTOR - 1));