o compat_group() and files_group() are more complicated than I thought

in rev. 1.34.  Mainly I missed the fact that the buffer is used for two
purposes:

1) storing a group line from the group file;

2) __gr_parse_entry() parses the buffer and tries to put the group
members to the remaining part of the buffer and can fail if there
is no enough room for them.

Re-arrange the buffer size checks to account the latter case.

Submitted by:	Kirk R Webb
MFC after:	2 weeks
This commit is contained in:
maxim 2006-07-14 17:45:33 +00:00
parent df5064de23
commit e03f872cad

View File

@ -770,18 +770,17 @@ files_group(void *retval, void *mdata, va_list ap)
* pointer for the member list terminator.
*/
if (bufsize <= linesize + _ALIGNBYTES + sizeof(char *)) {
fseeko(st->fp, pos, SEEK_SET);
*errnop = ERANGE;
rv = NS_RETURN;
break;
}
pos = ftello(st->fp);
memcpy(buffer, line, linesize);
buffer[linesize] = '\0';
rv = __gr_parse_entry(buffer, linesize, grp,
&buffer[linesize + 1], bufsize - linesize - 1, errnop);
if (rv & NS_TERMINATE)
break;
pos = ftello(st->fp);
}
if (!stayopen && st->fp != NULL) {
fclose(st->fp);
@ -789,6 +788,8 @@ files_group(void *retval, void *mdata, va_list ap)
}
if (rv == NS_SUCCESS && retval != NULL)
*(struct group **)retval = grp;
else if (*errnop == ERANGE)
fseeko(st->fp, pos, SEEK_SET);
return (rv);
}
@ -1322,18 +1323,17 @@ compat_group(void *retval, void *mdata, va_list ap)
* pointer for the member list terminator.
*/
if (bufsize <= linesize + _ALIGNBYTES + sizeof(char *)) {
fseeko(st->fp, pos, SEEK_SET);
*errnop = ERANGE;
rv = NS_RETURN;
break;
}
pos = ftello(st->fp);
memcpy(buffer, line, linesize);
buffer[linesize] = '\0';
rv = __gr_parse_entry(buffer, linesize, grp,
&buffer[linesize + 1], bufsize - linesize - 1, errnop);
if (rv & NS_TERMINATE)
break;
pos = ftello(st->fp);
}
fin:
if (!stayopen && st->fp != NULL) {
@ -1342,6 +1342,8 @@ compat_group(void *retval, void *mdata, va_list ap)
}
if (rv == NS_SUCCESS && retval != NULL)
*(struct group **)retval = grp;
else if (*errnop == ERANGE)
fseeko(st->fp, pos, SEEK_SET);
return (rv);
#undef set_lookup_type
}