aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/hostip.c23
1 files changed, 14 insertions, 9 deletions
diff --git a/lib/hostip.c b/lib/hostip.c
index a6e77170a..b77f70421 100644
--- a/lib/hostip.c
+++ b/lib/hostip.c
@@ -154,12 +154,11 @@ Curl_addrinfo *Curl_getaddrinfo(struct SessionHandle *data,
#ifndef HAVE_GETHOSTBYNAME_R
/**
- * Performs a "deep" copy of a hostent into a buffer
- * (returns a pointer to the copy).
+ * Performs a "deep" copy of a hostent into a buffer (returns a pointer to the
+ * copy). Make absolutely sure the destination buffer is big enough!
*
* Keith McGuigan
- * 10/3/2001
- */
+ * 10/3/2001 */
static struct hostent* pack_hostent(char* buf, struct hostent* orig)
{
char* bufptr;
@@ -178,7 +177,11 @@ static struct hostent* pack_hostent(char* buf, struct hostent* orig)
strncpy(bufptr, orig->h_name, len);
bufptr += len;
- copy->h_aliases = (char**)bufptr;
+ /* we align on even 64bit boundaries for safety */
+#define MEMALIGN(x) (((unsigned long)(x)&0xfffffff8)+8)
+
+ /* This must be aligned properly to work on many CPU architectures! */
+ copy->h_aliases = (char**)MEMALIGN(bufptr);
/* Figure out how many aliases there are */
for (i = 0; orig->h_aliases[i] != NULL; ++i);
@@ -186,20 +189,22 @@ static struct hostent* pack_hostent(char* buf, struct hostent* orig)
/* Reserve room for the array */
bufptr += (i + 1) * sizeof(char*);
- i = 0;
- str = orig->h_aliases[i];
- while (str != NULL) {
+ /* Clone all known aliases */
+ for(i = 0; (str = orig->h_aliases[i]); i++) {
len = strlen(str) + 1;
strncpy(bufptr, str, len);
copy->h_aliases[i] = bufptr;
bufptr += len;
- str = orig->h_aliases[++i];
}
+ /* Terminate the alias list with a NULL */
copy->h_aliases[i] = NULL;
copy->h_addrtype = orig->h_addrtype;
copy->h_length = orig->h_length;
+ /* align it for (at least) 32bit accesses */
+ bufptr = (char *)MEMALIGN(bufptr);
+
copy->h_addr_list = (char**)bufptr;
/* Figure out how many addresses there are */