cosmopolitan icon indicating copy to clipboard operation
cosmopolitan copied to clipboard

printf %n is not implemented

Open fabriziobertocci opened this issue 4 years ago • 5 comments

The following code does not work as expected:

int main(int argc, char **argv) {
    int i, len;
    char buf[100];
    len = snprintf(buf, sizeof(buf), "Hello-%n%s", &i, argv[0]);
    printf(">> all=%s\n", buf);
    printf(">> par=%.*s\n", len-i, &buf[i]);
    return 0;
}

When compiled on Linux, the output is:

>> all=Hello-./main
>> par=./main

When compiled with Cosmopolitan, the output is:

>> all=Hello-n�,@
>> par=

fabriziobertocci avatar Mar 23 '21 13:03 fabriziobertocci

I can get that fixed for you.

jart avatar Mar 23 '21 19:03 jart

Hi Justine, It's not blocking right now (I have split a single, clumsy, unreadable call to snprintf to two separate ones).... but I created that task just to remember to do it eventually (I can also take a look later). (I am testing the implementation of the syslog-related functions). Regards, Fab

On Tue, Mar 23, 2021 at 3:34 PM Justine Tunney @.***> wrote:

I can get that fixed for you.

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/jart/cosmopolitan/issues/133#issuecomment-805177292, or unsubscribe https://github.com/notifications/unsubscribe-auth/AB5RDSKWUS5D7VYD5ZYURRTTFDUM3ANCNFSM4ZVG3L7Q .

fabriziobertocci avatar Mar 23 '21 19:03 fabriziobertocci

Hmm it seems this is the formatting directive that has a history of being misused. Sadly POSIX doesn't say it's optional. Implementing this one is going to be a little painful because __fmt currently doesn't track the number of bytes written, but that could be changed.

jart avatar Apr 02 '21 03:04 jart

Is there such a thing as a legitimate use of %n which isn't for exploit development ?

Internet experts seem to consider that question an open question:

  • https://stackoverflow.com/questions/3401156/what-is-the-use-of-the-n-format-specifier-in-c
  • https://news.ycombinator.com/item?id=24317249

Wouldn't « implementing a new libc » be the right place to stop that questionable option from being a thing, and not implement it ?

59e5aaf4 avatar Jun 21 '21 14:06 59e5aaf4

Is there such a thing as a legitimate use of %n which isn't for exploit development ?

FWIW, I use it everyday for parsing lists of numbers of unknown length (typically 2 or 3 numbers)

    // fill the array "t" with at most "nmax" numbers parsed from the string "s"
    // return the number of parsed numbers
    // example:
    //        double t[10];
    //        int n = parse_doubles(t, 10, "[1, 2, 3; 4, 5, 6]");
    //        // n = 6; t = {1,2,3,4,5,6}
    int parse_doubles(double *t, int nmax, const char *s)
    {
            int i = 0, w;
            while (i < nmax && 1 == sscanf(s, "%*[][ \n\t,:;]%lf%n", t + i, &w)) {
                    i += 1;
                    s += w;
            }
            return i;
    }

but this is just a matter of lazy convenience. It wouldn't be a great deal if it disappeared, and I would totally understand the reasons.

mnhrdt avatar Jun 21 '21 15:06 mnhrdt