pixilang crash on vprintf

Pixilang programming language
Post Reply
Ol sen
Posts: 20
Joined: Sat Feb 12, 2022 6:26 am

pixilang crash on vprintf

Post by Ol sen »

In a couple of pixilang examples the app will crash.
Debugging told me, some __VA_ARGS__ are empty while trying to vprintf or vfprintf such with too much format strings and missing arguments.
Why are arguments gone missing? Turns out some return types can't be found when they are NULL, nullptr or 0
In short amount of format strings and va_arg don't match. This will expose an BADACCESS violation and the app must crash.

fix idea: wrapp vprintf in if condition that checks for argument count and compares before printing and access to NULL argument.

problem: argument count is given as is to functions or not officially accessible.

fix: use a clever macro that makes counting of arguments possible..

found in..

file: lib_sundog/log/log.cpp in function void slog( const char* format, ... )

Code: Select all

int _debugArgSum(int count, ...) {
    va_list	arg_ptr;
    int	sum = 0;
    int	i = 0;
    int c = 0;
    va_start(arg_ptr, count);
    for (i = 0; i < count; i++) {
        sum += va_arg(arg_ptr, int);
        c++;
    }
    return c;
}
int formatCounts(const char* format) { //, ...
    int formatCount = 0;
    int len = 0;
    while (format[len]!='\0') {
        if (format[len]=='%') formatCount++;
        len++;
    }
    return formatCount;
}
#define DEBUGARGCOUNT(...) _DEBUGARGCOUNT(__VA_ARGS__,10, 9, 8, 7, 6, 5, 4, 3, 2, 1)
#define _DEBUGARGCOUNT(a, b, c, d, e, f, g, h, i, j, count, ...) count
bool compare_formatstring_and_arguments( const char* format, ... ) {
    va_list p;
    va_start( p, format );
    bool safe = formatCounts(format) <= _debugArgSum(DEBUGARGCOUNT(p),0);
    va_end(p);
    if (!safe) vprintf("argument format mismatch violation!\n");
    return safe;
}
#define ARGUMENTS_MUST_MATCH_FORMAT(fmt, p, x) if(compare_formatstring_and_arguments(fmt, p)){x;}
use as...

Code: Select all

ARGUMENTS_MUST_MATCH_FORMAT(format,p, vprintf(format,p) );
//&&
ARGUMENTS_MUST_MATCH_FORMAT(format,p, vfprintf(f,format,p) );
this will make sure no matter what, too much arguments will never crash, such malicious print will be just skipped.
Native log commands do the same with some internal macro ..
Post Reply