Welcome to mirror list, hosted at ThFree Co, Russian Federation.

cygwin.com/git/newlib-cygwin.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeff Johnston <jjohnstn@redhat.com>2008-07-02 22:17:48 +0400
committerJeff Johnston <jjohnstn@redhat.com>2008-07-02 22:17:48 +0400
commita9f7d0a7a7b134004b92092831bdefc6faf8213c (patch)
tree296ca87b94d60e11219f80a7c1ffaf726a14086d /newlib/libc
parentbb82bbe6ff1e97b1e2baba9436676aa9406fcef3 (diff)
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.
Diffstat (limited to 'newlib/libc')
-rw-r--r--newlib/libc/machine/mips/strncpy.c20
1 files changed, 20 insertions, 0 deletions
diff --git a/newlib/libc/machine/mips/strncpy.c b/newlib/libc/machine/mips/strncpy.c
index a2ceb2c77..324c45209 100644
--- a/newlib/libc/machine/mips/strncpy.c
+++ b/newlib/libc/machine/mips/strncpy.c
@@ -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));