From edff491c30e342564388d6f6a4086af4336a9870 Mon Sep 17 00:00:00 2001
From: Hamish Morrison <hamish@lavabit.com>
Date: Sun, 22 Apr 2012 01:31:08 +0100
Subject: [PATCH] strncpy: pad the destination with NULs
And optimize for word aligned loads/stores
---
src/system/libroot/posix/string/strncpy.c | 51 ++++++++++++++++++++++++++---
1 files changed, 46 insertions(+), 5 deletions(-)
diff --git a/src/system/libroot/posix/string/strncpy.c b/src/system/libroot/posix/string/strncpy.c
index ff3b159..362da9d 100644
a
|
b
|
|
5 | 5 | |
6 | 6 | #include <sys/types.h> |
7 | 7 | #include <string.h> |
| 8 | #include <SupportDefs.h> |
8 | 9 | |
9 | 10 | |
10 | | char * |
11 | | strncpy(char *dest, char const *src, size_t count) |
| 11 | /* From Bit twiddling hacks: |
| 12 | http://graphics.stanford.edu/~seander/bithacks.html */ |
| 13 | #define LACKS_ZERO_BYTE(value) \ |
| 14 | (((value - 0x01010101) & ~value & 0x80808080) == 0) |
| 15 | |
| 16 | |
| 17 | char* |
| 18 | strncpy(char* dest, const char* src, size_t count) |
12 | 19 | { |
13 | | char *tmp = dest; |
| 20 | char* tmp = dest; |
| 21 | |
| 22 | // Align destination buffer for four byte writes. |
| 23 | while (((addr_t)dest & 3) != 0 && count != 0) { |
| 24 | count--; |
| 25 | if ((*dest++ = *src++) == '\0') { |
| 26 | memset(dest, '\0', count); |
| 27 | return tmp; |
| 28 | } |
| 29 | } |
| 30 | |
| 31 | if (count == 0) |
| 32 | return tmp; |
| 33 | |
| 34 | if (((addr_t)src & 3) == 0) { |
| 35 | // If the source and destination are aligned, copy a word |
| 36 | // word at a time |
| 37 | uint32* alignedSrc = (uint32*)src; |
| 38 | uint32* alignedDest = (uint32*)dest; |
| 39 | size_t alignedCount = count / 4; |
| 40 | count -= alignedCount * 4; |
| 41 | |
| 42 | for (; alignedCount != 0 && LACKS_ZERO_BYTE(*alignedSrc); |
| 43 | alignedCount--) |
| 44 | *alignedDest++ = *alignedSrc++; |
| 45 | |
| 46 | count += alignedCount * 4; |
| 47 | src = (char*)alignedSrc; |
| 48 | dest = (char*)alignedDest; |
| 49 | } |
14 | 50 | |
15 | | while (count-- && (*dest++ = *src++) != '\0') |
16 | | ; |
| 51 | // Deal with the remainder. |
| 52 | while (count-- != 0) { |
| 53 | if ((*dest++ = *src++) == '\0') { |
| 54 | memset(dest, '\0', count); |
| 55 | return tmp; |
| 56 | } |
| 57 | } |
17 | 58 | |
18 | 59 | return tmp; |
19 | 60 | } |