rewrite_percent_specifiers(char *s)
{
    char *match_start;

    while (*s)
    {
        int flags;
        /* Find a % */
        while (*s && *s != '%')
            s++;
        if (*s == 0)
            return;
        match_start = s;
        s++;
        /* Skip over flags (just one instance of any given flag, in any order) */
        flags = 0;
        while (*s) {
            if (*s == '-' && (flags & 1) == 0)
                flags |= 1;
            else if (*s == '+' && (flags & 2) == 0)
                flags |= 2;
            else if (*s == ' ' && (flags & 4) == 0)
                flags |= 4;
            else if (*s == '0' && (flags & 8) == 0)
                flags |= 8;
            else if (*s == '#' && (flags & 16) == 0)
                flags |= 16;
            else
                break;
            s++;
        }
        /* Skip over width */
        while (*s >= '0' && *s <= '9')
            s++;
        /* Skip over .precision */
        if (*s == '.' && s[1] >= '0' && s[1] <= '9') {
            s++;
            while (*s >= '0' && *s <= '9')
                s++;
        }
        /* Skip over 'l' */
        if (*s == 'l')
            s++;
        if (*s == 'd' ||
            *s == 'i' ||
            *s == 'u' ||
            *s == 'o' ||
            *s == 'x' ||
            *s == 'X') {
            /* Success! */
            memset(match_start, '*', s - match_start + 1);
        }
        /* If we have escaped percents ("%%") so the percent
           will survive a call to sprintf and co, then we need
           to drop the extra one here, because the validation
           code will see the string *after* it's been sprintf'ed.
         */
        else if (*s == '%') {
            char *s0 = s;
            while (*s0) {
                *s0 = *(s0 + 1);
                s0++;
            }
        }
    }
}
rewrite_percent_specifiers(char *s)
{
    char *match_start;

    while (*s)
    {
        int flags;
         
        while (*s && *s != '%')
            s++;
        if (*s == 0)
            return;
        match_start = s;
        s++;
         
        flags = 0;
        while (*s) {
            if (*s == '-' && (flags & 1) == 0)
                flags |= 1;
            else if (*s == '+' && (flags & 2) == 0)
                flags |= 2;
            else if (*s == ' ' && (flags & 4) == 0)
                flags |= 4;
            else if (*s == '0' && (flags & 8) == 0)
                flags |= 8;
            else if (*s == '#' && (flags & 16) == 0)
                flags |= 16;
            else
                break;
            s++;
        }
         
        while (*s >= '0' && *s <= '9')
            s++;
         
        if (*s == '.' && s[1] >= '0' && s[1] <= '9') {
            s++;
            while (*s >= '0' && *s <= '9')
                s++;
        }
         
        if (*s == 'l')
            s++;
        if (*s == 'd' ||
            *s == 'i' ||
            *s == 'u' ||
            *s == 'o' ||
            *s == 'x' ||
            *s == 'X') {
             
            memset(match_start, '*', s - match_start + 1);
        }
         
        else if (*s == '%') {
            char *s0 = s;
            while (*s0) {
                *s0 = *(s0 + 1);
                s0++;
            }
        }
    }
}