You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
curl_mfprintf precision parameter isn't working right for floating point #1113
/* pick up the specified precision */if(p->flags&FLAGS_PRECPARAM) {
prec= (long)vto[p->precision].data.num.as_signed;
param_num++; /* since the precision is extracted from a parameter, we must skip that to get to the next one properly */if(prec<0)
/* "A negative precision is taken as if the precision were omitted." */prec=-1;
}
elseif(p->flags&FLAGS_PREC)
prec=p->precision;
elseprec=-1;
p->flags is FLAGS_PREC | FLAGS_PRECPARAM, p->precision is 1,
and so the precision is correctly set from the parameter as 6.
Next the specific type processing is done for FORMAT_DOUBLE and it resets both width and precision, as seen here:
p->flags and p->precision are unchanged so prec is incorrectly set as 1 and that's what causes the output to be rounded to 2.3. I'm baffled by the different processing at this point. It looks like width may have a similar issue.
While the patch may be correct I still don't get it. Before type specific processing is done the width and the precision are obtained, which makes sense, because that way they can be used for any type. But then why is it overridden for float type? Is it possible that's some artifact that was supposed to be removed?
I wouldn't call it "overridden". There are two separate code paths, one that output integers and one that deals with floats, so width and precision are handled in two places. The code path for floats checks the flags in the other order so it is sensitive to FLAGS_PREC being set together with FLAGS_PRECPARAM while the integer code path is not. Those flags are mutually exclusive anyway.
But why. If the bug is the flags are supposed to be mutually exclusive then it's almost the same logic in both places. It looks wrong, the main prec/width logic accounts for negative values and the float prec/width logic does away with that. Try curl_mfprintf(stderr, "%*f", -12, 3.1); it doesn't set the width. I do see one difference I can't explain, if not FLAGS_WIDTHPARAM then the main logic will set width = p->width even if not FLAGS_WIDTH. However in float logic if there's no FLAGS_WIDTH then width is -1
You're obviously now talking about other things than this particular issue. I will not deny that the mprintf() function can be improved, but I'm saying that my landed commit fixes the issues you reported.
The not handling of negative width seems like a bug for example.
But note: A) this function is deprecated and we strongly advice people not to use it in programs and B) we don't use such features in curl or libcurl. I'm not that concerned, but if you feel like it, do add more test cases and fix remaining bugs.
Activity
bagder commentedon Nov 8, 2016
I'm extending test 557 right now and will add some test strings for this as well and then we can get a patch going.
bagder commentedon Nov 8, 2016
(removed a comment I made based on me not reading correctly)
bagder commentedon Nov 8, 2016
Remove a single line seems to fix it (I have a larger amount of float tests to add to also make sure we don't regress).
printf: fix ".*f" handling
bagder commentedon Nov 8, 2016
I decided to push it. I figured you could try it out and if it fixes the issue for you as well, we can close this as fixed.
jay commentedon Nov 8, 2016
While the patch may be correct I still don't get it. Before type specific processing is done the width and the precision are obtained, which makes sense, because that way they can be used for any type. But then why is it overridden for float type? Is it possible that's some artifact that was supposed to be removed?
bagder commentedon Nov 8, 2016
I wouldn't call it "overridden". There are two separate code paths, one that output integers and one that deals with floats, so width and precision are handled in two places. The code path for floats checks the flags in the other order so it is sensitive to
FLAGS_PRECbeing set together withFLAGS_PRECPARAMwhile the integer code path is not. Those flags are mutually exclusive anyway.jay commentedon Nov 10, 2016
But why. If the bug is the flags are supposed to be mutually exclusive then it's almost the same logic in both places. It looks wrong, the main prec/width logic accounts for negative values and the float prec/width logic does away with that. Try
curl_mfprintf(stderr, "%*f", -12, 3.1);it doesn't set the width. I do see one difference I can't explain, if not FLAGS_WIDTHPARAM then the main logic will setwidth = p->widtheven if not FLAGS_WIDTH. However in float logic if there's no FLAGS_WIDTH then width is -1bagder commentedon Nov 10, 2016
You're obviously now talking about other things than this particular issue. I will not deny that the mprintf() function can be improved, but I'm saying that my landed commit fixes the issues you reported.
The not handling of negative width seems like a bug for example.
But note: A) this function is deprecated and we strongly advice people not to use it in programs and B) we don't use such features in curl or libcurl. I'm not that concerned, but if you feel like it, do add more test cases and fix remaining bugs.
jay commentedon Nov 10, 2016
Well I'm talking about something other than your solution but I think it's related. Fair enough though I will investigate more and start a new issue.