summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGES4
-rw-r--r--strings/apr_snprintf.c18
2 files changed, 14 insertions, 8 deletions
diff --git a/CHANGES b/CHANGES
index d33aed854..d98790a18 100644
--- a/CHANGES
+++ b/CHANGES
@@ -1,4 +1,8 @@
Changes with APR 0.9.2
+
+ *) Prevent obscenely large values of precision in apr_vformatter
+ from clobbering a buffer. [Sander Striker, Jim Jagielski]
+
*) limit the renames performed in apr_rename.pl to the most recent renames.
[Thom May]
diff --git a/strings/apr_snprintf.c b/strings/apr_snprintf.c
index b282f246b..aac28bfc6 100644
--- a/strings/apr_snprintf.c
+++ b/strings/apr_snprintf.c
@@ -321,15 +321,21 @@ static char *apr_gcvt(double number, int ndigit, char *buf, boolean_e altform)
* This macro does zero padding so that the precision
* requirement is satisfied. The padding is done by
* adding '0's to the left of the string that is going
- * to be printed.
+ * to be printed. We don't allow precision to be large
+ * enough that we continue past the start of s.
+ *
+ * NOTE: this makes use of the magic info that s is
+ * always based on num_buf with a size of NUM_BUF_SIZE.
*/
#define FIX_PRECISION(adjust, precision, s, s_len) \
- if (adjust) \
- while (s_len < precision) \
+ if (adjust) { \
+ int p = precision < NUM_BUF_SIZE - 1 ? precision : NUM_BUF_SIZE - 1; \
+ while (s_len < p) \
{ \
*--s = '0'; \
s_len++; \
- }
+ } \
+ }
/*
* Macro that does padding. The padding is done by printing
@@ -784,10 +790,6 @@ APR_DECLARE(int) apr_vformatter(int (*flush_func)(apr_vformatter_buff_t *),
/*
* Check if a precision was specified
- *
- * XXX: an unreasonable amount of precision may be specified
- * resulting in overflow of num_buf. Currently we
- * ignore this possibility.
*/
if (*fmt == '.') {
adjust_precision = YES;