Module Name:    src
Committed By:   christos
Date:           Mon Nov 27 22:43:07 UTC 2017

Modified Files:
        src/lib/libc/stdlib: strfmon.c

Log Message:
Fix various bugs with strfmon:
- Avoid out of bounds access for the currency_symbol[3] when the symbol
  is shorter (as it happens with the C locale where it is empty)
- Don't compare pointers to NUL, it is not helpful.
- Make the default sep_by_space 1 as suggested in:
      https://ftp.gnu.org/old-gnu/Manuals/glibc-2.2.3/html_node/libc_111.html
- Use the correct number of bytes for memmove(3)

XXX: pullup-8


To generate a diff of this commit:
cvs rdiff -u -r1.11 -r1.12 src/lib/libc/stdlib/strfmon.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/lib/libc/stdlib/strfmon.c
diff -u src/lib/libc/stdlib/strfmon.c:1.11 src/lib/libc/stdlib/strfmon.c:1.12
--- src/lib/libc/stdlib/strfmon.c:1.11	Wed Aug 16 09:53:20 2017
+++ src/lib/libc/stdlib/strfmon.c	Mon Nov 27 17:43:07 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: strfmon.c,v 1.11 2017/08/16 13:53:20 joerg Exp $	*/
+/*	$NetBSD: strfmon.c,v 1.12 2017/11/27 22:43:07 christos Exp $	*/
 
 /*-
  * Copyright (c) 2001 Alexey Zelkin <[email protected]>
@@ -32,7 +32,7 @@
 #if 0
 __FBSDID("$FreeBSD: src/lib/libc/stdlib/strfmon.c,v 1.14 2003/03/20 08:18:55 ache Exp $");
 #else
-__RCSID("$NetBSD: strfmon.c,v 1.11 2017/08/16 13:53:20 joerg Exp $");
+__RCSID("$NetBSD: strfmon.c,v 1.12 2017/11/27 22:43:07 christos Exp $");
 #endif
 #endif /* LIBC_SCCS and not lint */
 
@@ -241,8 +241,12 @@ vstrfmon_l(char * __restrict s, size_t m
 			free(currency_symbol);
 		if (flags & USE_INTL_CURRENCY) {
 			currency_symbol = strdup(lc->int_curr_symbol);
-			if (currency_symbol != NULL)
-				space_char = *(currency_symbol+3);
+			if (currency_symbol != NULL &&
+			    strlen(currency_symbol) > 3) {
+				space_char = currency_symbol[3];
+				currency_symbol[3] = '\0';
+			}
+
 		} else
 			currency_symbol = strdup(lc->currency_symbol);
 
@@ -418,7 +422,7 @@ __setup_vars(struct lconv *lc, int flags
 		*cs_precedes = lc->int_n_cs_precedes;
 		*sep_by_space = lc->int_n_sep_by_space;
 		*sign_posn = (flags & PARENTH_POSN) ? 0 : lc->int_n_sign_posn;
-		*signstr = (lc->negative_sign == '\0') ? "-"
+		*signstr = (*lc->negative_sign == '\0') ? "-"
 		    : lc->negative_sign;
 	} else if (flags & USE_INTL_CURRENCY) {
 		*cs_precedes = lc->int_p_cs_precedes;
@@ -429,7 +433,7 @@ __setup_vars(struct lconv *lc, int flags
 		*cs_precedes = lc->n_cs_precedes;
 		*sep_by_space = lc->n_sep_by_space;
 		*sign_posn = (flags & PARENTH_POSN) ? 0 : lc->n_sign_posn;
-		*signstr = (lc->negative_sign == '\0') ? "-"
+		*signstr = (*lc->negative_sign == '\0') ? "-"
 		    : lc->negative_sign;
 	} else {
 		*cs_precedes = lc->p_cs_precedes;
@@ -438,11 +442,11 @@ __setup_vars(struct lconv *lc, int flags
 		*signstr = lc->positive_sign;
 	}
 
-	/* Set defult values for unspecified information. */
+	/* Set default values for unspecified information. */
 	if (*cs_precedes != 0)
 		*cs_precedes = 1;
 	if ((unsigned char)*sep_by_space == NBCHAR_MAX)
-		*sep_by_space = 0;
+		*sep_by_space = 1;
 	if ((unsigned char)*sign_posn == NBCHAR_MAX)
 		*sign_posn = 0;
 }
@@ -615,8 +619,7 @@ __format_grouped_double(struct lconv *lc
 		memset(bufend, pad_char, (size_t) padded);
 	}
 
-	bufsize = bufsize - (bufend - rslt) + 1;
-	memmove(rslt, bufend, bufsize);
+	memmove(rslt, bufend, bufend - rslt + 1);
 	free(avalue);
 	return (rslt);
 }

Reply via email to