On Dec 12, 2009, at 10:28 PM, William A. Rowe Jr. wrote: > Sander Temme wrote: >> >> But do you agree that we should support %lld and that inside the if >> statement starting line 832 of apr_snprintf.c is a good spot to set var_type >> = IS_QUAD? > > exactly, there is nothing appropriate about a 'conditional' format type. > I used the sizeof(int) == sizeof(long) to illustrate this :)
Actually, that approach doesn't work because the logic never gets there. When
you feed "lld" (we lost the % earlier) into the following convoluted if
statement:
if ((sizeof(APR_INT64_T_FMT) == 4 &&
fmt[0] == APR_INT64_T_FMT[0] &&
fmt[1] == APR_INT64_T_FMT[1]) ||
(sizeof(APR_INT64_T_FMT) == 3 &&
fmt[0] == APR_INT64_T_FMT[0]) ||
(sizeof(APR_INT64_T_FMT) > 4 &&
strncmp(fmt, APR_INT64_T_FMT,
sizeof(APR_INT64_T_FMT) - 2) == 0)) {
it's caught by the middle one since (sizeof("ld\0") == 3 && fmt[0] == 'l')
which is subsequently stripped. The remaining "ld" goes into the switch, which
doesn't match 'l' so it falls to the default which prints the remaining
unrecognized characters back to the caller:
/*
* The default case is for unrecognized %'s.
* We print %<char> to help the user identify what
* option is not understood.
* This is also useful in case the user wants to pass
* the output of format_converter to another function
* that understands some other %<char> (like syslog).
* Note that we can't point s inside fmt because the
* unknown <char> could be preceded by width etc.
*/
default:
char_buf[0] = '%';
char_buf[1] = *fmt;
s = char_buf;
s_len = 2;
pad_char = ' ';
break;
which is exactly what we're seeing.
So how would we go about recognizing the oddly long "%lld" that we have foisted
upon ourselves?
S.
--
[email protected] http://www.temme.net/sander/
PGP FP: 51B4 8727 466A 0BC3 69F4 B7B8 B2BE BC40 1529 24AF
smime.p7s
Description: S/MIME cryptographic signature
