Improve the handling of dangling or invalid "%" sequences.

This commit is contained in:
Andrew Wood
2024-12-08 16:18:58 +00:00
parent 6298a7be9d
commit 838ebcb78f
10 changed files with 43 additions and 24 deletions
+26 -8
View File
@@ -1271,11 +1271,12 @@ static void pv__format_init(pvstate_t state, /*@null@ */ const char *format_supp
if ('%' == display_format[strpos]) {
unsigned long number_prefix;
size_t sequence_start, sequence_length;
size_t percent_sign_offset, sequence_start, sequence_length;
#if HAVE_STRTOUL
char *number_end_ptr;
#endif
percent_sign_offset = strpos;
strpos++;
/*
@@ -1286,10 +1287,11 @@ static void pv__format_init(pvstate_t state, /*@null@ */ const char *format_supp
#if HAVE_STRTOUL
number_end_ptr = NULL;
number_prefix = strtoul(&(display_format[strpos]), &number_end_ptr, 10);
if ((NULL == number_end_ptr) || (number_end_ptr[0] == '\0'))
break;
if (number_end_ptr > &(display_format[strpos]))
if ((NULL == number_end_ptr) || (number_end_ptr[0] == '\0')) {
number_prefix = 0;
} else if (number_end_ptr > &(display_format[strpos])) {
strpos += (number_end_ptr - &(display_format[strpos]));
}
#else /* !HAVE_STRTOUL */
while (isdigit((int) (display_format[strpos]))) {
number_prefix = number_prefix * 10;
@@ -1299,9 +1301,12 @@ static void pv__format_init(pvstate_t state, /*@null@ */ const char *format_supp
#endif /* !HAVE_STRTOUL */
sequence_start = strpos;
sequence_length = 1;
sequence_length = 0;
if ('\0' != display_format[strpos])
sequence_length = 1;
if ('{' == display_format[strpos]) {
while ('\0' != display_format[strpos] && '}' != display_format[strpos]) {
while ('\0' != display_format[strpos] && '}' != display_format[strpos]
&& '%' != display_format[strpos]) {
strpos++;
sequence_length++;
}
@@ -1322,8 +1327,21 @@ static void pv__format_init(pvstate_t state, /*@null@ */ const char *format_supp
}
if (-1 == component_type) {
str_start = sequence_start;
str_bytes = sequence_length;
/* Unknown sequence - pass it through verbatim. */
str_start = percent_sign_offset;
str_bytes = sequence_length + sequence_start - percent_sign_offset;
if (2 == str_bytes && '%' == display_format[percent_sign_offset + 1]) {
/* Special case: "%%" => "%". */
str_bytes = 1;
} else if (str_bytes > 1 && '%' == display_format[strpos]) {
/* Special case: "%{foo%p" => "%{foo" and go back one. */
str_bytes--;
strpos--;
} else if (str_bytes == 0 && '\0' == display_format[strpos]) {
/* Special case: "%" at end of string = "%". */
str_bytes = 1;
}
} else {
chosen_size = (size_t) number_prefix;
}