Loading...
stdio/FreeBSD/vfprintf.c Libc-1725.40.4 Libc-825.26
--- Libc/Libc-1725.40.4/stdio/FreeBSD/vfprintf.c
+++ Libc/Libc-825.26/stdio/FreeBSD/vfprintf.c
@@ -30,14 +30,6 @@
  * SUCH DAMAGE.
  */
 
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Wint-conversion"
-
-#include <TargetConditionals.h>
-#if !TARGET_OS_DRIVERKIT
-#define OS_CRASH_ENABLE_EXPERIMENTAL_LIBTRACE 1
-#endif
-
 #if defined(LIBC_SCCS) && !defined(lint)
 static char sccsid[] = "@(#)vfprintf.c	8.1 (Berkeley) 6/4/93";
 #endif /* LIBC_SCCS and not lint */
@@ -72,20 +64,13 @@
 #include <stdarg.h>
 #include "un-namespace.h"
 
-#include <os/assumes.h>
-#include <mach-o/dyld_priv.h>
-#include <mach/mach.h>
-
 #include "libc_private.h"
 #include "local.h"
 #include "fvwrite.h"
 #include "printflocal.h"
-#include "libc_hooks_impl.h"
 
 static int	__sprint(FILE *, locale_t, struct __suio *);
-#if 0
 static int	__sbprintf(FILE *, locale_t, const char *, va_list) __printflike(3, 0);
-#endif
 static char	*__wcsconv(wchar_t *, int, locale_t);
 
 __private_extern__ const char *__fix_nogrouping(const char *);
@@ -181,7 +166,6 @@
 	return (err);
 }
 
-#if 0
 /*
  * Helper function for `fprintf to unbuffered unix file': creates a
  * temporary buffer.  We only work on write-only files; this avoids
@@ -222,7 +206,6 @@
 		fp->_flags |= __SERR;
 	return (ret);
 }
-#endif
 
 /*
  * Convert a wide character string argument for the %ls format to a multibyte
@@ -292,10 +275,14 @@
 {
 	int ret;
 
-	libc_hooks_will_write(fp, sizeof(*fp));
-
+	NORMALIZE_LOCALE(loc);
 	FLOCKFILE(fp);
-	ret = __xvprintf(XPRINTF_PLAIN, NULL, fp, loc, fmt0, ap);
+	/* optimise fprintf(stderr) (and other unbuffered Unix files) */
+	if ((fp->_flags & (__SNBF|__SWR|__SRW)) == (__SNBF|__SWR) &&
+	    fp->_file >= 0)
+		ret = __sbprintf(fp, loc, fmt0, ap);
+	else
+		ret = __vfprintf(fp, loc, fmt0, ap);
 	FUNLOCKFILE(fp);
 	return (ret);
 }
@@ -304,14 +291,7 @@
 vfprintf(FILE * __restrict fp, const char * __restrict fmt0, va_list ap)
 
 {
-	int ret;
-
-	libc_hooks_will_write(fp, sizeof(*fp));
-
-	FLOCKFILE(fp);
-	ret = __xvprintf(XPRINTF_PLAIN, NULL, fp, __current_locale(), fmt0, ap);
-	FUNLOCKFILE(fp);
-	return ret;
+	return vfprintf_l(fp, __current_locale(), fmt0, ap);
 }
 
 /*
@@ -325,26 +305,6 @@
 #error "BUF must be large enough to format a uintmax_t"
 #endif
 
-__private_extern__ bool
-__printf_is_memory_read_only(void *addr, size_t __unused size)
-{
-	vm_address_t address = addr;
-	vm_size_t vmsize = 0;
-	vm_region_basic_info_data_64_t info;
-	mach_msg_type_number_t info_cnt = VM_REGION_BASIC_INFO_COUNT_64;
-	memory_object_name_t object = MACH_PORT_NULL;
-	kern_return_t kr = KERN_SUCCESS;
-
-	kr = vm_region_64(mach_task_self(),
-			&address,
-			&vmsize,
-			VM_REGION_BASIC_INFO_64,
-			(vm_region_info_t) &info,
-			&info_cnt,
-			&object);
-	return (kr == KERN_SUCCESS) && !(info.protection & VM_PROT_WRITE);
-}
-
 /*
  * Non-MT-safe version
  */
@@ -353,18 +313,14 @@
 {
 	char *fmt;		/* format string */
 	int ch;			/* character from fmt */
-	ssize_t n, n2;		/* handy integer (short term usage) */
+	int n, n2;		/* handy integer (short term usage) */
 	char *cp;		/* handy char pointer (short term usage) */
 	int flags;		/* flags as above */
-	ssize_t ret;		/* return value accumulator */
-	ssize_t width;		/* width from format (%8d), or 0 */
-	ssize_t prec;		/* precision from format; <0 for N/A */
+	int ret;		/* return value accumulator */
+	int width;		/* width from format (%8d), or 0 */
+	int prec;		/* precision from format; <0 for N/A */
 	char sign;		/* sign prefix (' ', '+', '-', or \0) */
 	struct grouping_state gs; /* thousands' grouping info */
-
-#ifndef ALLOW_DYNAMIC_PERCENT_N
-	bool static_format_checked = false;
-#endif // ALLOW_DYNAMIC_PERCENT_N
 
 #ifndef NO_FLOATING_POINT
 	/*
@@ -405,9 +361,9 @@
 	uintmax_t ujval;	/* %j, %ll, %q, %t, %z integers */
 	int base;		/* base for [diouxX] conversion */
 	int dprec;		/* a copy of prec if [diouxX], 0 otherwise */
-	ssize_t realsz;		/* field size expanded by dprec, sign, etc */
-	ssize_t size;		/* size of converted field or string */
-	ssize_t prsize;             /* max size of printed field */
+	int realsz;		/* field size expanded by dprec, sign, etc */
+	int size;		/* size of converted field or string */
+	int prsize;             /* max size of printed field */
 	const char *xdigs;     	/* digits for %[xX] conversion */
 	struct io_state io;	/* I/O buffering state */
 	char buf[BUF];		/* buffer with space for digits of uintmax_t */
@@ -502,15 +458,19 @@
 		val = GETARG (int); \
 	}
 
-	/* The following has been moved to __v2printf() */
-#if 0
+#if 0 // xprintf pending API review
+	if (__use_xprintf == 0 && getenv("USE_XPRINTF"))
+		__use_xprintf = 1;
+	if (__use_xprintf > 0)
+		return (__xvprintf(fp, loc, fmt0, ap));
+#endif
+
 	/* sorry, fprintf(read_only_file, "") returns EOF, not 0 */
 	if (prepwrite(fp) != 0) {
 		errno = EBADF;
 		return (EOF);
 	}
 	ORIENT(fp, -1);
-#endif
 
 	convbuf = NULL;
 	fmt = (char *)fmt0;
@@ -533,9 +493,8 @@
 		for (cp = fmt; (ch = *fmt) != '\0' && ch != '%'; fmt++)
 			/* void */;
 		if ((n = fmt - cp) != 0) {
-			if (ret + n >= INT_MAX) {
+			if ((unsigned)ret + n > INT_MAX) {
 				ret = EOF;
-				errno = EOVERFLOW;
 				goto error;
 			}
 			PRINT(cp, n);
@@ -875,37 +834,22 @@
 			void *ptr = GETARG(void *);
 			if (ptr == NULL)
 				continue;
-
-#ifndef ALLOW_DYNAMIC_PERCENT_N
-			if (!static_format_checked) {
-				static_format_checked = __printf_is_memory_read_only((void*)fmt0, strlen(fmt0));
-			}
-			if (!static_format_checked) {
-#if OS_CRASH_ENABLE_EXPERIMENTAL_LIBTRACE
-				os_crash("%%n used in a non-immutable format string: %s", fmt0);
-#else
-				os_crash("%%n used in a non-immutable format string");
-#endif
-			}
-#endif // ALLOW_DYNAMIC_PERCENT_N
-
-			if (flags & LLONGINT) {
-				LIBC_HOOKS_WRITE_SIMPLE_TYPE(ptr, long long, ret);
-			} else if (flags & SIZET) {
-				LIBC_HOOKS_WRITE_SIMPLE_TYPE(ptr, ssize_t, ret);
-			} else if (flags & PTRDIFFT) {
-				LIBC_HOOKS_WRITE_SIMPLE_TYPE(ptr, ptrdiff_t, ret);
-			} else if (flags & INTMAXT) {
-				LIBC_HOOKS_WRITE_SIMPLE_TYPE(ptr, intmax_t, ret);
-			} else if (flags & LONGINT) {
-				LIBC_HOOKS_WRITE_SIMPLE_TYPE(ptr, long, ret);
-			} else if (flags & SHORTINT) {
-				LIBC_HOOKS_WRITE_SIMPLE_TYPE(ptr, short, ret);
-			} else if (flags & CHARINT) {
-				LIBC_HOOKS_WRITE_SIMPLE_TYPE(ptr, signed char, ret);
-			} else {
-				LIBC_HOOKS_WRITE_SIMPLE_TYPE(ptr, int, ret);
-			}
+			else if (flags & LLONGINT)
+				*(long long *)ptr = ret;
+			else if (flags & SIZET)
+				*(ssize_t *)ptr = (ssize_t)ret;
+			else if (flags & PTRDIFFT)
+				*(ptrdiff_t *)ptr = ret;
+			else if (flags & INTMAXT)
+				*(intmax_t *)ptr = ret;
+			else if (flags & LONGINT)
+				*(long *)ptr = ret;
+			else if (flags & SHORTINT)
+				*(short *)ptr = ret;
+			else if (flags & CHARINT)
+				*(signed char *)ptr = ret;
+			else
+				*(int *)ptr = ret;
 			continue;	/* no output */
 		}
 		case 'O':
@@ -947,11 +891,11 @@
 			if (flags & LONGINT) {
 				wchar_t *wcp;
 
-				free(convbuf);
-				if ((wcp = GETARG(wchar_t *)) == NULL) {
-					convbuf = NULL;
+				if (convbuf != NULL)
+					free(convbuf);
+				if ((wcp = GETARG(wchar_t *)) == NULL)
 					cp = "(null)";
-				} else {
+				else {
 					convbuf = __wcsconv(wcp, prec, loc);
 					if (convbuf == NULL) {
 						fp->_flags |= __SERR;
@@ -961,16 +905,7 @@
 				}
 			} else if ((cp = GETARG(char *)) == NULL)
 				cp = "(null)";
-			{
-				size_t cp_len = (prec >= 0) ? strnlen(cp, prec) : strlen(cp);
-				if (cp_len < INT_MAX) {
-					size = cp_len;
-				} else {
-					ret = EOF;
-					goto error;
-				}
-				libc_hooks_will_read(cp, size);
-			}
+			size = (prec >= 0) ? strnlen(cp, prec) : strlen(cp);
 			sign = '\0';
 			break;
 		case 'U':
@@ -1042,7 +977,7 @@
 			}
 			size = buf + BUF - cp;
 			if (size > BUF)	/* should never happen */
-				LIBC_ABORT("size (%zd) > BUF (%d)", size, BUF);
+				LIBC_ABORT("size (%d) > BUF (%d)", size, BUF);
 			if ((flags & GROUPING) && size != 0)
 				size += grouping_init(&gs, size, loc);
 			break;
@@ -1367,9 +1302,8 @@
 			realsz += 2;
 
 		prsize = width > realsz ? width : realsz;
-		if (ret + prsize >= INT_MAX) {
+		if ((unsigned)ret + prsize > INT_MAX) {
 			ret = EOF;
-			errno = EOVERFLOW;
 			goto error;
 		}
 
@@ -1457,12 +1391,13 @@
 	if (dtoaresult != NULL)
 		freedtoa(dtoaresult);
 #endif
-	free(convbuf);
+	if (convbuf != NULL)
+		free(convbuf);
 	if (__sferror(fp))
 		ret = EOF;
 	if ((argtable != NULL) && (argtable != statargtable))
 		free (argtable);
-	return (ret < 0 || ret >= INT_MAX) ? -1 : (int)ret;
+	return (ret);
 	/* NOTREACHED */
 }
-#pragma clang diagnostic pop
+