"[EMAIL PROTECTED] (via RT)" <[EMAIL PROTECTED]> wrote: :When Perl 5.8.7 is compiled without -DUSE_LONG_DOUBLE, an API call :sv_vcatpvfn(sv, "%.1f", 4, &va_list, NULL, 0, NULL) doesn't work :properly. It is because an argument (type of double) in va_list is :swallowed during the special treatment for "%.<number>[gf]" format. :A quick patch follows: : :--- sv.c.orig Thu Jun 16 22:26:21 2005 :+++ sv.c Thu Jun 16 22:27:33 2005 :@@ -8403,7 +8403,7 @@ : pp = pat + 2; : while (*pp >= '0' && *pp <= '9') : digits = 10 * digits + (*pp++ - '0'); :- if (pp - pat == (int)patlen - 1) { :+ if (pp - pat == (int)patlen - 1 && (*pp == 'g' || !digits)) { : NV nv; : : if (args)
There are in fact several ways we can fall through to the standard code after grabbing the argument, so all of them are buggy in the same way. I'm not sure how we can fix the other cases though, since we need to get the NV and try stuff before we know whether we're going to get an ok result. I guess it might be possible to introduce an additional flag "I've already grabbed this arg", but that's going to complicate the code quite a lot. So I guess the question becomes: how useful is this optimisation anyway? Do we lose that much if we just rip it out? In the meantime, the patch below might be useful for testing, and something similar but less drastic is probably needed for production. (This patch against [EMAIL PROTECTED], the line numbers tend to move around quite a lot.) Hmm, I wonder how portable it would be to save a va_list* pointer and then reuse it, to allow us to step back to arguments previously read from the list. I'm pretty sure you're not allowed to do that, but I suspect the vast majority of implementations would cope. Hugo --- sv.c.old Mon Mar 21 10:06:39 2005 +++ sv.c Thu Jun 16 15:21:44 2005 @@ -9239,6 +9239,7 @@ return; } } + Perl_croak(aTHX_ "panic: unsafe fallthrough from /%.\d+[fg]/ optimisation"); } } #endif /* !USE_LONG_DOUBLE */