diff options
author | Renato Botelho <renato@netgate.com> | 2016-08-30 09:16:57 -0300 |
---|---|---|
committer | Renato Botelho <renato@netgate.com> | 2016-08-30 09:16:57 -0300 |
commit | 39fd693a18f8ef73b1268f2321393d5ca6101e89 (patch) | |
tree | b1bae394d01f4c868d315c2d7a2f7f7f0539a57b /lib/libc | |
parent | 29ebd1247162a77db08e5e2e00d033220ec807fe (diff) | |
parent | de43eec3e10416a7e9f3a7565f70e1ba2d265384 (diff) | |
download | FreeBSD-src-39fd693a18f8ef73b1268f2321393d5ca6101e89.zip FreeBSD-src-39fd693a18f8ef73b1268f2321393d5ca6101e89.tar.gz |
Merge remote-tracking branch 'origin/stable/10' into devel
Diffstat (limited to 'lib/libc')
-rw-r--r-- | lib/libc/net/getaddrinfo.c | 27 | ||||
-rw-r--r-- | lib/libc/nls/msgcat.c | 10 | ||||
-rw-r--r-- | lib/libc/stdio/fgetln.3 | 5 | ||||
-rw-r--r-- | lib/libc/stdio/fgetln.c | 15 | ||||
-rw-r--r-- | lib/libc/stdio/fgetwc.c | 13 | ||||
-rw-r--r-- | lib/libc/stdio/fgetwln.c | 7 | ||||
-rw-r--r-- | lib/libc/stdio/fputwc.c | 16 | ||||
-rw-r--r-- | lib/libc/stdio/getdelim.c | 4 | ||||
-rw-r--r-- | lib/libc/stdio/vfprintf.c | 6 | ||||
-rw-r--r-- | lib/libc/stdio/vfwprintf.c | 6 |
10 files changed, 69 insertions, 40 deletions
diff --git a/lib/libc/net/getaddrinfo.c b/lib/libc/net/getaddrinfo.c index 54ac329..c5bfc5e 100644 --- a/lib/libc/net/getaddrinfo.c +++ b/lib/libc/net/getaddrinfo.c @@ -207,6 +207,7 @@ struct ai_order { struct policyqueue *aio_dstpolicy; struct addrinfo *aio_ai; int aio_matchlen; + int aio_initial_sequence; }; static const ns_src default_dns_files[] = { @@ -690,6 +691,7 @@ reorder(struct addrinfo *sentinel) aio[i].aio_dstpolicy = match_addrselectpolicy(ai->ai_addr, &policyhead); set_source(&aio[i], &policyhead); + aio[i].aio_initial_sequence = i; } /* perform sorting. */ @@ -1048,6 +1050,23 @@ comp_dst(const void *arg1, const void *arg2) } /* Rule 10: Otherwise, leave the order unchanged. */ + + /* + * Note that qsort is unstable; so, we can't return zero and + * expect the order to be unchanged. + * That also means we can't depend on the current position of + * dst2 being after dst1. We must enforce the initial order + * with an explicit compare on the original position. + * The qsort specification requires that "When the same objects + * (consisting of width bytes, irrespective of their current + * positions in the array) are passed more than once to the + * comparison function, the results shall be consistent with one + * another." + * In other words, If A < B, then we must also return B > A. + */ + if (dst2->aio_initial_sequence < dst1->aio_initial_sequence) + return(1); + return(-1); } @@ -2251,6 +2270,8 @@ _dns_getaddrinfo(void *rv, void *cb_data, va_list ap) struct res_target q, q2; res_state res; + ai = NULL; + hostname = va_arg(ap, char *); pai = va_arg(ap, const struct addrinfo *); @@ -2329,16 +2350,16 @@ _dns_getaddrinfo(void *rv, void *cb_data, va_list ap) /* prefer IPv6 */ if (q.next) { ai = getanswer(buf2, q2.n, q2.name, q2.qtype, pai, res); - if (ai) { + if (ai != NULL) { cur->ai_next = ai; while (cur && cur->ai_next) cur = cur->ai_next; } } - if (!ai || pai->ai_family != AF_UNSPEC || + if (ai == NULL || pai->ai_family != AF_UNSPEC || (pai->ai_flags & (AI_ALL | AI_V4MAPPED)) != AI_V4MAPPED) { ai = getanswer(buf, q.n, q.name, q.qtype, pai, res); - if (ai) + if (ai != NULL) cur->ai_next = ai; } free(buf); diff --git a/lib/libc/nls/msgcat.c b/lib/libc/nls/msgcat.c index 0cba460..b373a3d 100644 --- a/lib/libc/nls/msgcat.c +++ b/lib/libc/nls/msgcat.c @@ -47,7 +47,6 @@ __FBSDID("$FreeBSD$"); #include <errno.h> #include <fcntl.h> #include <limits.h> -#include <locale.h> #include <nl_types.h> #include <pthread.h> #include <stdio.h> @@ -56,7 +55,7 @@ __FBSDID("$FreeBSD$"); #include <unistd.h> #include "un-namespace.h" -#include "../locale/setlocale.h" /* for ENCODING_LEN */ +#include "../locale/xlocale_private.h" #define _DEFAULT_NLS_PATH "/usr/share/nls/%L/%N.cat:/usr/share/nls/%N/%L:/usr/local/share/nls/%L/%N.cat:/usr/local/share/nls/%N/%L" @@ -115,9 +114,10 @@ catopen(const char *name, int type) { struct stat sbuf; struct catentry *np; - char *base, *cptr, *cptr1, *lang, *nlspath, *pathP, *pcode; - char *plang, *pter, *tmpptr; + char *base, *cptr, *cptr1, *nlspath, *pathP, *pcode; + char *plang, *pter; int saverr, spcleft; + const char *lang, *tmpptr; char path[PATH_MAX]; /* sanity checking */ @@ -129,7 +129,7 @@ catopen(const char *name, int type) lang = NULL; else { if (type == NL_CAT_LOCALE) - lang = setlocale(LC_MESSAGES, NULL); + lang = querylocale(LC_MESSAGES_MASK, __get_locale()); else lang = getenv("LANG"); diff --git a/lib/libc/stdio/fgetln.3 b/lib/libc/stdio/fgetln.3 index 4b83664..7d4b89a5 100644 --- a/lib/libc/stdio/fgetln.3 +++ b/lib/libc/stdio/fgetln.3 @@ -28,7 +28,7 @@ .\" @(#)fgetln.3 8.3 (Berkeley) 4/19/94 .\" $FreeBSD$ .\" -.Dd April 19, 1994 +.Dd February 15, 2016 .Dt FGETLN 3 .Os .Sh NAME @@ -97,6 +97,9 @@ These changes are lost as soon as the pointer becomes invalid. The argument .Fa stream is not a stream open for reading. +.It Bq Er ENOMEM +The internal line buffer could not be expanded due to lack of available memory, +or because it would need to expand beyond INT_MAX in size. .El .Pp The diff --git a/lib/libc/stdio/fgetln.c b/lib/libc/stdio/fgetln.c index 6546768..c8e30ee 100644 --- a/lib/libc/stdio/fgetln.c +++ b/lib/libc/stdio/fgetln.c @@ -37,6 +37,8 @@ static char sccsid[] = "@(#)fgetln.c 8.2 (Berkeley) 1/2/94"; __FBSDID("$FreeBSD$"); #include "namespace.h" +#include <errno.h> +#include <limits.h> #include <stdio.h> #include <stdlib.h> #include <string.h> @@ -61,6 +63,10 @@ __slbexpand(FILE *fp, size_t newsize) #endif if (fp->_lb._size >= newsize) return (0); + if (newsize > INT_MAX) { + errno = ENOMEM; + return (-1); + } if ((p = realloc(fp->_lb._base, newsize)) == NULL) return (-1); fp->_lb._base = p; @@ -133,8 +139,11 @@ fgetln(FILE *fp, size_t *lenp) (void)memcpy((void *)(fp->_lb._base + off), (void *)fp->_p, len - off); off = len; - if (__srefill(fp)) - break; /* EOF or error: return partial line */ + if (__srefill(fp)) { + if (__sfeof(fp)) + break; + goto error; + } if ((p = memchr((void *)fp->_p, '\n', (size_t)fp->_r)) == NULL) continue; @@ -152,7 +161,7 @@ fgetln(FILE *fp, size_t *lenp) } *lenp = len; #ifdef notdef - fp->_lb._base[len] = 0; + fp->_lb._base[len] = '\0'; #endif FUNLOCKFILE(fp); return ((char *)fp->_lb._base); diff --git a/lib/libc/stdio/fgetwc.c b/lib/libc/stdio/fgetwc.c index 52bc988..cf649fd 100644 --- a/lib/libc/stdio/fgetwc.c +++ b/lib/libc/stdio/fgetwc.c @@ -79,18 +79,9 @@ __fgetwc_mbs(FILE *fp, mbstate_t *mbs, int *nread, locale_t locale) size_t nconv; struct xlocale_ctype *l = XLOCALE_CTYPE(locale); - if (fp->_r <= 0 && __srefill(fp)) { - *nread = 0; - return (WEOF); - } - if (MB_CUR_MAX == 1) { - /* Fast path for single-byte encodings. */ - wc = *fp->_p++; - fp->_r--; - *nread = 1; - return (wc); - } *nread = 0; + if (fp->_r <= 0 && __srefill(fp)) + return (WEOF); do { nconv = l->__mbrtowc(&wc, fp->_p, fp->_r, mbs); if (nconv == (size_t)-1) diff --git a/lib/libc/stdio/fgetwln.c b/lib/libc/stdio/fgetwln.c index 8439496..34a80a0 100644 --- a/lib/libc/stdio/fgetwln.c +++ b/lib/libc/stdio/fgetwln.c @@ -56,13 +56,15 @@ fgetwln_l(FILE * __restrict fp, size_t *lenp, locale_t locale) while ((wc = __fgetwc(fp, locale)) != WEOF) { #define GROW 512 if (len * sizeof(wchar_t) >= fp->_lb._size && - __slbexpand(fp, (len + GROW) * sizeof(wchar_t))) + __slbexpand(fp, (len + GROW) * sizeof(wchar_t))) { + fp->_flags |= __SERR; goto error; + } *((wchar_t *)fp->_lb._base + len++) = wc; if (wc == L'\n') break; } - if (len == 0) + if (len == 0 || (wc == WEOF && !__sfeof(fp))) goto error; FUNLOCKFILE(fp); @@ -74,6 +76,7 @@ error: *lenp = 0; return (NULL); } + wchar_t * fgetwln(FILE * __restrict fp, size_t *lenp) { diff --git a/lib/libc/stdio/fputwc.c b/lib/libc/stdio/fputwc.c index 7b05d4a..7f0c910 100644 --- a/lib/libc/stdio/fputwc.c +++ b/lib/libc/stdio/fputwc.c @@ -53,19 +53,9 @@ __fputwc(wchar_t wc, FILE *fp, locale_t locale) size_t i, len; struct xlocale_ctype *l = XLOCALE_CTYPE(locale); - if (MB_CUR_MAX == 1 && wc > 0 && wc <= UCHAR_MAX) { - /* - * Assume single-byte locale with no special encoding. - * A more careful test would be to check - * _CurrentRuneLocale->encoding. - */ - *buf = (unsigned char)wc; - len = 1; - } else { - if ((len = l->__wcrtomb(buf, wc, &fp->_mbstate)) == (size_t)-1) { - fp->_flags |= __SERR; - return (WEOF); - } + if ((len = l->__wcrtomb(buf, wc, &fp->_mbstate)) == (size_t)-1) { + fp->_flags |= __SERR; + return (WEOF); } for (i = 0; i < len; i++) diff --git a/lib/libc/stdio/getdelim.c b/lib/libc/stdio/getdelim.c index d7d5627..7e0b2e2 100644 --- a/lib/libc/stdio/getdelim.c +++ b/lib/libc/stdio/getdelim.c @@ -125,7 +125,7 @@ getdelim(char ** __restrict linep, size_t * __restrict linecapp, int delim, if (fp->_r <= 0 && __srefill(fp)) { /* If fp is at EOF already, we just need space for the NUL. */ - if (__sferror(fp) || expandtofit(linep, 1, linecapp)) + if (!__sfeof(fp) || expandtofit(linep, 1, linecapp)) goto error; FUNLOCKFILE(fp); (*linep)[0] = '\0'; @@ -137,7 +137,7 @@ getdelim(char ** __restrict linep, size_t * __restrict linecapp, int delim, if (sappend(linep, &linelen, linecapp, fp->_p, fp->_r)) goto error; if (__srefill(fp)) { - if (__sferror(fp)) + if (!__sfeof(fp)) goto error; goto done; /* hit EOF */ } diff --git a/lib/libc/stdio/vfprintf.c b/lib/libc/stdio/vfprintf.c index e54e8ac..bf45bfb 100644 --- a/lib/libc/stdio/vfprintf.c +++ b/lib/libc/stdio/vfprintf.c @@ -364,6 +364,7 @@ __vfprintf(FILE *fp, locale_t locale, const char *fmt0, va_list ap) int nextarg; /* 1-based argument index */ va_list orgap; /* original argument pointer */ char *convbuf; /* wide to multibyte conversion result */ + int savserr; static const char xdigs_lower[16] = "0123456789abcdef"; static const char xdigs_upper[16] = "0123456789ABCDEF"; @@ -460,6 +461,9 @@ __vfprintf(FILE *fp, locale_t locale, const char *fmt0, va_list ap) return (EOF); } + savserr = fp->_flags & __SERR; + fp->_flags &= ~__SERR; + convbuf = NULL; fmt = (char *)fmt0; argtable = NULL; @@ -1031,6 +1035,8 @@ error: free(convbuf); if (__sferror(fp)) ret = EOF; + else + fp->_flags |= savserr; if ((argtable != NULL) && (argtable != statargtable)) free (argtable); return (ret); diff --git a/lib/libc/stdio/vfwprintf.c b/lib/libc/stdio/vfwprintf.c index b75c504..9a5381d 100644 --- a/lib/libc/stdio/vfwprintf.c +++ b/lib/libc/stdio/vfwprintf.c @@ -444,6 +444,7 @@ __vfwprintf(FILE *fp, locale_t locale, const wchar_t *fmt0, va_list ap) int nextarg; /* 1-based argument index */ va_list orgap; /* original argument pointer */ wchar_t *convbuf; /* multibyte to wide conversion result */ + int savserr; static const char xdigs_lower[16] = "0123456789abcdef"; static const char xdigs_upper[16] = "0123456789ABCDEF"; @@ -536,6 +537,9 @@ __vfwprintf(FILE *fp, locale_t locale, const wchar_t *fmt0, va_list ap) return (EOF); } + savserr = fp->_flags & __SERR; + fp->_flags &= ~__SERR; + convbuf = NULL; fmt = (wchar_t *)fmt0; argtable = NULL; @@ -1096,6 +1100,8 @@ error: free(convbuf); if (__sferror(fp)) ret = EOF; + else + fp->_flags |= savserr; if ((argtable != NULL) && (argtable != statargtable)) free (argtable); return (ret); |