ws2_32: Fix hostent memory allocation.
This commit is contained in:
parent
524a817195
commit
b2af5e1d31
@ -326,7 +326,7 @@ static INT num_startup; /* reference counter */
|
|||||||
static FARPROC blocking_hook = (FARPROC)WSA_DefaultBlockingHook;
|
static FARPROC blocking_hook = (FARPROC)WSA_DefaultBlockingHook;
|
||||||
|
|
||||||
/* function prototypes */
|
/* function prototypes */
|
||||||
static struct WS_hostent *WS_create_he(char *name, int aliases, int addresses, int fill_addresses);
|
static struct WS_hostent *WS_create_he(char *name, int aliases, int aliases_size, int addresses, int address_length);
|
||||||
static struct WS_hostent *WS_dup_he(const struct hostent* p_he);
|
static struct WS_hostent *WS_dup_he(const struct hostent* p_he);
|
||||||
static struct WS_protoent *WS_dup_pe(const struct protoent* p_pe);
|
static struct WS_protoent *WS_dup_pe(const struct protoent* p_pe);
|
||||||
static struct WS_servent *WS_dup_se(const struct servent* p_se);
|
static struct WS_servent *WS_dup_se(const struct servent* p_se);
|
||||||
@ -4557,7 +4557,7 @@ static struct WS_hostent* WS_get_local_ips( char *hostname )
|
|||||||
/* Allocate a hostent and enough memory for all the IPs,
|
/* Allocate a hostent and enough memory for all the IPs,
|
||||||
* including the NULL at the end of the list.
|
* including the NULL at the end of the list.
|
||||||
*/
|
*/
|
||||||
hostlist = WS_create_he(hostname, 1, numroutes+1, TRUE);
|
hostlist = WS_create_he(hostname, 1, 0, numroutes+1, sizeof(struct in_addr));
|
||||||
if (hostlist == NULL)
|
if (hostlist == NULL)
|
||||||
goto cleanup; /* Failed to allocate a hostent for the list of IPs */
|
goto cleanup; /* Failed to allocate a hostent for the list of IPs */
|
||||||
hostlist->h_addr_list[numroutes] = NULL; /* NULL-terminate the address list */
|
hostlist->h_addr_list[numroutes] = NULL; /* NULL-terminate the address list */
|
||||||
@ -5581,54 +5581,51 @@ static int list_dup(char** l_src, char** l_to, int item_size)
|
|||||||
*
|
*
|
||||||
* Creates the entry with enough memory for the name, aliases
|
* Creates the entry with enough memory for the name, aliases
|
||||||
* addresses, and the address pointers. Also copies the name
|
* addresses, and the address pointers. Also copies the name
|
||||||
* and sets up all the pointers. If "fill_addresses" is set then
|
* and sets up all the pointers.
|
||||||
* sufficient memory for the addresses is also allocated and the
|
|
||||||
* address pointers are set to this memory.
|
|
||||||
*
|
*
|
||||||
* NOTE: The alias and address lists must be allocated with room
|
* NOTE: The alias and address lists must be allocated with room
|
||||||
* for the NULL item terminating the list. This is true even if
|
* for the NULL item terminating the list. This is true even if
|
||||||
* the list has no items ("aliases" and "addresses" must be
|
* the list has no items ("aliases" and "addresses" must be
|
||||||
* at least "1", a truly empty list is invalid).
|
* at least "1", a truly empty list is invalid).
|
||||||
*/
|
*/
|
||||||
static struct WS_hostent *WS_create_he(char *name, int aliases, int addresses, int fill_addresses)
|
static struct WS_hostent *WS_create_he(char *name, int aliases, int aliases_size, int addresses, int address_length)
|
||||||
{
|
{
|
||||||
struct WS_hostent *p_to;
|
struct WS_hostent *p_to;
|
||||||
char *p;
|
char *p;
|
||||||
|
|
||||||
int size = (sizeof(struct WS_hostent) +
|
int size = (sizeof(struct WS_hostent) +
|
||||||
strlen(name) + 1 +
|
strlen(name) + 1 +
|
||||||
sizeof(char *) * aliases +
|
sizeof(char *) * aliases +
|
||||||
sizeof(char *)*addresses);
|
aliases_size +
|
||||||
|
sizeof(char *) * addresses +
|
||||||
/* Allocate enough memory for the addresses */
|
address_length * (addresses - 1)), i;
|
||||||
if (fill_addresses)
|
|
||||||
size += sizeof(struct in_addr)*addresses;
|
|
||||||
|
|
||||||
if (!(p_to = check_buffer_he(size))) return NULL;
|
if (!(p_to = check_buffer_he(size))) return NULL;
|
||||||
memset(p_to, 0, size);
|
memset(p_to, 0, size);
|
||||||
|
|
||||||
|
/* Use the memory in the same way winsock does.
|
||||||
|
* First set the pointer for aliases, second set the pointers for addressess.
|
||||||
|
* Third fill the addresses indexes, fourth jump aliases names size.
|
||||||
|
* Fifth fill the hostname.
|
||||||
|
* NOTE: This method is valid for OS version's >= XP.
|
||||||
|
*/
|
||||||
p = (char *)(p_to + 1);
|
p = (char *)(p_to + 1);
|
||||||
p_to->h_name = p;
|
|
||||||
strcpy(p, name);
|
|
||||||
p += strlen(p) + 1;
|
|
||||||
|
|
||||||
p_to->h_aliases = (char **)p;
|
p_to->h_aliases = (char **)p;
|
||||||
p += sizeof(char *)*aliases;
|
p += sizeof(char *)*aliases;
|
||||||
|
|
||||||
p_to->h_addr_list = (char **)p;
|
p_to->h_addr_list = (char **)p;
|
||||||
p += sizeof(char *)*addresses;
|
p += sizeof(char *)*addresses;
|
||||||
if (fill_addresses)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
/* NOTE: h_aliases must be filled in manually, leave these
|
for (i = 0, addresses--; i < addresses; i++, p += address_length)
|
||||||
* pointers NULL (already set to NULL by memset earlier).
|
p_to->h_addr_list[i] = p;
|
||||||
|
|
||||||
|
/* NOTE: h_aliases must be filled in manually because we don't know each string
|
||||||
|
* size, leave these pointers NULL (already set to NULL by memset earlier).
|
||||||
*/
|
*/
|
||||||
|
p += aliases_size;
|
||||||
|
|
||||||
|
p_to->h_name = p;
|
||||||
|
strcpy(p, name);
|
||||||
|
|
||||||
/* Fill in the list of address pointers */
|
|
||||||
for (i = 0; i < addresses; i++)
|
|
||||||
p_to->h_addr_list[i] = (p += sizeof(struct in_addr));
|
|
||||||
p += sizeof(struct in_addr);
|
|
||||||
}
|
|
||||||
return p_to;
|
return p_to;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -5638,18 +5635,30 @@ static struct WS_hostent *WS_create_he(char *name, int aliases, int addresses, i
|
|||||||
*/
|
*/
|
||||||
static struct WS_hostent *WS_dup_he(const struct hostent* p_he)
|
static struct WS_hostent *WS_dup_he(const struct hostent* p_he)
|
||||||
{
|
{
|
||||||
int addresses = list_size(p_he->h_addr_list, p_he->h_length);
|
int i, addresses = 0, alias_size = 0;
|
||||||
int aliases = list_size(p_he->h_aliases, 0);
|
|
||||||
struct WS_hostent *p_to;
|
struct WS_hostent *p_to;
|
||||||
|
char *p;
|
||||||
|
|
||||||
p_to = WS_create_he(p_he->h_name, aliases, addresses, FALSE);
|
for( i = 0; p_he->h_aliases[i]; i++) alias_size += strlen(p_he->h_aliases[i]) + 1;
|
||||||
|
while (p_he->h_addr_list[addresses]) addresses++;
|
||||||
|
|
||||||
|
p_to = WS_create_he(p_he->h_name, i + 1, alias_size, addresses + 1, p_he->h_length);
|
||||||
|
|
||||||
if (!p_to) return NULL;
|
if (!p_to) return NULL;
|
||||||
p_to->h_addrtype = p_he->h_addrtype;
|
p_to->h_addrtype = p_he->h_addrtype;
|
||||||
p_to->h_length = p_he->h_length;
|
p_to->h_length = p_he->h_length;
|
||||||
|
|
||||||
list_dup(p_he->h_aliases, p_to->h_aliases, 0);
|
for(i = 0, p = p_to->h_addr_list[0]; p_he->h_addr_list[i]; i++, p += p_to->h_length)
|
||||||
list_dup(p_he->h_addr_list, p_to->h_addr_list, p_he->h_length);
|
memcpy(p, p_he->h_addr_list[i], p_to->h_length);
|
||||||
|
|
||||||
|
/* Fill the aliases after the IP data */
|
||||||
|
for(i = 0; p_he->h_aliases[i]; i++)
|
||||||
|
{
|
||||||
|
p_to->h_aliases[i] = p;
|
||||||
|
strcpy(p, p_he->h_aliases[i]);
|
||||||
|
p += strlen(p) + 1;
|
||||||
|
}
|
||||||
|
|
||||||
return p_to;
|
return p_to;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2759,22 +2759,22 @@ static void test_dns(void)
|
|||||||
addr.mem = h + 1;
|
addr.mem = h + 1;
|
||||||
if(h->h_addr_list == addr.mem) /* <= W2K */
|
if(h->h_addr_list == addr.mem) /* <= W2K */
|
||||||
{
|
{
|
||||||
skip("Skipping hostent tests since this OS is unsupported\n");
|
win_skip("Skipping hostent tests since this OS is unsupported\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
todo_wine ok(h->h_aliases == addr.mem,
|
ok(h->h_aliases == addr.mem,
|
||||||
"hostent->h_aliases should be in %p, it is in %p\n", addr.mem, h->h_aliases);
|
"hostent->h_aliases should be in %p, it is in %p\n", addr.mem, h->h_aliases);
|
||||||
|
|
||||||
for(ptr = h->h_aliases, acount = 1; *ptr; ptr++) acount++;
|
for(ptr = h->h_aliases, acount = 1; *ptr; ptr++) acount++;
|
||||||
addr.chr += sizeof(*ptr) * acount;
|
addr.chr += sizeof(*ptr) * acount;
|
||||||
todo_wine ok(h->h_addr_list == addr.mem,
|
ok(h->h_addr_list == addr.mem,
|
||||||
"hostent->h_addr_list should be in %p, it is in %p\n", addr.mem, h->h_addr_list);
|
"hostent->h_addr_list should be in %p, it is in %p\n", addr.mem, h->h_addr_list);
|
||||||
|
|
||||||
for(ptr = h->h_addr_list, acount = 1; *ptr; ptr++) acount++;
|
for(ptr = h->h_addr_list, acount = 1; *ptr; ptr++) acount++;
|
||||||
|
|
||||||
addr.chr += sizeof(*ptr) * acount;
|
addr.chr += sizeof(*ptr) * acount;
|
||||||
todo_wine ok(h->h_addr_list[0] == addr.mem,
|
ok(h->h_addr_list[0] == addr.mem,
|
||||||
"hostent->h_addr_list[0] should be in %p, it is in %p\n", addr.mem, h->h_addr_list[0]);
|
"hostent->h_addr_list[0] should be in %p, it is in %p\n", addr.mem, h->h_addr_list[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user