Mailing List Archive

cvs commit: apache-1.3/src/ap ap_snprintf.c
martin 98/05/07 00:47:34

Modified: src/ap ap_snprintf.c
Log:
Avoid core dumps for bogus ap_snprintf() format strings by using more
defensive approach: never allow patching a prefix char in front of
a constant string (or in front of char_buf); delimit strchr() to not
scan past the generated string;
Add 'h' modifier for compatibility reasons with other printf()s.

Revision Changes Path
1.21 +15 -6 apache-1.3/src/ap/ap_snprintf.c

Index: ap_snprintf.c
===================================================================
RCS file: /home/cvs/apache-1.3/src/ap/ap_snprintf.c,v
retrieving revision 1.20
retrieving revision 1.21
diff -u -u -r1.20 -r1.21
--- ap_snprintf.c 1998/05/06 19:49:46 1.20
+++ ap_snprintf.c 1998/05/07 07:47:33 1.21
@@ -677,8 +677,11 @@
is_long = YES;
fmt++;
}
- else
+ else {
+ if (*fmt == 'h') /* "short" backward compatibility */
+ ++fmt;
is_long = NO;
+ }

/*
* Argument extraction and printing.
@@ -772,7 +775,9 @@
case 'e':
case 'E':
fp_num = va_arg(ap, double);
-
+ /*
+ * * We use &num_buf[ 1 ], so that we have room for the sign
+ */
s = conv_fp(*fmt, fp_num, alternate_form,
(adjust_precision == NO) ? FLOAT_DIGITS : precision,
&is_negative, &num_buf[1], &s_len);
@@ -804,8 +809,10 @@

s_len = strlen(s);

- if (alternate_form && (q = strchr(s, '.')) == NULL)
+ if (alternate_form && (q = strchr(s, '.')) == NULL) {
s[s_len++] = '.';
+ s[s_len] = '\0'; /* delimit for following strchr() */
+ }
if (*fmt == 'G' && (q = strchr(s, 'e')) != NULL)
*q = 'E';
break;
@@ -851,6 +858,7 @@
else {
s = "%p";
s_len = 2;
+ prefix_char = NUL;
}
pad_char = ' ';
break;
@@ -900,6 +908,7 @@
default:
s = "bogus %p";
s_len = 8;
+ prefix_char = NUL;
break;
}
break;
@@ -931,15 +940,15 @@
break;
}

- if (prefix_char != NUL) {
+ if (prefix_char != NUL && s != S_NULL & s != char_buf) {
*--s = prefix_char;
s_len++;
}

if (adjust_width && adjust == RIGHT && min_width > s_len) {
if (pad_char == '0' && prefix_char != NUL) {
- INS_CHAR(*s, sp, bep, cc)
- s++;
+ INS_CHAR(*s, sp, bep, cc);
+ s++;
s_len--;
min_width--;
}