Add a proper getdelim(3) replacement and use it instead of getline(3).
This commit is contained in:
3
MANIFEST
3
MANIFEST
@@ -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
|
||||||
|
@@ -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
37
configure
vendored
@@ -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
|
||||||
|
16
configure.ac
16
configure.ac
@@ -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)
|
||||||
|
@@ -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
|
||||||
|
@@ -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
|
||||||
|
@@ -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 */
|
|
@@ -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)
|
||||||
|
147
lib/util/regress/getdelim/getdelim_test.c
Normal file
147
lib/util/regress/getdelim/getdelim_test.c
Normal 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);
|
||||||
|
}
|
2
mkdep.pl
2
mkdep.pl
@@ -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;
|
||||||
|
@@ -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);
|
||||||
}
|
}
|
||||||
|
@@ -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';
|
||||||
|
@@ -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;
|
||||||
}
|
}
|
||||||
|
@@ -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')
|
||||||
|
@@ -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'))
|
||||||
|
@@ -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. */
|
||||||
|
Reference in New Issue
Block a user