diff options
-rw-r--r-- | ChangeLog | 5 | ||||
-rw-r--r-- | nis/nss_nisplus/nisplus-hosts.c | 88 |
2 files changed, 49 insertions, 44 deletions
@@ -1,3 +1,8 @@ +2006-04-15 Ulrich Drepper <drepper@redhat.com> + + * nis/nss_nisplus/nisplus-hosts.c (_nss_nisplus_parse_hostent): + Significant cleanups. Correct adjustment for pointer array. + 2006-04-14 Ulrich Drepper <drepper@redhat.com> * sysdeps/unix/sysv/linux/syscalls.list: Add tee syscall. diff --git a/nis/nss_nisplus/nisplus-hosts.c b/nis/nss_nisplus/nisplus-hosts.c index bf002d6..023e18f 100644 --- a/nis/nss_nisplus/nisplus-hosts.c +++ b/nis/nss_nisplus/nisplus-hosts.c @@ -36,15 +36,16 @@ static nis_result *result; static nis_name tablename_val; static u_long tablename_len; -#define NISENTRYVAL(idx,col,res) \ - ((res)->objects.objects_val[(idx)].EN_data.en_cols.en_cols_val[(col)].ec_value.ec_value_val) +#define NISENTRYVAL(idx, col, res) \ + (NIS_RES_OBJECT (res)[idx].EN_data.en_cols.en_cols_val[col].ec_value.ec_value_val) -#define NISENTRYLEN(idx,col,res) \ - ((res)->objects.objects_val[(idx)].EN_data.en_cols.en_cols_val[(col)].ec_value.ec_value_len) +#define NISENTRYLEN(idx, col, res) \ + (NIS_RES_OBJECT (res)[idx].EN_data.en_cols.en_cols_val[col].ec_value.ec_value_len) /* Get implementation for some internal functions. */ #include <resolv/mapv4v6addr.h> + static int _nss_nisplus_parse_hostent (nis_result *result, int af, struct hostent *host, char *buffer, size_t buflen, int *errnop, @@ -53,27 +54,26 @@ _nss_nisplus_parse_hostent (nis_result *result, int af, struct hostent *host, unsigned int i; char *first_unused = buffer; size_t room_left = buflen; - char *data, *p, *line; if (result == NULL) return 0; if ((result->status != NIS_SUCCESS && result->status != NIS_S_SUCCESS) || - __type_of (result->objects.objects_val) != NIS_ENTRY_OBJ || - strcmp(result->objects.objects_val[0].EN_data.en_type, - "hosts_tbl") != 0 || - result->objects.objects_val[0].EN_data.en_cols.en_cols_len < 4) + __type_of (NIS_RES_OBJECT (result)) != NIS_ENTRY_OBJ || + strcmp(NIS_RES_OBJECT (result)[0].EN_data.en_type, "hosts_tbl") != 0 || + NIS_RES_OBJECT (result)[0].EN_data.en_cols.en_cols_len < 4) return 0; - if (room_left < NISENTRYLEN (0, 2, result) + 1) + char *data = first_unused; + + if (room_left < (af == AF_INET6 || (flags & AI_V4MAPPED) != 0 + ? IN6ADDRSZ : INADDRSZ)) { no_more_room: *errnop = ERANGE; return -1; } - data = first_unused; - /* Parse address. */ if (af == AF_INET && inet_pton (af, NISENTRYVAL (0, 2, result), data) > 0) { @@ -99,51 +99,53 @@ _nss_nisplus_parse_hostent (nis_result *result, int af, struct hostent *host, /* Illegal address: ignore line. */ return 0; - first_unused+=host->h_length; - room_left-=host->h_length; + first_unused += host->h_length; + room_left -= host->h_length; if (NISENTRYLEN (0, 0, result) + 1 > room_left) goto no_more_room; - p = __stpncpy (first_unused, NISENTRYVAL (0, 0, result), - NISENTRYLEN (0, 0, result)); - *p = '\0'; - room_left -= (NISENTRYLEN (0, 0, result) + 1); host->h_name = first_unused; - first_unused += NISENTRYLEN (0, 0, result) +1; - p = first_unused; - - line = p; - for (i = 0; i < result->objects.objects_len; ++i) + first_unused = __stpncpy (first_unused, NISENTRYVAL (0, 0, result), + NISENTRYLEN (0, 0, result)); + *first_unused++ = '\0'; + room_left -= NISENTRYLEN (0, 0, result) + 1; + + /* XXX Rewrite at some point to allocate the array first and then + copy the strings. It wasteful to first concatenate the strings + to just split them again later. */ + char *line = first_unused; + for (i = 0; i < NIS_RES_NUMOBJ (result); ++i) { if (strcmp (NISENTRYVAL (i, 1, result), host->h_name) != 0) { if (NISENTRYLEN (i, 1, result) + 2 > room_left) goto no_more_room; - *p++ = ' '; - p = __stpncpy (p, NISENTRYVAL (i, 1, result), - NISENTRYLEN (i, 1, result)); - *p = '\0'; - room_left -= (NISENTRYLEN (i, 1, result) + 1); + *first_unused++ = ' '; + first_unused = __stpncpy (first_unused, NISENTRYVAL (i, 1, result), + NISENTRYLEN (i, 1, result)); + *first_unused = '\0'; + room_left -= NISENTRYLEN (i, 1, result) + 1; } } - *p++ = '\0'; - first_unused = p; + *first_unused++ = '\0'; /* Adjust the pointer so it is aligned for storing pointers. */ - first_unused += __alignof__ (char *) - 1; - first_unused -= ((first_unused - (char *) 0) % __alignof__ (char *)); - host->h_addr_list = (char **) first_unused; - if (room_left < 2 * sizeof (char *)) + size_t adjust = ((__alignof__ (char *) + - (first_unused - (char *) 0) % __alignof__ (char *)) + % __alignof__ (char *)); + if (room_left < adjust + 3 * sizeof (char *)) goto no_more_room; + first_unused += adjust; + room_left -= adjust; + host->h_addr_list = (char **) first_unused; - room_left -= (2 * sizeof (char *)); + room_left -= 3 * sizeof (char *); host->h_addr_list[0] = data; host->h_addr_list[1] = NULL; host->h_aliases = &host->h_addr_list[2]; - host->h_aliases[0] = NULL; i = 0; while (*line != '\0') @@ -159,23 +161,21 @@ _nss_nisplus_parse_hostent (nis_result *result, int af, struct hostent *host, goto no_more_room; room_left -= sizeof (char *); - host->h_aliases[i] = line; + host->h_aliases[i++] = line; while (*line != '\0' && *line != ' ') ++line; if (*line == ' ') - { - *line = '\0'; - ++line; - ++i; - } - else - host->h_aliases[i+1] = NULL; + *line++ = '\0'; } + + host->h_aliases[i] = NULL; + return 1; } + static enum nss_status _nss_create_tablename (int *errnop) { |