summaryrefslogtreecommitdiff
path: root/third_party/heimdal/lib/roken
diff options
context:
space:
mode:
authorJoseph Sutton <josephsutton@catalyst.net.nz>2022-03-01 14:17:54 +1300
committerJoseph Sutton <jsutton@samba.org>2022-03-01 22:34:34 +0000
commit51569b3152a952d07fddaa3a70d60c920618c704 (patch)
tree4e447f5d9eb04c7acadf3cff4547068fc79d2113 /third_party/heimdal/lib/roken
parentfccf9859786dfb50b317ea2296c2494997f0ae09 (diff)
downloadsamba-51569b3152a952d07fddaa3a70d60c920618c704.tar.gz
third_party/heimdal: import lorikeet-heimdal-202203010107 (commit 0e7a12404c388e831fe6933fcc3c86e7eb334825)
NOTE: THIS COMMIT WON'T COMPILE/WORK ON ITS OWN! BUG: https://bugzilla.samba.org/show_bug.cgi?id=14995 Signed-off-by: Joseph Sutton <josephsutton@catalyst.net.nz> Reviewed-by: Stefan Metzmacher <metze@samba.org> Reviewed-by: Andrew Bartlett <abartlet@samba.org>
Diffstat (limited to 'third_party/heimdal/lib/roken')
-rw-r--r--third_party/heimdal/lib/roken/Makefile.am6
-rw-r--r--third_party/heimdal/lib/roken/base32-test.c3
-rw-r--r--third_party/heimdal/lib/roken/base32.c12
-rw-r--r--third_party/heimdal/lib/roken/base64-test.c3
-rw-r--r--third_party/heimdal/lib/roken/base64.c4
-rw-r--r--third_party/heimdal/lib/roken/copyhostent.c3
-rw-r--r--third_party/heimdal/lib/roken/detach.c3
-rw-r--r--third_party/heimdal/lib/roken/dirent-test.c6
-rw-r--r--third_party/heimdal/lib/roken/environment.c15
-rw-r--r--third_party/heimdal/lib/roken/fnmatch.c2
-rw-r--r--third_party/heimdal/lib/roken/freeaddrinfo.c2
-rw-r--r--third_party/heimdal/lib/roken/freehostent.c2
-rw-r--r--third_party/heimdal/lib/roken/getaddrinfo.c10
-rw-r--r--third_party/heimdal/lib/roken/getcap.c996
-rw-r--r--third_party/heimdal/lib/roken/getipnodebyaddr.c2
-rw-r--r--third_party/heimdal/lib/roken/getipnodebyname.c2
-rw-r--r--third_party/heimdal/lib/roken/getnameinfo.c8
-rw-r--r--third_party/heimdal/lib/roken/getuserinfo.c30
-rw-r--r--third_party/heimdal/lib/roken/hex-test.c35
-rw-r--r--third_party/heimdal/lib/roken/hex.c28
-rw-r--r--third_party/heimdal/lib/roken/mergesort_r.c4
-rw-r--r--third_party/heimdal/lib/roken/ndbm_wrap.c2
-rw-r--r--third_party/heimdal/lib/roken/net_write.c7
-rw-r--r--third_party/heimdal/lib/roken/resolve-test.c2
-rw-r--r--third_party/heimdal/lib/roken/roken-common.h6
-rw-r--r--third_party/heimdal/lib/roken/roken.h.in60
-rw-r--r--third_party/heimdal/lib/roken/snprintf.c2
-rw-r--r--third_party/heimdal/lib/roken/socket.c29
-rw-r--r--third_party/heimdal/lib/roken/strftime.c7
-rw-r--r--third_party/heimdal/lib/roken/strptime.c2
-rw-r--r--third_party/heimdal/lib/roken/strtoll.c3
-rw-r--r--third_party/heimdal/lib/roken/strtoull.c3
-rw-r--r--third_party/heimdal/lib/roken/test-getuserinfo.c3
-rw-r--r--third_party/heimdal/lib/roken/test-mini_inetd.c2
-rw-r--r--third_party/heimdal/lib/roken/timeval.c215
-rw-r--r--third_party/heimdal/lib/roken/version-script.map5
-rw-r--r--third_party/heimdal/lib/roken/vis.c17
37 files changed, 407 insertions, 1134 deletions
diff --git a/third_party/heimdal/lib/roken/Makefile.am b/third_party/heimdal/lib/roken/Makefile.am
index a6168f944d4..35d753204e7 100644
--- a/third_party/heimdal/lib/roken/Makefile.am
+++ b/third_party/heimdal/lib/roken/Makefile.am
@@ -21,7 +21,7 @@ AM_CPPFLAGS += -I$(DBHEADER)
endif
bin_PROGRAMS = rkvis rkbase32 rkbase64
-noinst_PROGRAMS = snprintf-test resolve-test rkpty test-detach test-auxval rtbl
+noinst_PROGRAMS = snprintf-test resolve-test rkpty test-detach test-auxval rtbl timeval
CHECK_LOCAL = snprintf-test resolve-test rkpty make-roken
@@ -40,6 +40,7 @@ check_PROGRAMS = \
parse_time-test \
snprintf-test \
strpftime-test \
+ timeval \
tsearch-test
TESTS = $(check_PROGRAMS)
@@ -89,6 +90,9 @@ else
vis_h = vis.h
endif
+timeval_SOURCES = timeval.c
+timeval_CPPFLAGS = -DTEST
+
rkvis_SOURCES = vis.c $(vis_h) vis-extras.h
rkvis_CPPFLAGS = -DTEST
diff --git a/third_party/heimdal/lib/roken/base32-test.c b/third_party/heimdal/lib/roken/base32-test.c
index bea2866e47d..e30c193c478 100644
--- a/third_party/heimdal/lib/roken/base32-test.c
+++ b/third_party/heimdal/lib/roken/base32-test.c
@@ -66,7 +66,8 @@ main(int argc, char **argv)
for(t = tests; t->data; t++) {
char *str;
int len;
- len = rk_base32_encode(t->data, t->len, &str, t->preserve_order);
+
+ (void) rk_base32_encode(t->data, t->len, &str, t->preserve_order);
if (strcmp(str, t->result) != 0) {
fprintf(stderr, "failed test %d: %s != %s\n", numtest,
str, t->result);
diff --git a/third_party/heimdal/lib/roken/base32.c b/third_party/heimdal/lib/roken/base32.c
index 638ec2925f2..ef74336d70a 100644
--- a/third_party/heimdal/lib/roken/base32.c
+++ b/third_party/heimdal/lib/roken/base32.c
@@ -100,10 +100,10 @@ rk_base32_encode(const void *data, int size, char **str, enum rk_base32_flags fl
p[6] = chars[(c & 0x0000000000000003e0ULL) >> 5];
p[7] = chars[(c & 0x00000000000000001fULL) >> 0];
switch (i - size) {
- case 4: p[2] = p[3] = '='; /*fallthrough*/
- case 3: p[4] = '='; /*fallthrough*/
- case 2: p[5] = p[6] = '='; /*fallthrough*/
- case 1: p[7] = '='; /*fallthrough*/
+ case 4: p[2] = p[3] = '='; fallthrough;
+ case 3: p[4] = '='; fallthrough;
+ case 2: p[5] = p[6] = '='; fallthrough;
+ case 1: p[7] = '='; fallthrough;
default: break;
}
p += 8;
@@ -271,7 +271,7 @@ main(int argc, char **argv)
} else {
void *d;
- if ((ret = rk_undumpdata(argv[0], &d, &bufsz)))
+ if ((errno = rk_undumpdata(argv[0], &d, &bufsz)))
err(1, "Could not read %s", argv[0]);
buflen = bufsz;
buf = d;
@@ -298,7 +298,7 @@ main(int argc, char **argv)
if (fwrite(d, ret, 1, stdout) != 1)
err(1, "Could not write decoded data");
free(d);
- } else {
+ } else if (buf) { /* buf can be NULL if we read from an empty file */
char *e;
if ((ret = rk_base32_encode(buf, buflen, &e, flags)) < 0)
diff --git a/third_party/heimdal/lib/roken/base64-test.c b/third_party/heimdal/lib/roken/base64-test.c
index 86cccbb1d4f..8fb3f528001 100644
--- a/third_party/heimdal/lib/roken/base64-test.c
+++ b/third_party/heimdal/lib/roken/base64-test.c
@@ -58,7 +58,8 @@ main(int argc, char **argv)
for(t = tests; t->data; t++) {
char *str;
int len;
- len = rk_base64_encode(t->data, t->len, &str);
+
+ (void) rk_base64_encode(t->data, t->len, &str);
if(strcmp(str, t->result) != 0) {
fprintf(stderr, "failed test %d: %s != %s\n", numtest,
str, t->result);
diff --git a/third_party/heimdal/lib/roken/base64.c b/third_party/heimdal/lib/roken/base64.c
index a6dacdd1d29..582d183bcf7 100644
--- a/third_party/heimdal/lib/roken/base64.c
+++ b/third_party/heimdal/lib/roken/base64.c
@@ -214,7 +214,7 @@ main(int argc, char **argv)
err(1, "Could not read stdin");
} else {
void *d;
- if ((ret = rk_undumpdata(argv[0], &d, &bufsz)))
+ if ((errno = rk_undumpdata(argv[0], &d, &bufsz)))
err(1, "Could not read %s", argv[0]);
buflen = bufsz;
buf = d;
@@ -241,7 +241,7 @@ main(int argc, char **argv)
if (fwrite(d, ret, 1, stdout) != 1)
err(1, "Could not write decoded data");
free(d);
- } else {
+ } else if (buf) { /* buf can be NULL if we read from an empty file */
char *e;
if ((ret = rk_base64_encode(buf, buflen, &e)) < 0)
diff --git a/third_party/heimdal/lib/roken/copyhostent.c b/third_party/heimdal/lib/roken/copyhostent.c
index 4ed630210fc..9b9dba2aea5 100644
--- a/third_party/heimdal/lib/roken/copyhostent.c
+++ b/third_party/heimdal/lib/roken/copyhostent.c
@@ -40,7 +40,7 @@
*/
ROKEN_LIB_FUNCTION struct hostent * ROKEN_LIB_CALL
-copyhostent (const struct hostent *h)
+rk_copyhostent(const struct hostent *h)
{
struct hostent *res;
char **p;
@@ -96,4 +96,3 @@ copyhostent (const struct hostent *h)
}
return res;
}
-
diff --git a/third_party/heimdal/lib/roken/detach.c b/third_party/heimdal/lib/roken/detach.c
index 36e6cda1e02..4a00682511f 100644
--- a/third_party/heimdal/lib/roken/detach.c
+++ b/third_party/heimdal/lib/roken/detach.c
@@ -75,7 +75,8 @@ roken_detach_prep(int argc, char **argv, char *special_arg)
if (pipefds[1] == -1)
err(1, "Out of memory");
#else
- fcntl(pipefds[1], F_SETFD, fcntl(pipefds[1], F_GETFD & ~(O_CLOEXEC)));
+ (void) fcntl(pipefds[1], F_SETFD,
+ fcntl(pipefds[1], F_GETFD & ~(O_CLOEXEC)));
#endif
if (snprintf(fildes, sizeof(fildes), "%d", pipefds[1]) >= sizeof(fildes))
diff --git a/third_party/heimdal/lib/roken/dirent-test.c b/third_party/heimdal/lib/roken/dirent-test.c
index f1035a1aed6..dc4518ad5b0 100644
--- a/third_party/heimdal/lib/roken/dirent-test.c
+++ b/third_party/heimdal/lib/roken/dirent-test.c
@@ -28,7 +28,7 @@
* OF THE POSSIBILITY OF SUCH DAMAGE.
*
**********************************************************************/
-
+#include <config.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
@@ -148,7 +148,7 @@ int teardown_test(void)
strcmp(dirname + len + 1 - sizeof(TESTDIR)/sizeof(char), TESTDIR) == 0) {
- /* fallthrough */
+ fallthrough;
} else {
/* did we create the directory? */
@@ -162,7 +162,7 @@ int teardown_test(void)
fprintf(stderr, "Can't change to test directory. Aborting cleanup.\n");
return -1;
} else {
- /* fallthrough */
+ fallthrough;
}
} else {
return -1;
diff --git a/third_party/heimdal/lib/roken/environment.c b/third_party/heimdal/lib/roken/environment.c
index 64c354d62bb..a14f27b8a93 100644
--- a/third_party/heimdal/lib/roken/environment.c
+++ b/third_party/heimdal/lib/roken/environment.c
@@ -62,7 +62,8 @@ find_var(char **env, char *assignment, size_t len)
static int
read_env_file(FILE *F, char ***env, int *assigned)
{
- int idx = 0;
+ size_t alloced = 0;
+ size_t idx = 0;
int i;
char **l;
char buf[BUFSIZ], *p, *r;
@@ -71,8 +72,11 @@ read_env_file(FILE *F, char ***env, int *assigned)
*assigned = 0;
- for(idx = 0; *env != NULL && (*env)[idx] != NULL; idx++);
l = *env;
+ for (idx = 0; l != NULL && l[idx] != NULL; idx++)
+ ;
+ if (l)
+ alloced = idx + 1;
/* This is somewhat more relaxed on what it accepts then
* Wietses sysv_environ from K4 was...
@@ -90,7 +94,11 @@ read_env_file(FILE *F, char ***env, int *assigned)
continue;
if((i = find_var(l, p, r - p + 1)) >= 0) {
- char *val = strdup(p);
+ char *val;
+
+ if ((size_t)i >= alloced)
+ continue; /* Doesn't happen (fix scan-build noise) */
+ val = strdup(p);
if(val == NULL) {
ret = ENOMEM;
break;
@@ -114,6 +122,7 @@ read_env_file(FILE *F, char ***env, int *assigned)
break;
}
l[++idx] = NULL;
+ alloced = idx + 1;
(*assigned)++;
}
if(ferror(F))
diff --git a/third_party/heimdal/lib/roken/fnmatch.c b/third_party/heimdal/lib/roken/fnmatch.c
index 7dfe492179d..74f35283d35 100644
--- a/third_party/heimdal/lib/roken/fnmatch.c
+++ b/third_party/heimdal/lib/roken/fnmatch.c
@@ -129,7 +129,7 @@ rk_fnmatch(const char *pattern, const char *string, int flags)
--pattern;
}
}
- /* FALLTHROUGH */
+ fallthrough;
default:
if (c != *string++)
return (FNM_NOMATCH);
diff --git a/third_party/heimdal/lib/roken/freeaddrinfo.c b/third_party/heimdal/lib/roken/freeaddrinfo.c
index 7132e95dd38..80a7487b8d5 100644
--- a/third_party/heimdal/lib/roken/freeaddrinfo.c
+++ b/third_party/heimdal/lib/roken/freeaddrinfo.c
@@ -40,7 +40,7 @@
*/
ROKEN_LIB_FUNCTION void ROKEN_LIB_CALL
-freeaddrinfo(struct addrinfo *ai)
+rk_freeaddrinfo(struct addrinfo *ai)
{
struct addrinfo *tofree;
diff --git a/third_party/heimdal/lib/roken/freehostent.c b/third_party/heimdal/lib/roken/freehostent.c
index 61fbb223b5e..05dd0fe385c 100644
--- a/third_party/heimdal/lib/roken/freehostent.c
+++ b/third_party/heimdal/lib/roken/freehostent.c
@@ -40,7 +40,7 @@
*/
ROKEN_LIB_FUNCTION void ROKEN_LIB_CALL
-freehostent (struct hostent *h)
+rk_freehostent(struct hostent *h)
{
char **p;
diff --git a/third_party/heimdal/lib/roken/getaddrinfo.c b/third_party/heimdal/lib/roken/getaddrinfo.c
index c8ed95413fe..12a26a71225 100644
--- a/third_party/heimdal/lib/roken/getaddrinfo.c
+++ b/third_party/heimdal/lib/roken/getaddrinfo.c
@@ -366,10 +366,10 @@ get_nodes (const char *nodename,
*/
ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL
-getaddrinfo(const char *nodename,
- const char *servname,
- const struct addrinfo *hints,
- struct addrinfo **res)
+rk_getaddrinfo(const char *nodename,
+ const char *servname,
+ const struct addrinfo *hints,
+ struct addrinfo **res)
{
int ret;
int port = 0;
@@ -409,6 +409,6 @@ getaddrinfo(const char *nodename,
ret = get_null (hints, port, protocol, socktype, res);
}
if (ret)
- freeaddrinfo (*res);
+ rk_freeaddrinfo(*res);
return ret;
}
diff --git a/third_party/heimdal/lib/roken/getcap.c b/third_party/heimdal/lib/roken/getcap.c
deleted file mode 100644
index a8dd94bef9a..00000000000
--- a/third_party/heimdal/lib/roken/getcap.c
+++ /dev/null
@@ -1,996 +0,0 @@
-/* $NetBSD: getcap.c,v 1.29 1999/03/29 09:27:29 abs Exp $ */
-
-/*-
- * Copyright (c) 1992, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Casey Leedom of Lawrence Livermore National Laboratory.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include <config.h>
-
-#include "roken.h"
-
-#include <sys/types.h>
-#include <ctype.h>
-#if defined(HAVE_DB_185_H)
-#include <db_185.h>
-#elif defined(HAVE_DB_H)
-#include <db.h>
-#endif
-#include <errno.h>
-#include <fcntl.h>
-#include <limits.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-#define BFRAG 1024
-#define ESC ('[' & 037) /* ASCII ESC */
-#define MAX_RECURSION 32 /* maximum getent recursion */
-#define SFRAG 100 /* cgetstr mallocs in SFRAG chunks */
-
-#define RECOK (char)0
-#define TCERR (char)1
-#define SHADOW (char)2
-
-static size_t topreclen; /* toprec length */
-static char *toprec; /* Additional record specified by cgetset() */
-static int gottoprec; /* Flag indicating retrieval of toprecord */
-
-#ifdef USE_DB
-static int cdbget (DB *, char **, const char *);
-#endif
-static int getent (char **, size_t *, char **, int, const char *, int, char *);
-static int nfcmp (char *, char *);
-
-
-ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL cgetset(const char *ent);
-ROKEN_LIB_FUNCTION char * ROKEN_LIB_CALL cgetcap(char *buf, const char *cap, int type);
-ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL cgetent(char **buf, char **db_array, const char *name);
-ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL cgetmatch(const char *buf, const char *name);
-ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL cgetclose(void);
-ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL cgetstr(char *buf, const char *cap, char **str);
-ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL cgetustr(char *buf, const char *cap, char **str);
-ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL cgetnum(char *buf, const char *cap, long *num);
-/*
- * Cgetset() allows the addition of a user specified buffer to be added
- * to the database array, in effect "pushing" the buffer on top of the
- * virtual database. 0 is returned on success, -1 on failure.
- */
-ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL
-cgetset(const char *ent)
-{
- const char *source, *check;
- char *dest;
-
- if (ent == NULL) {
- if (toprec)
- free(toprec);
- toprec = NULL;
- topreclen = 0;
- return (0);
- }
- topreclen = strlen(ent);
- if ((toprec = malloc (topreclen + 1)) == NULL) {
- errno = ENOMEM;
- return (-1);
- }
- gottoprec = 0;
-
- source=ent;
- dest=toprec;
- while (*source) { /* Strip whitespace */
- *dest++ = *source++; /* Do not check first field */
- while (*source == ':') {
- check=source+1;
- while (*check && (isspace((unsigned char)*check) ||
- (*check=='\\' && isspace((unsigned char)check[1]))))
- ++check;
- if( *check == ':' )
- source=check;
- else
- break;
-
- }
- }
- *dest=0;
-
- return (0);
-}
-
-/*
- * Cgetcap searches the capability record buf for the capability cap with
- * type `type'. A pointer to the value of cap is returned on success, NULL
- * if the requested capability couldn't be found.
- *
- * Specifying a type of ':' means that nothing should follow cap (:cap:).
- * In this case a pointer to the terminating ':' or NUL will be returned if
- * cap is found.
- *
- * If (cap, '@') or (cap, terminator, '@') is found before (cap, terminator)
- * return NULL.
- */
-ROKEN_LIB_FUNCTION char * ROKEN_LIB_CALL
-cgetcap(char *buf, const char *cap, int type)
-{
- char *bp;
- const char *cp;
-
- bp = buf;
- for (;;) {
- /*
- * Skip past the current capability field - it's either the
- * name field if this is the first time through the loop, or
- * the remainder of a field whose name failed to match cap.
- */
- for (;;)
- if (*bp == '\0')
- return (NULL);
- else
- if (*bp++ == ':')
- break;
-
- /*
- * Try to match (cap, type) in buf.
- */
- for (cp = cap; *cp == *bp && *bp != '\0'; cp++, bp++)
- continue;
- if (*cp != '\0')
- continue;
- if (*bp == '@')
- return (NULL);
- if (type == ':') {
- if (*bp != '\0' && *bp != ':')
- continue;
- return(bp);
- }
- if (*bp != type)
- continue;
- bp++;
- return (*bp == '@' ? NULL : bp);
- }
- /* NOTREACHED */
-}
-
-/*
- * Cgetent extracts the capability record name from the NULL terminated file
- * array db_array and returns a pointer to a malloc'd copy of it in buf.
- * Buf must be retained through all subsequent calls to cgetcap, cgetnum,
- * cgetflag, and cgetstr, but may then be free'd. 0 is returned on success,
- * -1 if the requested record couldn't be found, -2 if a system error was
- * encountered (couldn't open/read a file, etc.), and -3 if a potential
- * reference loop is detected.
- */
-ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL
-cgetent(char **buf, char **db_array, const char *name)
-{
- size_t dummy;
-
- return (getent(buf, &dummy, db_array, -1, name, 0, NULL));
-}
-
-/*
- * Getent implements the functions of cgetent. If fd is non-negative,
- * *db_array has already been opened and fd is the open file descriptor. We
- * do this to save time and avoid using up file descriptors for tc=
- * recursions.
- *
- * Getent returns the same success/failure codes as cgetent. On success, a
- * pointer to a malloc'ed capability record with all tc= capabilities fully
- * expanded and its length (not including trailing ASCII NUL) are left in
- * *cap and *len.
- *
- * Basic algorithm:
- * + Allocate memory incrementally as needed in chunks of size BFRAG
- * for capability buffer.
- * + Recurse for each tc=name and interpolate result. Stop when all
- * names interpolated, a name can't be found, or depth exceeds
- * MAX_RECURSION.
- */
-static int
-getent(char **cap, size_t *len, char **db_array, int fd,
- const char *name, int depth, char *nfield)
-{
- char *r_end, *rp = NULL, **db_p; /* pacify gcc */
- int myfd = 0, eof, foundit;
- char *record;
- int tc_not_resolved;
-
- /*
- * Return with ``loop detected'' error if we've recursed more than
- * MAX_RECURSION times.
- */
- if (depth > MAX_RECURSION)
- return (-3);
-
- /*
- * Check if we have a top record from cgetset().
- */
- if (depth == 0 && toprec != NULL && cgetmatch(toprec, name) == 0) {
- size_t tmplen = topreclen + BFRAG;
- if ((record = malloc (tmplen)) == NULL) {
- errno = ENOMEM;
- return (-2);
- }
- (void)strlcpy(record, toprec, tmplen);
- db_p = db_array;
- rp = record + topreclen + 1;
- r_end = rp + BFRAG;
- goto tc_exp;
- }
- /*
- * Allocate first chunk of memory.
- */
- if ((record = malloc(BFRAG)) == NULL) {
- errno = ENOMEM;
- return (-2);
- }
- r_end = record + BFRAG;
- foundit = 0;
- /*
- * Loop through database array until finding the record.
- */
-
- for (db_p = db_array; *db_p != NULL; db_p++) {
- eof = 0;
-
- /*
- * Open database if not already open.
- */
-
- if (fd >= 0) {
- (void)lseek(fd, (off_t)0, SEEK_SET);
- } else {
-#ifdef USE_DB
- char pbuf[_POSIX_PATH_MAX];
- char *cbuf;
- size_t clen;
- int retval;
- DB *capdbp;
-
- (void)snprintf(pbuf, sizeof(pbuf), "%s.db", *db_p);
- if ((capdbp = dbopen(pbuf, O_RDONLY, 0, DB_HASH, 0))
- != NULL) {
- free(record);
- retval = cdbget(capdbp, &record, name);
- /* record is no longer for us to free here */
- if (retval < 0) {
- /* no record available */
- (void)capdbp->close(capdbp);
- return (retval);
- }
- /* save the data; close frees it */
- clen = strlen(record);
- cbuf = malloc(clen + 1);
- if (cbuf == NULL)
- return (-2);
- memmove(cbuf, record, clen + 1);
- if (capdbp->close(capdbp) < 0) {
- free(cbuf);
- return (-2);
- }
- *len = clen;
- *cap = cbuf;
- return (retval);
- } else
-#endif
- {
- fd = open(*db_p, O_RDONLY, 0);
- if (fd < 0) {
- /* No error on unfound file. */
- continue;
- }
- myfd = 1;
- }
- }
- /*
- * Find the requested capability record ...
- */
- {
- char buf[BUFSIZ];
- char *b_end, *bp, *cp;
- int c, slash;
-
- /*
- * Loop invariants:
- * There is always room for one more character in record.
- * R_end always points just past end of record.
- * Rp always points just past last character in record.
- * B_end always points just past last character in buf.
- * Bp always points at next character in buf.
- * Cp remembers where the last colon was.
- */
- b_end = buf;
- bp = buf;
- cp = 0;
- slash = 0;
- for (;;) {
-
- /*
- * Read in a line implementing (\, newline)
- * line continuation.
- */
- rp = record;
- for (;;) {
- if (bp >= b_end) {
- int n;
-
- n = read(fd, buf, sizeof(buf));
- if (n <= 0) {
- if (myfd)
- (void)close(fd);
- if (n < 0) {
- free(record);
- return (-2);
- } else {
- fd = -1;
- eof = 1;
- break;
- }
- }
- b_end = buf+n;
- bp = buf;
- }
-
- c = *bp++;
- if (c == '\n') {
- if (slash) {
- slash = 0;
- rp--;
- continue;
- } else
- break;
- }
- if (slash) {
- slash = 0;
- cp = 0;
- }
- if (c == ':') {
- /*
- * If the field was `empty' (i.e.
- * contained only white space), back up
- * to the colon (eliminating the
- * field).
- */
- if (cp)
- rp = cp;
- else
- cp = rp;
- } else if (c == '\\') {
- slash = 1;
- } else if (c != ' ' && c != '\t') {
- /*
- * Forget where the colon was, as this
- * is not an empty field.
- */
- cp = 0;
- }
- *rp++ = c;
-
- /*
- * Enforce loop invariant: if no room
- * left in record buffer, try to get
- * some more.
- */
- if (rp >= r_end) {
- u_int pos;
- char *tmp;
- size_t newsize;
-
- pos = rp - record;
- newsize = r_end - record + BFRAG;
- tmp = realloc(record, newsize);
- if (tmp == NULL) {
- errno = ENOMEM;
- if (myfd)
- (void)close(fd);
- free(record);
- return (-2);
- }
- record = tmp;
- r_end = record + newsize;
- rp = record + pos;
- }
- }
- /* Eliminate any white space after the last colon. */
- if (cp)
- rp = cp + 1;
- /* Loop invariant lets us do this. */
- *rp++ = '\0';
-
- /*
- * If encountered eof check next file.
- */
- if (eof)
- break;
-
- /*
- * Toss blank lines and comments.
- */
- if (*record == '\0' || *record == '#')
- continue;
-
- /*
- * See if this is the record we want ...
- */
- if (cgetmatch(record, name) == 0) {
- if (nfield == NULL || !nfcmp(nfield, record)) {
- foundit = 1;
- break; /* found it! */
- }
- }
- }
- }
- if (foundit)
- break;
- }
-
- if (!foundit) {
- free(record);
- return (-1);
- }
-
- /*
- * Got the capability record, but now we have to expand all tc=name
- * references in it ...
- */
- tc_exp: {
- char *newicap, *s;
- size_t ilen, newilen;
- int diff, iret, tclen;
- char *icap, *scan, *tc, *tcstart, *tcend;
-
- /*
- * Loop invariants:
- * There is room for one more character in record.
- * R_end points just past end of record.
- * Rp points just past last character in record.
- * Scan points at remainder of record that needs to be
- * scanned for tc=name constructs.
- */
- scan = record;
- tc_not_resolved = 0;
- for (;;) {
- if ((tc = cgetcap(scan, "tc", '=')) == NULL)
- break;
-
- /*
- * Find end of tc=name and stomp on the trailing `:'
- * (if present) so we can use it to call ourselves.
- */
- s = tc;
- for (;;)
- if (*s == '\0')
- break;
- else
- if (*s++ == ':') {
- *(s - 1) = '\0';
- break;
- }
- tcstart = tc - 3;
- tclen = s - tcstart;
- tcend = s;
-
- iret = getent(&icap, &ilen, db_p, fd, tc, depth+1,
- NULL);
- newicap = icap; /* Put into a register. */
- newilen = ilen;
- if (iret != 0) {
- /* an error */
- if (iret < -1) {
- if (myfd)
- (void)close(fd);
- free(record);
- return (iret);
- }
- if (iret == 1)
- tc_not_resolved = 1;
- /* couldn't resolve tc */
- if (iret == -1) {
- *(s - 1) = ':';
- scan = s - 1;
- tc_not_resolved = 1;
- continue;
-
- }
- }
- /* not interested in name field of tc'ed record */
- s = newicap;
- for (;;)
- if (*s == '\0')
- break;
- else
- if (*s++ == ':')
- break;
- newilen -= s - newicap;
- newicap = s;
-
- /* make sure interpolated record is `:'-terminated */
- s += newilen;
- if (*(s-1) != ':') {
- *s = ':'; /* overwrite NUL with : */
- newilen++;
- }
-
- /*
- * Make sure there's enough room to insert the
- * new record.
- */
- diff = newilen - tclen;
- if (diff >= r_end - rp) {
- u_int pos, tcpos, tcposend;
- size_t newsize;
- char *tmp;
-
- pos = rp - record;
- newsize = r_end - record + diff + BFRAG;
- tcpos = tcstart - record;
- tcposend = tcend - record;
- tmp = realloc(record, newsize);
- if (tmp == NULL) {
- errno = ENOMEM;
- if (myfd)
- (void)close(fd);
- free(icap);
- free(record);
- return (-2);
- }
- record = tmp;
- r_end = record + newsize;
- rp = record + pos;
- tcstart = record + tcpos;
- tcend = record + tcposend;
- }
-
- /*
- * Insert tc'ed record into our record.
- */
- s = tcstart + newilen;
- memmove(s, tcend, (size_t)(rp - tcend));
- memmove(tcstart, newicap, newilen);
- rp += diff;
- free(icap);
-
- /*
- * Start scan on `:' so next cgetcap works properly
- * (cgetcap always skips first field).
- */
- scan = s-1;
- }
-
- }
- /*
- * Close file (if we opened it), give back any extra memory, and
- * return capability, length and success.
- */
- if (myfd)
- (void)close(fd);
- *len = rp - record - 1; /* don't count NUL */
- if (r_end > rp) {
- char *tmp = realloc(record, (size_t)(rp - record));
- if (tmp == NULL) {
- errno = ENOMEM;
- free(record);
- return (-2);
- }
- record = tmp;
- }
-
- *cap = record;
- if (tc_not_resolved)
- return (1);
- return (0);
-}
-
-#ifdef USE_DB
-static int
-cdbget(DB *capdbp, char **bp, const char *name)
-{
- DBT key;
- DBT data;
-
- /* LINTED key is not modified */
- key.data = (char *)name;
- key.size = strlen(name);
-
- for (;;) {
- /* Get the reference. */
- switch(capdbp->get(capdbp, &key, &data, 0)) {
- case -1:
- return (-2);
- case 1:
- return (-1);
- }
-
- /* If not an index to another record, leave. */
- if (((char *)data.data)[0] != SHADOW)
- break;
-
- key.data = (char *)data.data + 1;
- key.size = data.size - 1;
- }
-
- *bp = (char *)data.data + 1;
- return (((char *)(data.data))[0] == TCERR ? 1 : 0);
-}
-#endif /* USE_DB */
-
-/*
- * Cgetmatch will return 0 if name is one of the names of the capability
- * record buf, -1 if not.
- */
-int
-cgetmatch(const char *buf, const char *name)
-{
- const char *np, *bp;
-
- /*
- * Start search at beginning of record.
- */
- bp = buf;
- for (;;) {
- /*
- * Try to match a record name.
- */
- np = name;
- for (;;)
- if (*np == '\0') {
- if (*bp == '|' || *bp == ':' || *bp == '\0')
- return (0);
- else
- break;
- } else
- if (*bp++ != *np++)
- break;
-
- /*
- * Match failed, skip to next name in record.
- */
- bp--; /* a '|' or ':' may have stopped the match */
- for (;;)
- if (*bp == '\0' || *bp == ':')
- return (-1); /* match failed totally */
- else
- if (*bp++ == '|')
- break; /* found next name */
- }
-}
-
-static FILE *pfp;
-static int slash;
-static char **dbp;
-
-ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL
-cgetclose(void)
-{
- if (pfp != NULL) {
- (void)fclose(pfp);
- pfp = NULL;
- }
- dbp = NULL;
- gottoprec = 0;
- slash = 0;
- return(0);
-}
-
-/*
- * Cgetstr retrieves the value of the string capability cap from the
- * capability record pointed to by buf. A pointer to a decoded, NUL
- * terminated, malloc'd copy of the string is returned in the char *
- * pointed to by str. The length of the string not including the trailing
- * NUL is returned on success, -1 if the requested string capability
- * couldn't be found, -2 if a system error was encountered (storage
- * allocation failure).
- */
-ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL
-cgetstr(char *buf, const char *cap, char **str)
-{
- u_int m_room;
- const char *bp;
- char *mp;
- int len;
- char *mem, *nmem;
-
- *str = NULL;
-
- /*
- * Find string capability cap
- */
- bp = cgetcap(buf, cap, '=');
- if (bp == NULL)
- return (-1);
-
- /*
- * Conversion / storage allocation loop ... Allocate memory in
- * chunks SFRAG in size.
- */
- if ((mem = malloc(SFRAG)) == NULL) {
- errno = ENOMEM;
- return (-2); /* couldn't even allocate the first fragment */
- }
- m_room = SFRAG;
- mp = mem;
-
- while (*bp != ':' && *bp != '\0') {
- /*
- * Loop invariants:
- * There is always room for one more character in mem.
- * Mp always points just past last character in mem.
- * Bp always points at next character in buf.
- */
- if (*bp == '^') {
- bp++;
- if (*bp == ':' || *bp == '\0')
- break; /* drop unfinished escape */
- *mp++ = *bp++ & 037;
- } else if (*bp == '\\') {
- bp++;
- if (*bp == ':' || *bp == '\0')
- break; /* drop unfinished escape */
- if ('0' <= *bp && *bp <= '7') {
- int n, i;
-
- n = 0;
- i = 3; /* maximum of three octal digits */
- do {
- n = n * 8 + (*bp++ - '0');
- } while (--i && '0' <= *bp && *bp <= '7');
- *mp++ = n;
- }
- else switch (*bp++) {
- case 'b': case 'B':
- *mp++ = '\b';
- break;
- case 't': case 'T':
- *mp++ = '\t';
- break;
- case 'n': case 'N':
- *mp++ = '\n';
- break;
- case 'f': case 'F':
- *mp++ = '\f';
- break;
- case 'r': case 'R':
- *mp++ = '\r';
- break;
- case 'e': case 'E':
- *mp++ = ESC;
- break;
- case 'c': case 'C':
- *mp++ = ':';
- break;
- default:
- /*
- * Catches '\', '^', and
- * everything else.
- */
- *mp++ = *(bp-1);
- break;
- }
- } else
- *mp++ = *bp++;
- m_room--;
-
- /*
- * Enforce loop invariant: if no room left in current
- * buffer, try to get some more.
- */
- if (m_room == 0) {
- size_t size = mp - mem;
-
- if ((nmem = realloc(mem, size + SFRAG)) == NULL) {
- free(mem);
- return (-2);
- }
- mem = nmem;
- m_room = SFRAG;
- mp = mem + size;
- }
- }
- *mp++ = '\0'; /* loop invariant let's us do this */
- m_room--;
- len = mp - mem - 1;
-
- /*
- * Give back any extra memory and return value and success.
- */
- if (m_room != 0) {
- if ((nmem = realloc(mem, (size_t)(mp - mem))) == NULL) {
- free(mem);
- return (-2);
- }
- mem = nmem;
- }
- *str = mem;
- return (len);
-}
-
-/*
- * Cgetustr retrieves the value of the string capability cap from the
- * capability record pointed to by buf. The difference between cgetustr()
- * and cgetstr() is that cgetustr does not decode escapes but rather treats
- * all characters literally. A pointer to a NUL terminated malloc'd
- * copy of the string is returned in the char pointed to by str. The
- * length of the string not including the trailing NUL is returned on success,
- * -1 if the requested string capability couldn't be found, -2 if a system
- * error was encountered (storage allocation failure).
- */
-ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL
-cgetustr(char *buf, const char *cap, char **str)
-{
- u_int m_room;
- const char *bp;
- char *mp;
- int len;
- char *mem;
-
- /*
- * Find string capability cap
- */
- if ((bp = cgetcap(buf, cap, '=')) == NULL)
- return (-1);
-
- /*
- * Conversion / storage allocation loop ... Allocate memory in
- * chunks SFRAG in size.
- */
- if ((mem = malloc(SFRAG)) == NULL) {
- errno = ENOMEM;
- return (-2); /* couldn't even allocate the first fragment */
- }
- m_room = SFRAG;
- mp = mem;
-
- while (*bp != ':' && *bp != '\0') {
- /*
- * Loop invariants:
- * There is always room for one more character in mem.
- * Mp always points just past last character in mem.
- * Bp always points at next character in buf.
- */
- *mp++ = *bp++;
- m_room--;
-
- /*
- * Enforce loop invariant: if no room left in current
- * buffer, try to get some more.
- */
- if (m_room == 0) {
- size_t size = mp - mem;
-
- if ((mem = realloc(mem, size + SFRAG)) == NULL)
- return (-2);
- m_room = SFRAG;
- mp = mem + size;
- }
- }
- *mp++ = '\0'; /* loop invariant let's us do this */
- m_room--;
- len = mp - mem - 1;
-
- /*
- * Give back any extra memory and return value and success.
- */
- if (m_room != 0) {
- char *tmp = realloc(mem, (size_t)(mp - mem));
- if (tmp == NULL) {
- free(mem);
- return (-2);
- }
- mem = tmp;
- }
- *str = mem;
- return (len);
-}
-
-/*
- * Cgetnum retrieves the value of the numeric capability cap from the
- * capability record pointed to by buf. The numeric value is returned in
- * the long pointed to by num. 0 is returned on success, -1 if the requested
- * numeric capability couldn't be found.
- */
-ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL
-cgetnum(char *buf, const char *cap, long *num)
-{
- long n;
- int base, digit;
- const char *bp;
-
- /*
- * Find numeric capability cap
- */
- bp = cgetcap(buf, cap, '#');
- if (bp == NULL)
- return (-1);
-
- /*
- * Look at value and determine numeric base:
- * 0x... or 0X... hexadecimal,
- * else 0... octal,
- * else decimal.
- */
- if (*bp == '0') {
- bp++;
- if (*bp == 'x' || *bp == 'X') {
- bp++;
- base = 16;
- } else
- base = 8;
- } else
- base = 10;
-
- /*
- * Conversion loop ...
- */
- n = 0;
- for (;;) {
- if ('0' <= *bp && *bp <= '9')
- digit = *bp - '0';
- else if ('a' <= *bp && *bp <= 'f')
- digit = 10 + *bp - 'a';
- else if ('A' <= *bp && *bp <= 'F')
- digit = 10 + *bp - 'A';
- else
- break;
-
- if (digit >= base)
- break;
-
- n = n * base + digit;
- bp++;
- }
-
- /*
- * Return value and success.
- */
- *num = n;
- return (0);
-}
-
-
-/*
- * Compare name field of record.
- */
-static int
-nfcmp(char *nf, char *rec)
-{
- char *cp, tmp;
- int ret;
-
- for (cp = rec; *cp != ':'; cp++)
- ;
-
- tmp = *(cp + 1);
- *(cp + 1) = '\0';
- ret = strcmp(nf, rec);
- *(cp + 1) = tmp;
-
- return (ret);
-}
diff --git a/third_party/heimdal/lib/roken/getipnodebyaddr.c b/third_party/heimdal/lib/roken/getipnodebyaddr.c
index 7d4095f1d84..afebe914950 100644
--- a/third_party/heimdal/lib/roken/getipnodebyaddr.c
+++ b/third_party/heimdal/lib/roken/getipnodebyaddr.c
@@ -41,7 +41,7 @@
*/
ROKEN_LIB_FUNCTION struct hostent * ROKEN_LIB_CALL
-getipnodebyaddr (const void *src, size_t len, int af, int *error_num)
+rk_getipnodebyaddr(const void *src, size_t len, int af, int *error_num)
{
struct hostent *tmp;
diff --git a/third_party/heimdal/lib/roken/getipnodebyname.c b/third_party/heimdal/lib/roken/getipnodebyname.c
index 2ff282707c2..ee430c76eb6 100644
--- a/third_party/heimdal/lib/roken/getipnodebyname.c
+++ b/third_party/heimdal/lib/roken/getipnodebyname.c
@@ -45,7 +45,7 @@ static int h_errno = NO_RECOVERY;
*/
ROKEN_LIB_FUNCTION struct hostent * ROKEN_LIB_CALL
-getipnodebyname (const char *name, int af, int flags, int *error_num)
+rk_getipnodebyname(const char *name, int af, int flags, int *error_num)
{
struct hostent *tmp;
diff --git a/third_party/heimdal/lib/roken/getnameinfo.c b/third_party/heimdal/lib/roken/getnameinfo.c
index b23ad01ebdd..9d118600f26 100644
--- a/third_party/heimdal/lib/roken/getnameinfo.c
+++ b/third_party/heimdal/lib/roken/getnameinfo.c
@@ -92,10 +92,10 @@ doit (int af,
*/
ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL
-getnameinfo(const struct sockaddr *sa, socklen_t salen,
- char *host, size_t hostlen,
- char *serv, size_t servlen,
- int flags)
+rk_getnameinfo(const struct sockaddr *sa, socklen_t salen,
+ char *host, size_t hostlen,
+ char *serv, size_t servlen,
+ int flags)
{
switch (sa->sa_family) {
#ifdef HAVE_IPV6
diff --git a/third_party/heimdal/lib/roken/getuserinfo.c b/third_party/heimdal/lib/roken/getuserinfo.c
index 76cd78241be..7fd2ca9f151 100644
--- a/third_party/heimdal/lib/roken/getuserinfo.c
+++ b/third_party/heimdal/lib/roken/getuserinfo.c
@@ -53,12 +53,12 @@ roken_get_shell(char *shell, size_t shellsz)
char *p;
#ifndef WIN32
- char user[128];
- const char *username = roken_get_username(user, sizeof(user));
+#ifdef HAVE_GETPWNAM_R
size_t buflen = 2048;
if (sysconf(_SC_GETPW_R_SIZE_MAX) > 0)
buflen = sysconf(_SC_GETPW_R_SIZE_MAX);
+#endif
if (issuid())
return "/bin/sh";
@@ -76,8 +76,11 @@ roken_get_shell(char *shell, size_t shellsz)
struct passwd pwd;
struct passwd *pwdp;
char buf[buflen];
+ char user[128];
+ const char *username = roken_get_username(user, sizeof(user));
- if (getpwnam_r(username, &pwd, buf, buflen, &pwdp) == 0 &&
+ if (username &&
+ getpwnam_r(username, &pwd, buf, buflen, &pwdp) == 0 &&
pwdp != NULL && pwdp->pw_shell != NULL) {
if (strlcpy(shell, pwdp->pw_shell, shellsz) < shellsz)
return shell;
@@ -133,14 +136,14 @@ roken_get_homedir(char *home, size_t homesz)
}
return home;
}
- /* Fallthru to return NULL */
+ fallthrough;
#else
- char user[128];
- const char *username = roken_get_username(user, sizeof(user));
+#ifdef HAVE_GETPWNAM_R
size_t buflen = 2048;
if (sysconf(_SC_GETPW_R_SIZE_MAX) > 0)
buflen = sysconf(_SC_GETPW_R_SIZE_MAX);
+#endif
if (issuid()) {
errno = 0;
@@ -156,12 +159,15 @@ roken_get_homedir(char *home, size_t homesz)
}
#ifdef HAVE_GETPWNAM_R
- if (username) {
+ {
+ char user[128];
+ const char *username = roken_get_username(user, sizeof(user));
struct passwd pwd;
struct passwd *pwdp;
char buf[buflen];
- if (getpwnam_r(username, &pwd, buf, buflen, &pwdp) == 0 &&
+ if (username &&
+ getpwnam_r(username, &pwd, buf, buflen, &pwdp) == 0 &&
pwdp != NULL && pwdp->pw_dir != NULL) {
if (strlcpy(home, pwdp->pw_dir, homesz) < homesz)
return home;
@@ -255,8 +261,13 @@ roken_get_username(char *user, size_t usersz)
}
}
#else
+#ifdef HAVE_GETPWUID_R
size_t buflen = 2048;
+ if (sysconf(_SC_GETPW_R_SIZE_MAX) > 0)
+ buflen = sysconf(_SC_GETPW_R_SIZE_MAX);
+#endif
+
p = secure_getenv("USER");
if (p == NULL || p[0] == '\0')
p = secure_getenv("LOGNAME");
@@ -268,9 +279,6 @@ roken_get_username(char *user, size_t usersz)
}
#ifdef HAVE_GETPWUID_R
- if (sysconf(_SC_GETPW_R_SIZE_MAX) > 0)
- buflen = sysconf(_SC_GETPW_R_SIZE_MAX);
-
{
struct passwd pwd;
struct passwd *pwdp;
diff --git a/third_party/heimdal/lib/roken/hex-test.c b/third_party/heimdal/lib/roken/hex-test.c
index a81422e1f4a..01f21c821d1 100644
--- a/third_party/heimdal/lib/roken/hex-test.c
+++ b/third_party/heimdal/lib/roken/hex-test.c
@@ -43,7 +43,7 @@ main(int argc, char **argv)
int numtest = 1;
struct test {
void *data;
- size_t len;
+ ssize_t len;
const char *result;
} *t, tests[] = {
{ "", 0 , "" },
@@ -55,26 +55,35 @@ main(int argc, char **argv)
{ "abcdef", 6, "616263646566" },
{ "abcdefg", 7, "61626364656667" },
{ "=", 1, "3D" },
+ /* Embedded NUL, non-ASCII / binary */
+ { "\0\x01\x1a\xad\xf1\xff", 6, "00011AADF1FF" },
+ /* Invalid encodings */
+ { "", -1, "00.11AADF1FF" },
+ { "", -1, "000x1AADF1FF" },
+ { "", -1, "00011?ADF1FF" },
{ NULL, 0, NULL }
};
for(t = tests; t->data; t++) {
+ ssize_t len;
char *str;
- int len;
- len = hex_encode(t->data, t->len, &str);
- if(strcmp(str, t->result) != 0) {
- fprintf(stderr, "failed test %d: %s != %s\n", numtest,
- str, t->result);
- numerr++;
- }
- free(str);
+
+ if (t->len > -1) {
+ (void) hex_encode(t->data, t->len, &str);
+ if (strcmp(str, t->result) != 0) {
+ fprintf(stderr, "failed test %d: %s != %s\n", numtest,
+ str, t->result);
+ numerr++;
+ }
+ free(str);
+ }
str = strdup(t->result);
len = strlen(str);
len = hex_decode(t->result, str, len);
- if(len != t->len) {
- fprintf(stderr, "failed test %d: len %lu != %lu\n", numtest,
- (unsigned long)len, (unsigned long)t->len);
+ if (len != t->len) {
+ fprintf(stderr, "failed test %d: len %lu != %ld\n", numtest,
+ (long)len, (long)t->len);
numerr++;
- } else if(memcmp(str, t->data, t->len) != 0) {
+ } else if (t->len > -1 && memcmp(str, t->data, t->len) != 0) {
fprintf(stderr, "failed test %d: data\n", numtest);
numerr++;
}
diff --git a/third_party/heimdal/lib/roken/hex.c b/third_party/heimdal/lib/roken/hex.c
index c66b324f790..cc47fa4d52d 100644
--- a/third_party/heimdal/lib/roken/hex.c
+++ b/third_party/heimdal/lib/roken/hex.c
@@ -39,14 +39,15 @@
static const char hexchar[16] = "0123456789ABCDEF";
-static int
+static inline int
pos(char c)
{
- const char *p;
- c = toupper((unsigned char)c);
- for (p = hexchar; *p; p++)
- if (*p == c)
- return p - hexchar;
+ if (c >= '0' && c <= '9')
+ return c - '0';
+ if (c >= 'A' && c <= 'F')
+ return 10 + c - 'A';
+ if (c >= 'a' && c <= 'f')
+ return 10 + c - 'a';
return -1;
}
@@ -86,6 +87,7 @@ hex_decode(const char *str, void *data, size_t len)
size_t l;
unsigned char *p = data;
size_t i;
+ int d;
l = strlen(str);
@@ -94,11 +96,19 @@ hex_decode(const char *str, void *data, size_t len)
return -1;
if (l & 1) {
- p[0] = pos(str[0]);
+ if ((d = pos(str[0])) == -1)
+ return -1;
+ p[0] = d;
str++;
p++;
}
- for (i = 0; i < l / 2; i++)
- p[i] = pos(str[i * 2]) << 4 | pos(str[(i * 2) + 1]);
+ for (i = 0; i < l / 2; i++) {
+ if ((d = pos(str[i * 2])) == -1)
+ return -1;
+ p[i] = d << 4;
+ if ((d = pos(str[(i * 2) + 1])) == -1)
+ return -1;
+ p[i] |= d;
+ }
return i + (l & 1);
}
diff --git a/third_party/heimdal/lib/roken/mergesort_r.c b/third_party/heimdal/lib/roken/mergesort_r.c
index 2d551a607a2..39b0301c454 100644
--- a/third_party/heimdal/lib/roken/mergesort_r.c
+++ b/third_party/heimdal/lib/roken/mergesort_r.c
@@ -85,7 +85,7 @@ static void insertionsort(u_char *, size_t, size_t, cmp_t, void *);
*/
/* Assumption: PSIZE is a power of 2. */
#define EVAL(p) (u_char **) \
- ((((u_char *)p + PSIZE - 1 - (u_char *) 0) & ~(PSIZE - 1)))
+ ((((uintptr_t)p + PSIZE - 1) & ~(PSIZE - 1)))
/*
* Arguments are as for qsort_r, except thunk is moved to the last
@@ -114,7 +114,7 @@ mergesort_r(void *base, size_t nmemb, size_t size, cmp_t cmp, void *thunk)
* Stupid subtraction for the Cray.
*/
iflag = 0;
- if (!(size % ISIZE) && !(((char *)base - (char *)0) % ISIZE))
+ if (!(size % ISIZE) && !(((uintptr_t)base) % ISIZE))
iflag = 1;
if ((list2 = malloc(nmemb * size + PSIZE)) == NULL)
diff --git a/third_party/heimdal/lib/roken/ndbm_wrap.c b/third_party/heimdal/lib/roken/ndbm_wrap.c
index f7b87f1203e..f8403da44ab 100644
--- a/third_party/heimdal/lib/roken/ndbm_wrap.c
+++ b/third_party/heimdal/lib/roken/ndbm_wrap.c
@@ -36,6 +36,8 @@
#include "ndbm_wrap.h"
#if defined(HAVE_DBHEADER)
#include <db.h>
+#elif defined(HAVE_DB6_DB_H)
+#include <db6/db.h>
#elif defined(HAVE_DB5_DB_H)
#include <db5/db.h>
#elif defined(HAVE_DB4_DB_H)
diff --git a/third_party/heimdal/lib/roken/net_write.c b/third_party/heimdal/lib/roken/net_write.c
index 1e8361999ea..e66f56b7595 100644
--- a/third_party/heimdal/lib/roken/net_write.c
+++ b/third_party/heimdal/lib/roken/net_write.c
@@ -71,7 +71,7 @@ net_write (rk_socket_t fd, const void *buf, size_t nbytes)
return nbytes;
}
-#else
+#else /* defined(_WIN32) */
ROKEN_LIB_FUNCTION ssize_t ROKEN_LIB_CALL
net_write(rk_socket_t sock, const void *buf, size_t nbytes)
@@ -102,6 +102,7 @@ net_write(rk_socket_t sock, const void *buf, size_t nbytes)
count = send (sock, cbuf, rem, 0);
#endif
if (count < 0) {
+#ifdef SOCKET_IS_NOT_AN_FD
if (!use_write) {
switch (rk_SOCK_ERRNO) {
case WSAEINTR:
@@ -111,7 +112,9 @@ net_write(rk_socket_t sock, const void *buf, size_t nbytes)
default:
return count;
}
- } else {
+ } else
+#endif
+ {
switch (errno) {
case EINTR:
continue;
diff --git a/third_party/heimdal/lib/roken/resolve-test.c b/third_party/heimdal/lib/roken/resolve-test.c
index 25cc98aafe3..581600a5937 100644
--- a/third_party/heimdal/lib/roken/resolve-test.c
+++ b/third_party/heimdal/lib/roken/resolve-test.c
@@ -159,7 +159,7 @@ test_rk_dns_srv_order(size_t run)
if (rr->u.srv->priority < prio0 ||
(rr->u.srv->priority != prio0 &&
(i % 4 != 0 || rr->u.srv->priority > prio0 + 1))) {
- printf("SRV RR order run %lu failed\n", run);
+ printf("SRV RR order run %zu failed\n", run);
fail = 1;
}
prio0 = rr->u.srv->priority;
diff --git a/third_party/heimdal/lib/roken/roken-common.h b/third_party/heimdal/lib/roken/roken-common.h
index f05f88668f3..035b99b8b97 100644
--- a/third_party/heimdal/lib/roken/roken-common.h
+++ b/third_party/heimdal/lib/roken/roken-common.h
@@ -472,6 +472,12 @@ vstrcollect(va_list *ap);
ROKEN_LIB_FUNCTION char ** ROKEN_LIB_CALL
strcollect(char *first, ...);
+ROKEN_LIB_FUNCTION time_t ROKEN_LIB_CALL
+rk_time_add(time_t, time_t);
+
+ROKEN_LIB_FUNCTION time_t ROKEN_LIB_CALL
+rk_time_sub(time_t, time_t);
+
#define timevalfix rk_timevalfix
ROKEN_LIB_FUNCTION void ROKEN_LIB_CALL
timevalfix(struct timeval *t1);
diff --git a/third_party/heimdal/lib/roken/roken.h.in b/third_party/heimdal/lib/roken/roken.h.in
index e1aa6b7b60c..e1902f582dc 100644
--- a/third_party/heimdal/lib/roken/roken.h.in
+++ b/third_party/heimdal/lib/roken/roken.h.in
@@ -356,7 +356,12 @@ ROKEN_CPP_START
#define fsync _commit
-/* The MSVC implementation of snprintf is not C99 compliant. */
+#define _PIPE_BUFFER_SZ 8192
+#define pipe(fds) _pipe((fds), _PIPE_BUFFER_SZ, O_BINARY);
+
+#define ftruncate(fd, sz) _chsize((fd), (sz))
+
+#if !defined(HAVE_UCRT)
#define snprintf rk_snprintf
#define vsnprintf rk_vsnprintf
#define vasnprintf rk_vasnprintf
@@ -364,11 +369,6 @@ ROKEN_CPP_START
#define asnprintf rk_asnprintf
#define asprintf rk_asprintf
-#define _PIPE_BUFFER_SZ 8192
-#define pipe(fds) _pipe((fds), _PIPE_BUFFER_SZ, O_BINARY);
-
-#define ftruncate(fd, sz) _chsize((fd), (sz))
-
ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL
rk_snprintf (char *str, size_t sz, const char *format, ...);
@@ -386,6 +386,7 @@ rk_vasnprintf (char **ret, size_t max_sz, const char *format, va_list args);
ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL
rk_vsnprintf (char *str, size_t sz, const char *format, va_list args);
+#endif /* !defined(HAVE_UCRT) */
/* missing stat.h predicates */
@@ -716,13 +717,6 @@ ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL mkostemp(char *, int);
ROKEN_LIB_FUNCTION char * ROKEN_LIB_CALL mkdtemp(char *);
#endif
-#ifndef HAVE_CGETENT
-#define cgetent rk_cgetent
-#define cgetstr rk_cgetstr
-ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL cgetent(char **, char **, const char *);
-ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL cgetstr(char *, const char *, char **);
-#endif
-
#ifndef HAVE_INITGROUPS
#define initgroups rk_initgroups
ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL initgroups(const char *, gid_t);
@@ -912,27 +906,27 @@ ROKEN_LIB_VARIABLE extern int opterr;
#ifndef HAVE_GETIPNODEBYNAME
#define getipnodebyname rk_getipnodebyname
-ROKEN_LIB_FUNCTION struct hostent * ROKEN_LIB_CALL
-getipnodebyname (const char *, int, int, int *);
#endif
+ROKEN_LIB_FUNCTION struct hostent * ROKEN_LIB_CALL
+rk_getipnodebyname(const char *, int, int, int *);
#ifndef HAVE_GETIPNODEBYADDR
#define getipnodebyaddr rk_getipnodebyaddr
-ROKEN_LIB_FUNCTION struct hostent * ROKEN_LIB_CALL
-getipnodebyaddr (const void *, size_t, int, int *);
#endif
+ROKEN_LIB_FUNCTION struct hostent * ROKEN_LIB_CALL
+rk_getipnodebyaddr(const void *, size_t, int, int *);
#ifndef HAVE_FREEHOSTENT
#define freehostent rk_freehostent
-ROKEN_LIB_FUNCTION void ROKEN_LIB_CALL
-freehostent (struct hostent *);
#endif
+ROKEN_LIB_FUNCTION void ROKEN_LIB_CALL
+rk_freehostent(struct hostent *);
#ifndef HAVE_COPYHOSTENT
#define copyhostent rk_copyhostent
-ROKEN_LIB_FUNCTION struct hostent * ROKEN_LIB_CALL
-copyhostent (const struct hostent *);
#endif
+ROKEN_LIB_FUNCTION struct hostent * ROKEN_LIB_CALL
+rk_copyhostent(const struct hostent *);
#ifndef HAVE_SOCKLEN_T
typedef int socklen_t;
@@ -998,27 +992,27 @@ struct addrinfo {
#ifndef HAVE_GETADDRINFO
#define getaddrinfo rk_getaddrinfo
-ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL
-getaddrinfo(const char *,
- const char *,
- const struct addrinfo *,
- struct addrinfo **);
#endif
+ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL
+rk_getaddrinfo(const char *,
+ const char *,
+ const struct addrinfo *,
+ struct addrinfo **);
#ifndef HAVE_GETNAMEINFO
#define getnameinfo rk_getnameinfo
-ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL
-getnameinfo(const struct sockaddr *, socklen_t,
- char *, size_t,
- char *, size_t,
- int);
#endif
+ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL
+rk_getnameinfo(const struct sockaddr *, socklen_t,
+ char *, size_t,
+ char *, size_t,
+ int);
#ifndef HAVE_FREEADDRINFO
#define freeaddrinfo rk_freeaddrinfo
-ROKEN_LIB_FUNCTION void ROKEN_LIB_CALL
-freeaddrinfo(struct addrinfo *);
#endif
+ROKEN_LIB_FUNCTION void ROKEN_LIB_CALL
+rk_freeaddrinfo(struct addrinfo *);
#ifndef HAVE_GAI_STRERROR
#define gai_strerror rk_gai_strerror
diff --git a/third_party/heimdal/lib/roken/snprintf.c b/third_party/heimdal/lib/roken/snprintf.c
index 620875f379c..3da48962ee3 100644
--- a/third_party/heimdal/lib/roken/snprintf.c
+++ b/third_party/heimdal/lib/roken/snprintf.c
@@ -515,7 +515,7 @@ xyzprintf (struct snprintf_state *state, const char *char_format, va_list ap)
}
case '\0' :
--format;
- /* FALLTHROUGH */
+ fallthrough;
case '%' :
(*state->append_char)(state, c);
++len;
diff --git a/third_party/heimdal/lib/roken/socket.c b/third_party/heimdal/lib/roken/socket.c
index 9feb343f508..a790e082d82 100644
--- a/third_party/heimdal/lib/roken/socket.c
+++ b/third_party/heimdal/lib/roken/socket.c
@@ -221,16 +221,16 @@ ROKEN_LIB_FUNCTION void ROKEN_LIB_CALL
socket_set_portrange (rk_socket_t sock, int restr, int af)
{
#if defined(IP_PORTRANGE)
- if (af == AF_INET) {
- int on = restr ? IP_PORTRANGE_HIGH : IP_PORTRANGE_DEFAULT;
- setsockopt (sock, IPPROTO_IP, IP_PORTRANGE, &on, sizeof(on));
- }
+ if (af == AF_INET) {
+ int on = restr ? IP_PORTRANGE_HIGH : IP_PORTRANGE_DEFAULT;
+ (void) setsockopt(sock, IPPROTO_IP, IP_PORTRANGE, &on, sizeof(on));
+ }
#endif
#if defined(IPV6_PORTRANGE)
- if (af == AF_INET6) {
- int on = restr ? IPV6_PORTRANGE_HIGH : IPV6_PORTRANGE_DEFAULT;
- setsockopt (sock, IPPROTO_IPV6, IPV6_PORTRANGE, &on, sizeof(on));
- }
+ if (af == AF_INET6) {
+ int on = restr ? IPV6_PORTRANGE_HIGH : IPV6_PORTRANGE_DEFAULT;
+ (void) setsockopt(sock, IPPROTO_IPV6, IPV6_PORTRANGE, &on, sizeof(on));
+ }
#endif
}
@@ -243,7 +243,7 @@ socket_set_debug (rk_socket_t sock)
{
#if defined(SO_DEBUG) && defined(HAVE_SETSOCKOPT)
int on = 1;
- setsockopt (sock, SOL_SOCKET, SO_DEBUG, (void *) &on, sizeof (on));
+ (void) setsockopt(sock, SOL_SOCKET, SO_DEBUG, (void *) &on, sizeof (on));
#endif
}
@@ -255,7 +255,7 @@ ROKEN_LIB_FUNCTION void ROKEN_LIB_CALL
socket_set_tos (rk_socket_t sock, int tos)
{
#if defined(IP_TOS) && defined(HAVE_SETSOCKOPT)
- setsockopt (sock, IPPROTO_IP, IP_TOS, (void *) &tos, sizeof(int));
+ (void) setsockopt (sock, IPPROTO_IP, IP_TOS, (void *) &tos, sizeof(int));
#endif
}
@@ -289,7 +289,8 @@ ROKEN_LIB_FUNCTION void ROKEN_LIB_CALL
socket_set_reuseaddr (rk_socket_t sock, int val)
{
#if defined(SO_REUSEADDR) && defined(HAVE_SETSOCKOPT)
- setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (void *)&val, sizeof(val));
+ (void) setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (void *)&val,
+ sizeof(val));
#endif
}
@@ -301,7 +302,8 @@ ROKEN_LIB_FUNCTION void ROKEN_LIB_CALL
socket_set_ipv6only (rk_socket_t sock, int val)
{
#if defined(IPV6_V6ONLY) && defined(HAVE_SETSOCKOPT)
- setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY, (void *)&val, sizeof(val));
+ (void) setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY, (void *)&val,
+ sizeof(val));
#endif
}
@@ -312,7 +314,8 @@ socket_set_ipv6only (rk_socket_t sock, int val)
ROKEN_LIB_FUNCTION void ROKEN_LIB_CALL
socket_set_keepalive(rk_socket_t sock, int val)
{
- setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, (void *)&val, sizeof(val));
+ (void) setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, (void *)&val,
+ sizeof(val));
}
/**
diff --git a/third_party/heimdal/lib/roken/strftime.c b/third_party/heimdal/lib/roken/strftime.c
index 447c1554337..9a951dd3008 100644
--- a/third_party/heimdal/lib/roken/strftime.c
+++ b/third_party/heimdal/lib/roken/strftime.c
@@ -36,6 +36,11 @@
#include "strpftime-test.h"
#endif
+#if defined(_WIN32)
+# define timezone _timezone
+# define tzname _tzname
+#endif
+
static const char *abb_weekdays[] = {
"Sun",
"Mon",
@@ -372,7 +377,7 @@ strftime (char *buf, size_t maxsize, const char *format,
break;
case '\0' :
--format;
- /* FALLTHROUGH */
+ fallthrough;
case '%' :
ret = snprintf (buf, maxsize - n,
"%%");
diff --git a/third_party/heimdal/lib/roken/strptime.c b/third_party/heimdal/lib/roken/strptime.c
index 75c27a32877..86216d2d6dc 100644
--- a/third_party/heimdal/lib/roken/strptime.c
+++ b/third_party/heimdal/lib/roken/strptime.c
@@ -424,7 +424,7 @@ strptime (const char *buf, const char *format, struct tm *timeptr)
abort ();
case '\0' :
--format;
- /* FALLTHROUGH */
+ fallthrough;
case '%' :
if (*buf == '%')
++buf;
diff --git a/third_party/heimdal/lib/roken/strtoll.c b/third_party/heimdal/lib/roken/strtoll.c
index 0d895d54a25..96c1b250974 100644
--- a/third_party/heimdal/lib/roken/strtoll.c
+++ b/third_party/heimdal/lib/roken/strtoll.c
@@ -38,6 +38,8 @@
#include "roken.h"
+#ifndef HAVE_STRTOLL
+
/* #include <sys/cdefs.h> */
#include <limits.h>
@@ -150,3 +152,4 @@ noconv:
*endptr = (char *)(any ? s - 1 : nptr);
return ret;
}
+#endif /* !HAVE_STRTOLL */
diff --git a/third_party/heimdal/lib/roken/strtoull.c b/third_party/heimdal/lib/roken/strtoull.c
index 94530e574d1..0516e18f913 100644
--- a/third_party/heimdal/lib/roken/strtoull.c
+++ b/third_party/heimdal/lib/roken/strtoull.c
@@ -38,6 +38,8 @@
#include "roken.h"
+#ifndef HAVE_STRTOULL
+
/* #include <sys/cdefs.h> */
#include <limits.h>
@@ -124,3 +126,4 @@ noconv:
*endptr = (char *)(any ? s - 1 : nptr);
return (acc);
}
+#endif /* !HAVE_STRTOULL */
diff --git a/third_party/heimdal/lib/roken/test-getuserinfo.c b/third_party/heimdal/lib/roken/test-getuserinfo.c
index b3f15214b56..4feae177aed 100644
--- a/third_party/heimdal/lib/roken/test-getuserinfo.c
+++ b/third_party/heimdal/lib/roken/test-getuserinfo.c
@@ -50,7 +50,8 @@ main(void)
char buf2[MAX_PATH * 2];
int ret = 0;
if (!issuid() && getuid() != 0) {
- const char *s, *s2;
+ const char *s = NULL;
+ const char *s2 = NULL;
if (getenv("USER") != NULL && strlen(getenv("USER")) != 0 &&
(s = roken_get_username(buf, sizeof(buf))) == NULL) {
diff --git a/third_party/heimdal/lib/roken/test-mini_inetd.c b/third_party/heimdal/lib/roken/test-mini_inetd.c
index 079ace266a1..7ab996ae8b4 100644
--- a/third_party/heimdal/lib/roken/test-mini_inetd.c
+++ b/third_party/heimdal/lib/roken/test-mini_inetd.c
@@ -144,7 +144,7 @@ test_simple_echo_client(void)
}
if (rv != strlen(test_strings[i])) {
- fprintf (stderr, "[%s] Data length mismatch %d != %d\n", prog, rv, strlen(test_strings[i]));
+ fprintf (stderr, "[%s] Data length mismatch %d != %zu\n", prog, rv, strlen(test_strings[i]));
rk_closesocket(s);
return 1;
}
diff --git a/third_party/heimdal/lib/roken/timeval.c b/third_party/heimdal/lib/roken/timeval.c
index 38b1f7ce9c3..3012513ee7d 100644
--- a/third_party/heimdal/lib/roken/timeval.c
+++ b/third_party/heimdal/lib/roken/timeval.c
@@ -39,6 +39,93 @@
#include "roken.h"
+ROKEN_LIB_FUNCTION time_t ROKEN_LIB_CALL
+rk_time_add(time_t t, time_t delta)
+{
+ if (delta == 0)
+ return t;
+
+#ifdef TIME_T_SIGNED
+ /* Signed overflow is UB in C */
+#if SIZEOF_TIME_T == 4
+ if (t >= 0 && delta > 0 && INT32_MAX - t < delta)
+ /* Time left to hit INT32_MAX is less than what we want to add */
+ return INT32_MAX;
+ else if (t == INT32_MIN && delta < 0)
+ /* Avoid computing -t when t == INT32_MIN! */
+ return INT32_MIN;
+ else if (t < 0 && delta < 0 && INT32_MIN + (-t) > delta)
+ /* Time left to hit INT32_MIN is less than what we want to subtract */
+ return INT32_MIN;
+ else
+ return t + delta;
+#elif SIZEOF_TIME_T == 8
+ if (t >= 0 && delta > 0 && INT64_MAX - t < delta)
+ return INT64_MAX;
+ else if (t == INT64_MIN && delta < 0)
+ /* Avoid computing -t when t == INT64_MIN! */
+ return INT64_MIN;
+ else if (t < 0 && delta < 0 && INT64_MIN + (-t) > delta)
+ return INT64_MIN;
+ else
+ return t + delta;
+#else
+#error "Unexpected sizeof(time_t)"
+#endif
+#else
+
+ /* Unsigned overflow is defined in C */
+#if SIZEOF_TIME_T == 4
+ if (t + delta < t)
+ return UINT32_MAX;
+#elif SIZEOF_TIME_T == 8
+ if (t + delta < t)
+ return UINT64_MAX;
+#else
+#error "Unexpected sizeof(time_t)"
+#endif
+#endif
+ return t + delta;
+}
+
+ROKEN_LIB_FUNCTION time_t ROKEN_LIB_CALL
+rk_time_sub(time_t t, time_t delta)
+{
+ if (delta == 0)
+ return t;
+#ifdef TIME_T_SIGNED
+ if (delta > 0)
+ return rk_time_add(t, -delta);
+#if SIZEOF_TIME_T == 4
+ if (delta == INT32_MIN) {
+ if (t < 0) {
+ t = t + INT32_MAX;
+ return t + 1;
+ }
+ return INT32_MAX;
+ }
+ /* Safe to compute -delta, so use rk_time_add() to add -delta */
+ return rk_time_add(t, -delta);
+#elif SIZEOF_TIME_T == 8
+ if (delta == INT64_MIN) {
+ if (t < 0) {
+ t = t + INT64_MAX;
+ return t + 1;
+ }
+ return INT64_MAX;
+ }
+ return rk_time_add(t, -delta);
+#else
+#error "Unexpected sizeof(time_t)"
+#endif
+#else
+ /* Both t and delta are non-negative. */
+ if (delta > t)
+ return 0;
+#endif
+ return t - delta;
+}
+
/*
* Make `t1' consistent.
*/
@@ -47,11 +134,11 @@ ROKEN_LIB_FUNCTION void ROKEN_LIB_CALL
timevalfix(struct timeval *t1)
{
if (t1->tv_usec < 0) {
- t1->tv_sec--;
- t1->tv_usec += 1000000;
+ t1->tv_sec = rk_time_sub(t1->tv_sec, 1);
+ t1->tv_usec = 1000000;
}
if (t1->tv_usec >= 1000000) {
- t1->tv_sec++;
+ t1->tv_sec = rk_time_add(t1->tv_sec, 1);
t1->tv_usec -= 1000000;
}
}
@@ -63,7 +150,7 @@ timevalfix(struct timeval *t1)
ROKEN_LIB_FUNCTION void ROKEN_LIB_CALL
timevaladd(struct timeval *t1, const struct timeval *t2)
{
- t1->tv_sec += t2->tv_sec;
+ t1->tv_sec = rk_time_add(t1->tv_sec, t2->tv_sec);
t1->tv_usec += t2->tv_usec;
timevalfix(t1);
}
@@ -75,7 +162,125 @@ timevaladd(struct timeval *t1, const struct timeval *t2)
ROKEN_LIB_FUNCTION void ROKEN_LIB_CALL
timevalsub(struct timeval *t1, const struct timeval *t2)
{
- t1->tv_sec -= t2->tv_sec;
+ t1->tv_sec = rk_time_sub(t1->tv_sec, t2->tv_sec);
t1->tv_usec -= t2->tv_usec;
timevalfix(t1);
}
+
+#ifdef TEST
+int
+main(int argc, char **argv)
+{
+ time_t t, delta, r;
+ int e = 0;
+
+ if (argc == 0)
+ return 0; /* Apparently POSIX and Linux allow this case */
+
+ argc--;
+ argv++;
+
+ while (argc > 0) {
+ int64_t n;
+ time_t a;
+ char *ends;
+
+ if (argc < 3)
+ errx(1, "Usage: [TIME +|- DELTA [== TIME]]");
+
+ errno = 0;
+ n = strtoll(argv[0], &ends, 0);
+ if (errno)
+ err(1, "Time value is invalid");
+ if (*ends != '\0')
+ errx(1, "Time value is invalid");
+ t = n;
+
+ n = strtoll(argv[2], &ends, 0);
+ if (errno)
+ err(1, "Delta value is invalid");
+ if (*ends != '\0')
+ errx(1, "Delta value is invalid");
+ delta = n;
+
+ if (argv[1][0] == '+' && argv[1][1] == '\0')
+ r = rk_time_add(t, delta);
+ else if (argv[1][0] == '-' && argv[1][1] == '\0')
+ r = rk_time_sub(t, delta);
+ else
+ errx(1, "Operator must be a + or a - arithmetic operator");
+
+ if (delta == 0 && r != t) {
+ warnx("%s %s %s != %s!", argv[0], argv[1], argv[2], argv[0]);
+ e = 1;
+ }
+ if (t == 0 && r != delta) {
+ warnx("%s %s %s != %s!", argv[0], argv[1], argv[2], argv[2]);
+ e = 1;
+ }
+
+ if (argc > 4 && strcmp(argv[3], "==") == 0) {
+ n = strtoll(argv[4], &ends, 0);
+ if (errno)
+ err(1, "Time value is invalid");
+ if (*ends != '\0')
+ errx(1, "Time value is invalid");
+ a = n;
+ if (a != r) {
+ warnx("%s %s %s != %s!", argv[0], argv[1], argv[2], argv[4]);
+ e = 1;
+ }
+ argc -= 5;
+ argv += 5;
+ } else {
+#ifdef TIME_T_SIGNED
+ printf("%s %s %s == %lld\n", argv[0], argv[1], argv[2],
+ (long long)r);
+#else
+ printf("%s %s %s == %llu\n", argv[0], argv[1], argv[2],
+ (unsigned long long)r);
+#endif
+ argc -= 3;
+ argv += 3;
+ }
+ }
+
+#define CHECK(e) do { if (!(e)) errx(1, "Expression not true: " #e "!"); } while (0)
+#ifdef TIME_T_SIGNED
+#if SIZEOF_TIME_T == 4
+ CHECK(rk_time_add(INT32_MIN, -1) == INT32_MIN);
+ CHECK(rk_time_sub(INT32_MIN, 1) == INT32_MIN);
+ CHECK(rk_time_sub(-1, INT32_MAX) == INT32_MIN);
+ CHECK(rk_time_add(INT32_MAX, 0) == INT32_MAX);
+ CHECK(rk_time_add(INT32_MAX, 1) == INT32_MAX);
+ CHECK(rk_time_add(1, INT32_MAX) == INT32_MAX);
+ CHECK(rk_time_add(0, INT32_MAX) == INT32_MAX);
+#elif SIZEOF_TIME_T == 8
+ CHECK(rk_time_add(INT64_MIN, -1) == INT64_MIN);
+ CHECK(rk_time_sub(INT64_MIN, 1) == INT64_MIN);
+ CHECK(rk_time_sub(-1, INT64_MAX) == INT64_MIN);
+ CHECK(rk_time_add(INT64_MAX, 0) == INT64_MAX);
+ CHECK(rk_time_add(INT64_MAX, 1) == INT64_MAX);
+ CHECK(rk_time_add(1, INT64_MAX) == INT64_MAX);
+ CHECK(rk_time_add(0, INT64_MAX) == INT64_MAX);
+#endif
+ CHECK(rk_time_add(0, -1) == -1);
+ CHECK(rk_time_sub(0, 1) == -1);
+#else
+#if SIZEOF_TIME_T == 4
+ CHECK(rk_time_add(UINT32_MAX, 0) == UINT32_MAX);
+ CHECK(rk_time_add(UINT32_MAX, 1) == UINT32_MAX);
+ CHECK(rk_time_add(1, UINT32_MAX) == UINT32_MAX);
+ CHECK(rk_time_add(0, UINT32_MAX) == UINT32_MAX);
+#elif SIZEOF_TIME_T == 8
+ CHECK(rk_time_add(UINT64_MAX, 0) == UINT64_MAX);
+ CHECK(rk_time_add(UINT64_MAX, 1) == UINT64_MAX);
+ CHECK(rk_time_add(1, UINT64_MAX) == UINT64_MAX);
+ CHECK(rk_time_add(0, UINT64_MAX) == UINT64_MAX);
+#endif
+#endif
+ CHECK(rk_time_add(0, 1) == 1);
+ CHECK(rk_time_add(1, 0) == 1);
+ return e;
+}
+#endif
diff --git a/third_party/heimdal/lib/roken/version-script.map b/third_party/heimdal/lib/roken/version-script.map
index 3307341c049..be1713e8261 100644
--- a/third_party/heimdal/lib/roken/version-script.map
+++ b/third_party/heimdal/lib/roken/version-script.map
@@ -2,7 +2,6 @@ HEIMDAL_ROKEN_2.0 {
global:
arg_printusage;
arg_printusage_i18n;
- cgetcap;
cgetclose;
cgetmatch;
cgetnum;
@@ -40,8 +39,6 @@ HEIMDAL_ROKEN_2.0 {
rk_bswap16;
rk_bswap32;
rk_bswap64;
- rk_cgetent;
- rk_cgetstr;
rk_cloexec;
rk_cloexec_dir;
rk_cloexec_file;
@@ -164,6 +161,8 @@ HEIMDAL_ROKEN_2.0 {
rk_tdelete;
rk_tfind;
rk_timegm;
+ rk_time_add;
+ rk_time_sub;
rk_timevaladd;
rk_timevalfix;
rk_timevalsub;
diff --git a/third_party/heimdal/lib/roken/vis.c b/third_party/heimdal/lib/roken/vis.c
index c598967fb72..0fe44ae3502 100644
--- a/third_party/heimdal/lib/roken/vis.c
+++ b/third_party/heimdal/lib/roken/vis.c
@@ -377,12 +377,12 @@ rk_strsvisx(char *dst, const char *csrc, size_t len, int flag, const char *extra
if (flag & VIS_HTTPSTYLE) {
for (start = dst; len > 0; len--) {
c = *src++;
- dst = do_hvis(dst, c, flag, len ? *src : '\0', nextra);
+ dst = do_hvis(dst, c, flag, *src, nextra);
}
} else {
for (start = dst; len > 0; len--) {
c = *src++;
- dst = do_svis(dst, c, flag, len ? *src : '\0', nextra);
+ dst = do_svis(dst, c, flag, *src, nextra);
}
}
free(nextra);
@@ -440,16 +440,18 @@ rk_strrasvisx(char **out,
return -1;
}
if (have < want) {
- if ((s = realloc(*out, want)) == NULL)
+ if ((s = realloc(s, want)) == NULL)
return -1;
*outsz = want;
*out = s;
}
+ if (*out == NULL) {
+ errno = EINVAL;
+ return -1;
+ }
**out = '\0'; /* Makes source debugging nicer, that's all */
- if ((r = strsvisx(*out, csrc, len, flag, extra)) < 0)
- return r;
- errno = *out ? errno : EINVAL;
- return *out ? r : -1;
+ r = strsvisx(*out, csrc, len, flag, extra);
+ return r;
}
#if !HAVE_VIS
@@ -641,6 +643,7 @@ main(int argc, char **argv)
}
free(nextra);
+ free(s);
return 0;
}
#endif