mirror of
https://gitlab.xiph.org/xiph/icecast-common.git
synced 2024-12-04 14:46:31 -05:00
This is part of the patch-set addressing CVE-2011-4612.
svn path=/icecast/trunk/log/; revision=18356
This commit is contained in:
parent
8e7def3ad4
commit
51271b13e7
133
log/log.c
133
log/log.c
@ -419,11 +419,132 @@ void log_contents (int log_id, char **_contents, unsigned int *_len)
|
|||||||
_unlock_logger ();
|
_unlock_logger ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void __vsnprintf(char *str, size_t size, const char *format, va_list ap) {
|
||||||
|
int in_block = 0;
|
||||||
|
int block_size = 0;
|
||||||
|
int block_len;
|
||||||
|
const char * arg;
|
||||||
|
char buf[80];
|
||||||
|
|
||||||
|
for (; *format && size; format++)
|
||||||
|
{
|
||||||
|
if ( !in_block )
|
||||||
|
{
|
||||||
|
if ( *format == '%' ) {
|
||||||
|
in_block = 1;
|
||||||
|
block_size = 0;
|
||||||
|
block_len = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
*(str++) = *format;
|
||||||
|
size--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// TODO: %l*[sdupi] as well as %.4080s and "%.*s
|
||||||
|
arg = NULL;
|
||||||
|
switch (*format)
|
||||||
|
{
|
||||||
|
case 'l':
|
||||||
|
block_size++;
|
||||||
|
break;
|
||||||
|
case '.':
|
||||||
|
// just ignore '.'. If somebody cares: fix it.
|
||||||
|
break;
|
||||||
|
case '*':
|
||||||
|
block_len = va_arg(ap, int);
|
||||||
|
break;
|
||||||
|
case '1':
|
||||||
|
case '2':
|
||||||
|
case '3':
|
||||||
|
case '4':
|
||||||
|
case '5':
|
||||||
|
case '6':
|
||||||
|
case '7':
|
||||||
|
case '8':
|
||||||
|
case '9':
|
||||||
|
block_len = atoi(format);
|
||||||
|
for (; *format >= '0' && *format <= '9'; format++);
|
||||||
|
break;
|
||||||
|
case 'p':
|
||||||
|
snprintf(buf, sizeof(buf), "%p", (void*)va_arg(ap, void *));
|
||||||
|
arg = buf;
|
||||||
|
case 'd':
|
||||||
|
case 'i':
|
||||||
|
case 'u':
|
||||||
|
if (!arg)
|
||||||
|
{
|
||||||
|
switch (block_size)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
if (*format == 'u')
|
||||||
|
snprintf(buf, sizeof(buf), "%u", (unsigned int)va_arg(ap, unsigned int));
|
||||||
|
else
|
||||||
|
snprintf(buf, sizeof(buf), "%i", (int)va_arg(ap, int));
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
if (*format == 'u')
|
||||||
|
snprintf(buf, sizeof(buf), "%lu", (unsigned long int)va_arg(ap, unsigned long int));
|
||||||
|
else
|
||||||
|
snprintf(buf, sizeof(buf), "%li", (long int)va_arg(ap, long int));
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
if (*format == 'u')
|
||||||
|
snprintf(buf, sizeof(buf), "%llu", (unsigned long long int)va_arg(ap, unsigned long long int));
|
||||||
|
else
|
||||||
|
snprintf(buf, sizeof(buf), "%lli", (long long int)va_arg(ap, long long int));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
snprintf(buf, sizeof(buf), "<<<invalid>>>");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
arg = buf;
|
||||||
|
}
|
||||||
|
case 's':
|
||||||
|
case 'H':
|
||||||
|
// TODO.
|
||||||
|
if (!arg)
|
||||||
|
arg = va_arg(ap, const char *);
|
||||||
|
if (!arg)
|
||||||
|
arg = "(null)";
|
||||||
|
if (!block_len)
|
||||||
|
block_len = strlen(arg);
|
||||||
|
|
||||||
|
// the if() is the outer structure so the inner for()
|
||||||
|
// is branch optimized.
|
||||||
|
if (*format == 'H' )
|
||||||
|
{
|
||||||
|
for (; *arg && block_len && size; arg++, size--)
|
||||||
|
{
|
||||||
|
if (*arg <= '"')
|
||||||
|
*(str++) = '.';
|
||||||
|
else
|
||||||
|
*(str++) = *arg;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (; *arg && block_len && size; arg++, size--)
|
||||||
|
*(str++) = *arg;
|
||||||
|
}
|
||||||
|
in_block = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( !size )
|
||||||
|
str--;
|
||||||
|
|
||||||
|
*str = 0;
|
||||||
|
}
|
||||||
|
|
||||||
void log_write(int log_id, unsigned priority, const char *cat, const char *func,
|
void log_write(int log_id, unsigned priority, const char *cat, const char *func,
|
||||||
const char *fmt, ...)
|
const char *fmt, ...)
|
||||||
{
|
{
|
||||||
static char *prior[] = { "EROR", "WARN", "INFO", "DBUG" };
|
static const char *prior[] = { "EROR", "WARN", "INFO", "DBUG" };
|
||||||
int datelen;
|
int datelen;
|
||||||
time_t now;
|
time_t now;
|
||||||
char pre[256];
|
char pre[256];
|
||||||
@ -434,16 +555,16 @@ void log_write(int log_id, unsigned priority, const char *cat, const char *func,
|
|||||||
if (loglist[log_id].level < priority) return;
|
if (loglist[log_id].level < priority) return;
|
||||||
if (priority > sizeof(prior)/sizeof(prior[0])) return; /* Bad priority */
|
if (priority > sizeof(prior)/sizeof(prior[0])) return; /* Bad priority */
|
||||||
|
|
||||||
|
|
||||||
va_start(ap, fmt);
|
va_start(ap, fmt);
|
||||||
vsnprintf(line, LOG_MAXLINELEN, fmt, ap);
|
__vsnprintf(line, sizeof(line), fmt, ap);
|
||||||
|
va_end(ap);
|
||||||
|
|
||||||
now = time(NULL);
|
now = time(NULL);
|
||||||
|
|
||||||
_lock_logger();
|
|
||||||
datelen = strftime (pre, sizeof (pre), "[%Y-%m-%d %H:%M:%S]", localtime(&now));
|
datelen = strftime (pre, sizeof (pre), "[%Y-%m-%d %H:%M:%S]", localtime(&now));
|
||||||
|
|
||||||
snprintf (pre+datelen, sizeof (pre)-datelen, " %s %s%s ", prior [priority-1], cat, func);
|
snprintf (pre+datelen, sizeof (pre)-datelen, " %s %s%s ", prior [priority-1], cat, func);
|
||||||
|
|
||||||
|
_lock_logger();
|
||||||
if (_log_open (log_id))
|
if (_log_open (log_id))
|
||||||
{
|
{
|
||||||
int len = create_log_entry (log_id, pre, line);
|
int len = create_log_entry (log_id, pre, line);
|
||||||
@ -451,8 +572,6 @@ void log_write(int log_id, unsigned priority, const char *cat, const char *func,
|
|||||||
loglist[log_id].size += len;
|
loglist[log_id].size += len;
|
||||||
}
|
}
|
||||||
_unlock_logger();
|
_unlock_logger();
|
||||||
|
|
||||||
va_end(ap);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void log_write_direct(int log_id, const char *fmt, ...)
|
void log_write_direct(int log_id, const char *fmt, ...)
|
||||||
|
Loading…
Reference in New Issue
Block a user