Add a proper getdelim(3) replacement and use it instead of getline(3).

This commit is contained in:
Todd C. Miller
2019-04-08 10:37:30 -06:00
parent f0910c01da
commit de65d70929
16 changed files with 312 additions and 164 deletions

View File

@@ -108,7 +108,7 @@ lib/util/getcwd.c
lib/util/getentropy.c lib/util/getentropy.c
lib/util/getgrouplist.c lib/util/getgrouplist.c
lib/util/gethostname.c lib/util/gethostname.c
lib/util/getline.c lib/util/getdelim.c
lib/util/getopt_long.c lib/util/getopt_long.c
lib/util/gettime.c lib/util/gettime.c
lib/util/gidlist.c lib/util/gidlist.c
@@ -135,6 +135,7 @@ lib/util/reallocarray.c
lib/util/regress/atofoo/atofoo_test.c lib/util/regress/atofoo/atofoo_test.c
lib/util/regress/fnmatch/fnm_test.c lib/util/regress/fnmatch/fnm_test.c
lib/util/regress/fnmatch/fnm_test.in lib/util/regress/fnmatch/fnm_test.in
lib/util/regress/getdelim/getdelim_test.c
lib/util/regress/getgrouplist/getgrouplist_test.c lib/util/regress/getgrouplist/getgrouplist_test.c
lib/util/regress/glob/files lib/util/regress/glob/files
lib/util/regress/glob/globtest.c lib/util/regress/glob/globtest.c

View File

@@ -248,9 +248,6 @@
/* Define to 1 if you have the `fexecve' function. */ /* Define to 1 if you have the `fexecve' function. */
#undef HAVE_FEXECVE #undef HAVE_FEXECVE
/* Define to 1 if you have the `fgetln' function. */
#undef HAVE_FGETLN
/* Define to 1 if you have the `fnmatch' function. */ /* Define to 1 if you have the `fnmatch' function. */
#undef HAVE_FNMATCH #undef HAVE_FNMATCH
@@ -284,6 +281,9 @@
/* Define to 1 if you have the `getauxval' function. */ /* Define to 1 if you have the `getauxval' function. */
#undef HAVE_GETAUXVAL #undef HAVE_GETAUXVAL
/* Define to 1 if you have the `getdelim' function. */
#undef HAVE_GETDELIM
/* Define to 1 if you have the `getdomainname' function. */ /* Define to 1 if you have the `getdomainname' function. */
#undef HAVE_GETDOMAINNAME #undef HAVE_GETDOMAINNAME
@@ -308,9 +308,6 @@
/* Define to 1 if you have the `getifaddrs' function. */ /* Define to 1 if you have the `getifaddrs' function. */
#undef HAVE_GETIFADDRS #undef HAVE_GETIFADDRS
/* Define to 1 if you have the `getline' function. */
#undef HAVE_GETLINE
/* Define to 1 if you have the `getopt_long' function. */ /* Define to 1 if you have the `getopt_long' function. */
#undef HAVE_GETOPT_LONG #undef HAVE_GETOPT_LONG

37
configure vendored
View File

@@ -15510,11 +15510,11 @@ fi
ac_cv_func_strnlen=no ac_cv_func_strnlen=no
fi fi
# getline() may or may ont be present on AIX <= 6.1. # getdelim() may or may not be present on AIX <= 6.1.
# bos610 is missing getline/getdelim but bos61J has it. # bos610 is missing getdelim but bos61J has it.
if test "$enable_package_build" = "yes"; then if test "$enable_package_build" = "yes"; then
if test $OSMAJOR -le 6; then if test $OSMAJOR -le 6; then
ac_cv_func_getline=no ac_cv_func_getdelim=no
fi fi
fi fi
@@ -15731,8 +15731,6 @@ $as_echo "$sudo_cv_var_daportable" >&6; }
hpux10.*) hpux10.*)
shadow_funcs="getprpwnam iscomsec" shadow_funcs="getprpwnam iscomsec"
shadow_libs="-lsec" shadow_libs="-lsec"
# HP-UX 10.20 libc has an incompatible getline
ac_cv_func_getline="no"
# HP-UX 10.x doesn't support LD_PRELOAD # HP-UX 10.x doesn't support LD_PRELOAD
with_noexec=no with_noexec=no
;; ;;
@@ -19381,39 +19379,34 @@ fi
fi fi
done done
for ac_func in getline for ac_func in getdelim
do : do :
ac_fn_c_check_func "$LINENO" "getline" "ac_cv_func_getline" ac_fn_c_check_func "$LINENO" "getdelim" "ac_cv_func_getdelim"
if test "x$ac_cv_func_getline" = xyes; then : if test "x$ac_cv_func_getdelim" = xyes; then :
cat >>confdefs.h <<_ACEOF cat >>confdefs.h <<_ACEOF
#define HAVE_GETLINE 1 #define HAVE_GETDELIM 1
_ACEOF _ACEOF
else else
case " $LIBOBJS " in case " $LIBOBJS " in
*" getline.$ac_objext "* ) ;; *" getdelim.$ac_objext "* ) ;;
*) LIBOBJS="$LIBOBJS getline.$ac_objext" *) LIBOBJS="$LIBOBJS getdelim.$ac_objext"
;; ;;
esac esac
for _sym in sudo_getdelim; do
COMPAT_EXP="${COMPAT_EXP}${_sym}
"
done
for _sym in sudo_getline; do for _sym in sudo_getline; do
COMPAT_EXP="${COMPAT_EXP}${_sym} COMPAT_EXP="${COMPAT_EXP}${_sym}
" "
done done
for ac_func in fgetln
do :
ac_fn_c_check_func "$LINENO" "fgetln" "ac_cv_func_fgetln"
if test "x$ac_cv_func_fgetln" = xyes; then :
cat >>confdefs.h <<_ACEOF
#define HAVE_FGETLN 1
_ACEOF
fi
done
fi fi
done done

View File

@@ -1829,11 +1829,11 @@ case "$host" in
ac_cv_func_strnlen=no ac_cv_func_strnlen=no
fi fi
# getline() may or may ont be present on AIX <= 6.1. # getdelim() may or may not be present on AIX <= 6.1.
# bos610 is missing getline/getdelim but bos61J has it. # bos610 is missing getdelim but bos61J has it.
if test "$enable_package_build" = "yes"; then if test "$enable_package_build" = "yes"; then
if test $OSMAJOR -le 6; then if test $OSMAJOR -le 6; then
ac_cv_func_getline=no ac_cv_func_getdelim=no
fi fi
fi fi
@@ -1954,8 +1954,6 @@ case "$host" in
hpux10.*) hpux10.*)
shadow_funcs="getprpwnam iscomsec" shadow_funcs="getprpwnam iscomsec"
shadow_libs="-lsec" shadow_libs="-lsec"
# HP-UX 10.20 libc has an incompatible getline
ac_cv_func_getline="no"
# HP-UX 10.x doesn't support LD_PRELOAD # HP-UX 10.x doesn't support LD_PRELOAD
with_noexec=no with_noexec=no
;; ;;
@@ -2555,10 +2553,10 @@ AC_CHECK_FUNCS([getgrouplist], [], [
esac esac
SUDO_APPEND_COMPAT_EXP(sudo_getgrouplist) SUDO_APPEND_COMPAT_EXP(sudo_getgrouplist)
]) ])
AC_CHECK_FUNCS([getline], [], [ AC_CHECK_FUNCS([getdelim], [], [
AC_LIBOBJ(getline) AC_LIBOBJ(getdelim)
SUDO_APPEND_COMPAT_EXP(sudo_getline) SUDO_APPEND_COMPAT_EXP(sudo_getdelim)
AC_CHECK_FUNCS([fgetln]) COMPAT_TEST_PROGS="${COMPAT_TEST_PROGS}${COMPAT_TEST_PROGS+ }getdelim_test"
]) ])
AC_CHECK_FUNCS([reallocarray], [], [ AC_CHECK_FUNCS([reallocarray], [], [
AC_LIBOBJ(reallocarray) AC_LIBOBJ(reallocarray)

View File

@@ -405,11 +405,11 @@ __dso_public int sudo_getgrouplist(const char *name, GETGROUPS_T basegid, GETGRO
# undef getgrouplist # undef getgrouplist
# define getgrouplist(_a, _b, _c, _d) sudo_getgrouplist((_a), (_b), (_c), (_d)) # define getgrouplist(_a, _b, _c, _d) sudo_getgrouplist((_a), (_b), (_c), (_d))
#endif /* GETGROUPLIST */ #endif /* GETGROUPLIST */
#ifndef HAVE_GETLINE #ifndef HAVE_GETDELIM
__dso_public ssize_t sudo_getline(char **bufp, size_t *bufsizep, FILE *fp); __dso_public ssize_t sudo_getdelim(char **bufp, size_t *bufsizep, int delim, FILE *fp);
# undef getline # undef getdelim
# define getline(_a, _b, _c) sudo_getline((_a), (_b), (_c)) # define getdelim(_a, _b, _c, _d) sudo_getdelim((_a), (_b), (_c), (_d))
#endif /* HAVE_GETLINE */ #endif /* HAVE_GETDELIM */
#ifndef HAVE_UTIMENSAT #ifndef HAVE_UTIMENSAT
__dso_public int sudo_utimensat(int fd, const char *file, const struct timespec *times, int flag); __dso_public int sudo_utimensat(int fd, const char *file, const struct timespec *times, int flag);
# undef utimensat # undef utimensat

View File

@@ -138,6 +138,8 @@ FNM_TEST_OBJS = fnm_test.lo
GLOBTEST_OBJS = globtest.lo GLOBTEST_OBJS = globtest.lo
GETDELIM_TEST_OBJS = getdelim_test.lo
STRSPLIT_TEST_OBJS = strsplit_test.lo STRSPLIT_TEST_OBJS = strsplit_test.lo
PARSE_GIDS_TEST_OBJS = parse_gids_test.lo PARSE_GIDS_TEST_OBJS = parse_gids_test.lo
@@ -215,6 +217,9 @@ fnm_test: $(FNM_TEST_OBJS) libsudo_util.la
globtest: $(GLOBTEST_OBJS) libsudo_util.la globtest: $(GLOBTEST_OBJS) libsudo_util.la
$(LIBTOOL) $(LTFLAGS) --mode=link $(CC) -o $@ $(GLOBTEST_OBJS) libsudo_util.la $(ASAN_LDFLAGS) $(PIE_LDFLAGS) $(SSP_LDFLAGS) $(TEST_LDFLAGS) $(TEST_LIBS) $(LIBTOOL) $(LTFLAGS) --mode=link $(CC) -o $@ $(GLOBTEST_OBJS) libsudo_util.la $(ASAN_LDFLAGS) $(PIE_LDFLAGS) $(SSP_LDFLAGS) $(TEST_LDFLAGS) $(TEST_LIBS)
getdelim_test: $(GETDELIM_TEST_OBJS) libsudo_util.la
$(LIBTOOL) $(LTFLAGS) --mode=link $(CC) -o $@ $(GETDELIM_TEST_OBJS) libsudo_util.la $(ASAN_LDFLAGS) $(PIE_LDFLAGS) $(SSP_LDFLAGS) $(TEST_LDFLAGS) $(TEST_LIBS)
hltq_test: $(HLTQ_TEST_OBJS) libsudo_util.la hltq_test: $(HLTQ_TEST_OBJS) libsudo_util.la
$(LIBTOOL) $(LTFLAGS) --mode=link $(CC) -o $@ $(HLTQ_TEST_OBJS) libsudo_util.la $(ASAN_LDFLAGS) $(PIE_LDFLAGS) $(SSP_LDFLAGS) $(TEST_LDFLAGS) $(TEST_LIBS) $(LIBTOOL) $(LTFLAGS) --mode=link $(CC) -o $@ $(HLTQ_TEST_OBJS) libsudo_util.la $(ASAN_LDFLAGS) $(PIE_LDFLAGS) $(SSP_LDFLAGS) $(TEST_LDFLAGS) $(TEST_LIBS)
@@ -295,6 +300,9 @@ check: $(TEST_PROGS)
./globtest $(srcdir)/regress/glob/globtest.in || rval=`expr $$rval + $$?`; \ ./globtest $(srcdir)/regress/glob/globtest.in || rval=`expr $$rval + $$?`; \
rm -rf fake; \ rm -rf fake; \
fi; \ fi; \
if test -f getdelim_test; then \
./getdelim_test || rval=`expr $$rval + $$?`; \
fi; \
if test -f mktemp_test; then \ if test -f mktemp_test; then \
./mktemp_test || rval=`expr $$rval + $$?`; \ ./mktemp_test || rval=`expr $$rval + $$?`; \
fi; \ fi; \
@@ -560,6 +568,26 @@ getcwd.i: $(srcdir)/getcwd.c $(incdir)/sudo_compat.h $(top_builddir)/config.h
$(CC) -E -o $@ $(CPPFLAGS) $< $(CC) -E -o $@ $(CPPFLAGS) $<
getcwd.plog: getcwd.i getcwd.plog: getcwd.i
rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/getcwd.c --i-file $< --output-file $@ rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/getcwd.c --i-file $< --output-file $@
getdelim.lo: $(srcdir)/getdelim.c $(incdir)/sudo_compat.h \
$(top_builddir)/config.h
$(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c -o $@ $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/getdelim.c
getdelim.i: $(srcdir)/getdelim.c $(incdir)/sudo_compat.h \
$(top_builddir)/config.h
$(CC) -E -o $@ $(CPPFLAGS) $<
getdelim.plog: getdelim.i
rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/getdelim.c --i-file $< --output-file $@
getdelim_test.lo: $(srcdir)/regress/getdelim/getdelim_test.c \
$(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \
$(incdir)/sudo_fatal.h $(incdir)/sudo_util.h \
$(top_builddir)/config.h
$(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c -o $@ $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/regress/getdelim/getdelim_test.c
getdelim_test.i: $(srcdir)/regress/getdelim/getdelim_test.c \
$(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \
$(incdir)/sudo_fatal.h $(incdir)/sudo_util.h \
$(top_builddir)/config.h
$(CC) -E -o $@ $(CPPFLAGS) $<
getdelim_test.plog: getdelim_test.i
rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/regress/getdelim/getdelim_test.c --i-file $< --output-file $@
getentropy.lo: $(srcdir)/getentropy.c $(incdir)/sudo_compat.h \ getentropy.lo: $(srcdir)/getentropy.c $(incdir)/sudo_compat.h \
$(incdir)/sudo_digest.h $(incdir)/sudo_rand.h \ $(incdir)/sudo_digest.h $(incdir)/sudo_rand.h \
$(top_builddir)/config.h $(top_builddir)/config.h
@@ -602,12 +630,6 @@ gethostname.i: $(srcdir)/gethostname.c $(incdir)/compat/stdbool.h \
$(CC) -E -o $@ $(CPPFLAGS) $< $(CC) -E -o $@ $(CPPFLAGS) $<
gethostname.plog: gethostname.i gethostname.plog: gethostname.i
rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/gethostname.c --i-file $< --output-file $@ rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/gethostname.c --i-file $< --output-file $@
getline.lo: $(srcdir)/getline.c $(incdir)/sudo_compat.h $(top_builddir)/config.h
$(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c -o $@ $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/getline.c
getline.i: $(srcdir)/getline.c $(incdir)/sudo_compat.h $(top_builddir)/config.h
$(CC) -E -o $@ $(CPPFLAGS) $<
getline.plog: getline.i
rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/getline.c --i-file $< --output-file $@
getopt_long.lo: $(srcdir)/getopt_long.c $(incdir)/compat/getopt.h \ getopt_long.lo: $(srcdir)/getopt_long.c $(incdir)/compat/getopt.h \
$(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \ $(incdir)/compat/stdbool.h $(incdir)/sudo_compat.h \
$(incdir)/sudo_fatal.h $(top_builddir)/config.h $(incdir)/sudo_fatal.h $(top_builddir)/config.h

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2009-2010, 2012-2015 Todd C. Miller <Todd.Miller@sudo.ws> * Copyright (c) 2019 Todd C. Miller <Todd.Miller@sudo.ws>
* *
* Permission to use, copy, modify, and distribute this software for any * Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above * purpose with or without fee is hereby granted, provided that the above
@@ -21,7 +21,7 @@
#include <config.h> #include <config.h>
#ifndef HAVE_GETLINE #ifndef HAVE_GETDELIM
#include <sys/types.h> #include <sys/types.h>
@@ -37,65 +37,50 @@
#include "sudo_compat.h" #include "sudo_compat.h"
#ifdef HAVE_FGETLN
ssize_t ssize_t
sudo_getline(char **bufp, size_t *bufsizep, FILE *fp) sudo_getdelim(char **buf, size_t *bufsize, int delim, FILE *fp)
{ {
char *buf, *cp; char *cp, *ep;
size_t bufsize; int ch;
size_t len;
buf = fgetln(fp, &len); if (*buf == NULL || *bufsize == 0) {
if (buf) { char *tmp = realloc(*buf, LINE_MAX);
bufsize = *bufp ? *bufsizep : 0; if (tmp == NULL)
if (bufsize == 0 || bufsize - 1 < len) {
bufsize = len + 1;
cp = realloc(*bufp, bufsize);
if (cp == NULL)
return -1;
*bufp = cp;
*bufsizep = bufsize;
}
memcpy(*bufp, buf, len);
(*bufp)[len] = '\0';
}
return buf ? len : -1;
}
#else
ssize_t
sudo_getline(char **bufp, size_t *bufsizep, FILE *fp)
{
char *buf, *cp;
size_t bufsize;
ssize_t len = 0;
buf = *bufp;
bufsize = *bufsizep;
if (buf == NULL || bufsize == 0) {
bufsize = LINE_MAX;
cp = realloc(buf, bufsize);
if (cp == NULL)
return -1; return -1;
buf = cp; *buf = tmp;
*bufsize = LINE_MAX;
} }
cp = *buf;
ep = cp + *bufsize;
for (;;) { do {
if (fgets(buf + len, bufsize - len, fp) == NULL) { if (cp + 1 >= ep) {
len = -1; char *tmp = reallocarray(*buf, *bufsize, 2);
break; if (tmp == NULL)
goto bad;
cp = tmp + (cp - *buf);
*buf = tmp;
*bufsize *= 2;
} }
len = strlen(buf); if ((ch = getc(fp)) == EOF) {
if (!len || buf[len - 1] == '\n' || feof(fp)) if (feof(fp))
break; break;
cp = reallocarray(buf, bufsize, 2); goto bad;
if (cp == NULL) }
return -1; *cp++ = ch;
bufsize *= 2; } while (ch != delim);
buf = cp;
/* getdelim(3) should never return a length of 0. */
if (cp != *buf) {
*cp = '\0';
return (ssize_t)(cp - *buf);
} }
*bufp = buf; bad:
*bufsizep = bufsize; /* Error, push back what was read if possible. */
return len; while (cp > *buf) {
if (ungetc(*cp--, fp) == EOF)
break;
}
return -1;
} }
#endif /* HAVE_FGETLN */ #endif /* HAVE_GETDELIM */
#endif /* HAVE_GETLINE */

View File

@@ -46,7 +46,7 @@
* Read a line of input, honoring line continuation chars. * Read a line of input, honoring line continuation chars.
* Remove comments and strip off leading and trailing spaces. * Remove comments and strip off leading and trailing spaces.
* Returns the line length and updates the buf and bufsize pointers. * Returns the line length and updates the buf and bufsize pointers.
* XXX - just use a struct w/ state, including getline buffer? * XXX - just use a struct w/ state, including getdelim buffer?
* could also make comment char and line continuation configurable * could also make comment char and line continuation configurable
*/ */
ssize_t ssize_t
@@ -61,7 +61,7 @@ sudo_parseln_v2(char **bufp, size_t *bufsizep, unsigned int *lineno, FILE *fp, i
do { do {
comment = false; comment = false;
continued = false; continued = false;
len = getline(&line, &linesize, fp); len = getdelim(&line, &linesize, '\n', fp);
if (len == -1) if (len == -1)
break; break;
if (lineno != NULL) if (lineno != NULL)

View File

@@ -0,0 +1,147 @@
/*
* Copyright (c) 2019 Todd C. Miller <Todd.Miller@sudo.ws>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <config.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/wait.h>
#include <stdio.h>
#include <stdlib.h>
#ifdef HAVE_STRING_H
# include <string.h>
#endif /* HAVE_STRING_H */
#ifdef HAVE_STRINGS_H
# include <strings.h>
#endif /* HAVE_STRINGS_H */
#ifdef HAVE_STDBOOL_H
# include <stdbool.h>
#else
# include "compat/stdbool.h"
#endif
#include <unistd.h>
#include "sudo_compat.h"
#include "sudo_fatal.h"
#include "sudo_util.h"
__dso_public int main(int argc, char *argv[]);
/*
* Test that sudo_getdelim() works as expected.
*/
struct getdelim_test {
const char *input;
const char *output[4];
int delim;
};
/*
* TODO: test error case.
* test realloc case (buf > LINE_MAX)
*/
static struct getdelim_test test_data[] = {
{ "a\nb\nc\n", { "a\n", "b\n", "c\n", NULL }, '\n' },
{ "a\nb\nc", { "a\n", "b\n", "c", NULL }, '\n' },
{ "a\tb\tc\t", { "a\t", "b\t", "c\t", NULL }, '\t' },
{ "a\tb\tc", { "a\t", "b\t", "c", NULL }, '\t' },
{ NULL, { NULL }, '\0' }
};
static int errors = 0, ntests = 0;
static void
runtests(char **buf, size_t *buflen)
{
int i, j, sv[2];
pid_t pid;
FILE *fp;
for (i = 0; test_data[i].input != NULL; i++) {
if (socketpair(PF_UNIX, SOCK_STREAM, 0, sv) == -1)
sudo_fatal_nodebug("socketpair");
switch ((pid = fork())) {
case -1:
sudo_fatal_nodebug("fork");
case 0:
/* child */
close(sv[0]);
if (send(sv[1], test_data[i].input, strlen(test_data[i].input), 0) == -1) {
sudo_warn_nodebug("send");
_exit(127);
}
_exit(0);
break;
default:
/* parent */
break;
}
close(sv[1]);
if ((fp = fdopen(sv[0], "r")) == NULL)
sudo_fatal_nodebug("fdopen");
for (j = 0; test_data[i].output[j] != NULL; j++) {
ntests++;
alarm(10);
if (getdelim(buf, buflen, test_data[i].delim, fp) == -1)
sudo_fatal_nodebug("getdelim");
alarm(0);
if (strcmp(*buf, test_data[i].output[j]) != 0) {
sudo_warnx_nodebug("failed test #%d: expected %s, got %s",
ntests, test_data[i].output[j], *buf);
errors++;
}
}
/* test EOF */
ntests++;
alarm(30);
if (getdelim(buf, buflen, test_data[i].delim, fp) != -1) {
sudo_warnx_nodebug("failed test #%d: expected EOF, got %s",
ntests, *buf);
errors++;
} else {
if (!feof(fp)) {
sudo_warn_nodebug("failed test #%d: expected EOF, got error",
ntests);
errors++;
}
}
fclose(fp);
waitpid(pid, NULL, 0);
alarm(0);
}
}
int
main(int argc, char *argv[])
{
size_t buflen = 0;
char *buf = NULL;
initprogname(argc > 0 ? argv[0] : "getdelim_test");
runtests(&buf, &buflen);
/* XXX - redo tests with preallocated buffer filled with junk */
if (ntests != 0) {
printf("%s: %d tests run, %d errors, %d%% success rate\n",
getprogname(), ntests, errors, (ntests - errors) * 100 / ntests);
}
exit(errors);
}

View File

@@ -112,7 +112,7 @@ sub mkdep {
# XXX - fill in AUTH_OBJS from contents of the auth dir instead # XXX - fill in AUTH_OBJS from contents of the auth dir instead
$makefile =~ s:\@AUTH_OBJS\@:afs.lo aix_auth.lo bsdauth.lo dce.lo fwtk.lo getspwuid.lo kerb5.lo pam.lo passwd.lo rfc1938.lo secureware.lo securid5.lo sia.lo:; $makefile =~ s:\@AUTH_OBJS\@:afs.lo aix_auth.lo bsdauth.lo dce.lo fwtk.lo getspwuid.lo kerb5.lo pam.lo passwd.lo rfc1938.lo secureware.lo securid5.lo sia.lo:;
$makefile =~ s:\@DIGEST\@:digest.lo digest_openssl.lo digest_gcrypt.lo:; $makefile =~ s:\@DIGEST\@:digest.lo digest_openssl.lo digest_gcrypt.lo:;
$makefile =~ s:\@LTLIBOBJS\@:arc4random.lo arc4random_uniform.lo closefrom.lo fnmatch.lo getaddrinfo.lo getcwd.lo getentropy.lo getgrouplist.lo getline.lo getopt_long.lo glob.lo inet_ntop_lo inet_pton.lo isblank.lo memrchr.lo memset_s.lo mksiglist.lo mksigname.lo mktemp.lo nanosleep.lo pw_dup.lo reallocarray.lo sha2.lo sig2str.lo siglist.lo signame.lo snprintf.lo strlcat.lo strlcpy.lo strndup.lo strnlen.lo strsignal.lo strtonum.lo utimens.lo vsyslog.lo pipe2.lo:; $makefile =~ s:\@LTLIBOBJS\@:arc4random.lo arc4random_uniform.lo closefrom.lo fnmatch.lo getaddrinfo.lo getcwd.lo getentropy.lo getgrouplist.lo getdelim.lo getopt_long.lo glob.lo inet_ntop_lo inet_pton.lo isblank.lo memrchr.lo memset_s.lo mksiglist.lo mksigname.lo mktemp.lo nanosleep.lo pw_dup.lo reallocarray.lo sha2.lo sig2str.lo siglist.lo signame.lo snprintf.lo strlcat.lo strlcpy.lo strndup.lo strnlen.lo strsignal.lo strtonum.lo utimens.lo vsyslog.lo pipe2.lo:;
# Parse OBJS lines # Parse OBJS lines
my %objs; my %objs;

View File

@@ -65,59 +65,64 @@ sudo_aix_authtype(void)
FILE *fp; FILE *fp;
debug_decl(sudo_aix_authtype, SUDOERS_DEBUG_AUTH) debug_decl(sudo_aix_authtype, SUDOERS_DEBUG_AUTH)
if ((fp = fopen("/etc/security/login.cfg", "r")) != NULL) { if ((fp = fopen("/etc/security/login.cfg", "r")) == NULL)
while (authtype == AIX_AUTH_UNKNOWN && (len = getline(&line, &linesize, fp)) != -1) { debug_return_int(AIX_AUTH_UNKNOWN);
/* First remove comments. */
if ((cp = strchr(line, '#')) != NULL) {
*cp = '\0';
len = (ssize_t)(cp - line);
}
/* Next remove trailing newlines and whitespace. */ while ((len = getdelim(&line, &linesize, '\n', fp)) != -1) {
while (len > 0 && isspace((unsigned char)line[len - 1])) /* First remove comments. */
line[--len] = '\0'; if ((cp = strchr(line, '#')) != NULL) {
*cp = '\0';
/* Skip blank lines. */ len = (ssize_t)(cp - line);
if (len == 0) }
continue;
/* Next remove trailing newlines and whitespace. */
/* Match start of the usw stanza. */ while (len > 0 && isspace((unsigned char)line[len - 1]))
if (!in_stanza) { line[--len] = '\0';
if (strncmp(line, "usw:", 4) == 0)
in_stanza = true; /* Skip blank lines. */
continue; if (len == 0)
} continue;
/* Check for end of the usw stanza. */ /* Match start of the usw stanza. */
if (!isblank((unsigned char)line[0])) { if (!in_stanza) {
in_stanza = false; if (strncmp(line, "usw:", 4) == 0)
break; in_stanza = true;
} continue;
}
/* Skip leading blanks. */
cp = line; /* Check for end of the usw stanza. */
do { if (!isblank((unsigned char)line[0])) {
cp++; in_stanza = false;
} while (isblank((unsigned char)*cp)); break;
}
/* Match "auth_type = (PAM_AUTH|STD_AUTH)". */
if (strncmp(cp, "auth_type", 9) != 0) /* Skip leading blanks. */
continue; cp = line;
cp += 9; do {
while (isblank((unsigned char)*cp)) cp++;
cp++; } while (isblank((unsigned char)*cp));
if (*cp++ != '=')
continue; /* Match "auth_type = (PAM_AUTH|STD_AUTH)". */
while (isblank((unsigned char)*cp)) if (strncmp(cp, "auth_type", 9) != 0)
cp++; continue;
if (strcmp(cp, "PAM_AUTH") == 0) cp += 9;
authtype = AIX_AUTH_PAM; while (isblank((unsigned char)*cp))
else if (strcmp(cp, "STD_AUTH") == 0) cp++;
authtype = AIX_AUTH_STD; if (*cp++ != '=')
continue;
while (isblank((unsigned char)*cp))
cp++;
if (strcmp(cp, "PAM_AUTH") == 0) {
authtype = AIX_AUTH_PAM;
break;
}
if (strcmp(cp, "STD_AUTH") == 0) {
authtype = AIX_AUTH_STD;
break;
} }
free(line);
fclose(fp);
} }
free(line);
fclose(fp);
debug_return_int(authtype); debug_return_int(authtype);
} }

View File

@@ -72,7 +72,7 @@ get_boottime(struct timespec *ts)
/* read btime from /proc/stat */ /* read btime from /proc/stat */
fp = fopen("/proc/stat", "r"); fp = fopen("/proc/stat", "r");
if (fp != NULL) { if (fp != NULL) {
while ((len = getline(&line, &linesize, fp)) != -1) { while ((len = getdelim(&line, &linesize, '\n', fp)) != -1) {
if (strncmp(line, "btime ", 6) == 0) { if (strncmp(line, "btime ", 6) == 0) {
if (line[len - 1] == '\n') if (line[len - 1] == '\n')
line[len - 1] = '\0'; line[len - 1] = '\0';

View File

@@ -81,9 +81,9 @@ parse_logfile(const char *logfile)
*/ */
if ((li = calloc(1, sizeof(*li))) == NULL) if ((li = calloc(1, sizeof(*li))) == NULL)
sudo_fatalx(U_("%s: %s"), __func__, U_("unable to allocate memory")); sudo_fatalx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
if (getline(&buf, &bufsize, fp) == -1 || if (getdelim(&buf, &bufsize, '\n', fp) == -1 ||
getline(&li->cwd, &cwdsize, fp) == -1 || getdelim(&li->cwd, &cwdsize, '\n', fp) == -1 ||
getline(&li->cmd, &cmdsize, fp) == -1) { getdelim(&li->cmd, &cmdsize, '\n', fp) == -1) {
sudo_warn(U_("%s: invalid log file"), logfile); sudo_warn(U_("%s: invalid log file"), logfile);
goto bad; goto bad;
} }

View File

@@ -361,7 +361,7 @@ sudo_ldap_read_secret(const char *path)
debug_decl(sudo_ldap_read_secret, SUDOERS_DEBUG_LDAP) debug_decl(sudo_ldap_read_secret, SUDOERS_DEBUG_LDAP)
if ((fp = fopen(path_ldap_secret, "r")) != NULL) { if ((fp = fopen(path_ldap_secret, "r")) != NULL) {
len = getline(&line, &linesize, fp); len = getdelim(&line, &linesize, '\n', fp);
if (len != -1) { if (len != -1) {
/* trim newline */ /* trim newline */
while (len > 0 && line[len - 1] == '\n') while (len > 0 && line[len - 1] == '\n')

View File

@@ -566,7 +566,7 @@ sudoers_parse_ldif(struct sudoers_parse_tree *parse_tree,
/* Read through input, parsing into sudo_roles and global defaults. */ /* Read through input, parsing into sudo_roles and global defaults. */
for (;;) { for (;;) {
int ch; int ch;
ssize_t len = getline(&line, &linesize, fp); ssize_t len = getdelim(&line, &linesize, '\n', fp);
/* Trim trailing return or newline. */ /* Trim trailing return or newline. */
while (len > 0 && (line[len - 1] == '\r' || line[len - 1] == '\n')) while (len > 0 && (line[len - 1] == '\r' || line[len - 1] == '\n'))

View File

@@ -110,7 +110,7 @@ get_ipa_hostname(char **shostp, char **lhostp)
fp = fopen(_PATH_SSSD_CONF, "r"); fp = fopen(_PATH_SSSD_CONF, "r");
if (fp != NULL) { if (fp != NULL) {
while ((len = getline(&line, &linesize, fp)) != -1) { while ((len = getdelim(&line, &linesize, '\n', fp)) != -1) {
char *cp = line; char *cp = line;
/* Trim trailing and leading spaces. */ /* Trim trailing and leading spaces. */