On Wed, Jan 23, 2013 at 04:49:04PM +0400, Evgeniy Stepanov wrote: > On Wed, Jan 23, 2013 at 4:39 PM, Jakub Jelinek <ja...@redhat.com> wrote: > > On Wed, Jan 23, 2013 at 04:24:01PM +0400, Evgeniy Stepanov wrote: > >> > So, e.g. whenever match_spec > >> > > returns 0, it should break out of the loop, rather than continue. > >> > > And for %hh it doesn't check following letters, no match_spec at all. > >> > >> That's cause they don't change the write size. The same for %h, the > >> following letters don't matter to us. It seems safe to "continue" as > >> soon as we are sure we know what the current spec's write length is. > > > > You can't know. What if say %hhQ is seen where Q is a user spec defined > > through some future hook? For printf you can already add things like > > that, and say let the va_arg argument be a pointer to some struct > > (some people e.g. print struct sockaddr* that way etc.). What if it takes > > more than one pointer. IMHO you really need to parse the whole directive, > > and only if you detect no errors, check the corresponding pointer (unless > > %*), if you detect any errors or unknown things, just give up immediately. > > What if these future hooks allow one to redefine existing specs? :)
That would be a violation of the standards, so nothing you need to support. But if the format string isn't valid for ISO C99/POSIX, then thge implementation can either issue error on it, or handle it as an extension somehow. > Fighting unknown future changes sounds hopeless. The only reliable way > to handle them is keeping both implementations in sync, but that's > probably not worth it. If it has hooks, you can't keep up with the hooks. You can surely implement POSIX mandated behavior (with the exception I mentioned, %as, %aS and %a[ should be conservatively handled as undefined, because they could be either %a followed by s/S/[ letter, or the GNU extension, depending on exact glibc version, preprocessor flags etc.), but if you detect an error (or unhandled thing), silently pretending there is no error is just wrong, it can crash the program etc. even when it would work fine otherwise. Even without hooks, if the format string is invalid, e.g. sscanf ("abcd", "%hhQ", (void *) 0); it will just return 0, while with the libasan instrumentation it will crash. Jakub