Improve handling of padding in status formats.

Status formats support a %<PAD>c syntax for specifying padding.  This change
ensures that we only use padding consisting of the characters "0123456789.",
which ensures it won't confuse sprintf.


git-svn-id: svn://svn.code.sf.net/p/bitchx/code/trunk@424 13b04d17-f746-0410-82c6-800466cd88b0
This commit is contained in:
Kevin Easton
2013-10-29 13:14:19 +00:00
parent e281537918
commit e9d180f526
2 changed files with 68 additions and 60 deletions

View File

@@ -1,5 +1,7 @@
[Changes 1.2c01] [Changes 1.2c01]
* Improve handling of padding in status formats. (caf)
* Use system setenv() in preference to compat bsd_setenv(). (caf) * Use system setenv() in preference to compat bsd_setenv(). (caf)
* Allow selection of alternate hashing methods with $crypt(). (caf) * Allow selection of alternate hashing methods with $crypt(). (caf)

View File

@@ -114,7 +114,7 @@ static char *status_refnum (Window *);
static char *status_topic (Window *); static char *status_topic (Window *);
static char *status_null_function (Window *); static char *status_null_function (Window *);
static char *status_notify_windows (Window *); static char *status_notify_windows (Window *);
static char *convert_sub_format (char *, char, char *); static char *convert_sub_format (const char *, char, const char *);
static char *status_voice (Window *); static char *status_voice (Window *);
static char *status_cpu_saver_mode (Window *); static char *status_cpu_saver_mode (Window *);
static char *status_dcccount (Window *); static char *status_dcccount (Window *);
@@ -275,79 +275,79 @@ void *default_status_output_function = make_status;
/* /*
* convert_sub_format: This is used to convert the formats of the * convert_sub_format: This is used to convert the formats of the
* sub-portions of the status line to a format statement specially designed * sub-portions of the status line to a format statement specially designed
* for that sub-portion. convert_sub_format looks for a single occurence of * for that sub-portion. convert_sub_format looks for occurences of %c
* %c (where c is passed to the function). When found, it is replaced by "%s" * (where c is passed to the function); when found, it is replaced by %s
* for use in an sprintf. All other occurences of % followed by any other * for use in an sprintf. All other occurences of % are replaced by %%.
* character are left unchanged. Only the first occurence of %c is * The string returned by this function must be freed.
* converted, all subsequent occurences are left unchanged. This routine
* mallocs the returned string.
*/ */
static char * convert_sub_format(char *format, char c, char *padded) static char *convert_sub_format(const char *format, char c, const char *padded)
{ {
char *ptr = NULL; size_t i = 0;
char buffer[BIG_BUFFER_SIZE]; char buffer[BIG_BUFFER_SIZE];
static char bletch[] = "%% ";
if (!format) if (!format)
return NULL; return NULL;
*buffer = 0; while (*format && i < sizeof buffer)
while (format)
{ {
if ((ptr = strchr(format, '%')) != NULL) buffer[i++] = *format;
if (*format == '%')
{ {
*ptr = 0; format++;
strlcat(buffer, format, sizeof buffer);
*ptr++ = '%'; if (*format == c)
if (*ptr == c)
{ {
if (*padded) if (i < sizeof buffer)
i += strlcpy(buffer + i, padded, sizeof buffer - i);
if (i < sizeof buffer)
buffer[i++] = 's';
}
else if (*format == '<')
{
const char *saved_format = format;
size_t saved_i = i;
format++;
while (strchr("0123456789.", *format) && i < sizeof buffer)
buffer[i++] = *format++;
while (*format != '>' && *format)
format++;
if (*format)
format++;
if (*format == c)
{ {
strlcat(buffer, "%", sizeof buffer); if (i < sizeof buffer)
strlcat(buffer, padded, sizeof buffer); buffer[i++] = 's';
strlcat(buffer, "s", sizeof buffer);
} }
else else
strlcat(buffer, "%s", sizeof buffer);
}
else if (*ptr == '<')
{
char *s = ptr + 1;
while (*ptr && *ptr != '>') ptr++;
if (*ptr)
{ {
ptr++; i = saved_i;
if (!*ptr) format = saved_format;
continue;
else if (*ptr == c) if (i < sizeof buffer)
{ buffer[i++] = '%';
strlcat(buffer, "%", sizeof buffer);
strlcat(buffer, s, ptr - s);
strlcat(buffer, "s", sizeof buffer);
}
}
}
else
{
bletch[2] = *ptr;
strlcat(buffer, bletch, sizeof buffer);
if (!*ptr)
{
format = ptr;
continue; continue;
} }
} }
ptr++; else
{
if (i < sizeof buffer)
buffer[i++] = '%';
continue;
}
} }
else format++;
strlcat(buffer, format, sizeof buffer); }
format = ptr;
} if (i > sizeof buffer - 1)
malloc_strcpy(&ptr, buffer); i = sizeof buffer - 1;
return ptr; buffer[i] = 0;
return m_strdup(buffer);
} }
static char *convert_format(Window *win, char *format, int k) static char *convert_format(Window *win, char *format, int k)
@@ -389,12 +389,18 @@ static char *convert_format(Window *win, char *format, int k)
} }
else if (*format == '<') else if (*format == '<')
{ {
char *p = padded; size_t pad_len;
format++; format++;
pad_len = strspn(format, "0123456789.");
memcpy(padded, format, pad_len);
padded[pad_len] = 0;
format += pad_len;
while(*format && *format != '>') while(*format && *format != '>')
*p++ = *format++; format++;
*p = 0; if (*format)
format++; format++;
} }
key = *format++; key = *format++;