Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit2ac95c8

Browse files
committed
port/snprintf(): fix overflow and do padding
Prevent port/snprintf() from overflowing its local fixed-sizebuffer and pad to the desired number of digits with zeros, evenif the precision is beyond the ability of the native sprintf().port/snprintf() is only used on systems that lack a nativesnprintf().Reported by Bruce Momjian. Patch by Tom Lane.Backpatch to allsupported versions.Security:CVE-2015-0242
1 parent56d2bee commit2ac95c8

File tree

1 file changed

+62
-7
lines changed

1 file changed

+62
-7
lines changed

‎src/port/snprintf.c

Lines changed: 62 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,9 @@
3232

3333
#include"c.h"
3434

35+
#include<ctype.h>
3536
#include<limits.h>
37+
#include<math.h>
3638
#ifndefWIN32
3739
#include<sys/ioctl.h>
3840
#endif
@@ -932,27 +934,80 @@ fmtfloat(double value, char type, int forcesign, int leftjust,
932934
PrintfTarget*target)
933935
{
934936
intsignvalue=0;
937+
intprec;
935938
intvallen;
936939
charfmt[32];
937-
charconvert[512];
938-
intpadlen=0;/* amount to pad */
940+
charconvert[1024];
941+
intzeropadlen=0;/* amount to pad with zeroes */
942+
intpadlen=0;/* amount to pad with spaces */
943+
944+
/*
945+
* We rely on the regular C library's sprintf to do the basic conversion,
946+
* then handle padding considerations here.
947+
*
948+
* The dynamic range of "double" is about 1E+-308 for IEEE math, and not
949+
* too wildly more than that with other hardware. In "f" format, sprintf
950+
* could therefore generate at most 308 characters to the left of the
951+
* decimal point; while we need to allow the precision to get as high as
952+
* 308+17 to ensure that we don't truncate significant digits from very
953+
* small values. To handle both these extremes, we use a buffer of 1024
954+
* bytes and limit requested precision to 350 digits; this should prevent
955+
* buffer overrun even with non-IEEE math. If the original precision
956+
* request was more than 350, separately pad with zeroes.
957+
*/
958+
if (precision<0)/* cover possible overflow of "accum" */
959+
precision=0;
960+
prec=Min(precision,350);
939961

940-
/* we rely on regular C library's sprintf to do the basic conversion */
941962
if (pointflag)
942-
sprintf(fmt,"%%.%d%c",precision,type);
963+
{
964+
sprintf(fmt,"%%.%d%c",prec,type);
965+
zeropadlen=precision-prec;
966+
}
943967
else
944968
sprintf(fmt,"%%%c",type);
945969

946-
if (adjust_sign((value<0),forcesign,&signvalue))
970+
if (!isnan(value)&&adjust_sign((value<0),forcesign,&signvalue))
947971
value=-value;
948972

949973
vallen=sprintf(convert,fmt,value);
950974

951-
adjust_padlen(minlen,vallen,leftjust,&padlen);
975+
/* If it's infinity or NaN, forget about doing any zero-padding */
976+
if (zeropadlen>0&& !isdigit((unsignedchar)convert[vallen-1]))
977+
zeropadlen=0;
978+
979+
adjust_padlen(minlen,vallen+zeropadlen,leftjust,&padlen);
952980

953981
leading_pad(zpad,&signvalue,&padlen,target);
954982

955-
dostr(convert,vallen,target);
983+
if (zeropadlen>0)
984+
{
985+
/* If 'e' or 'E' format, inject zeroes before the exponent */
986+
char*epos=strrchr(convert,'e');
987+
988+
if (!epos)
989+
epos=strrchr(convert,'E');
990+
if (epos)
991+
{
992+
/* pad after exponent */
993+
dostr(convert,epos-convert,target);
994+
while (zeropadlen-->0)
995+
dopr_outch('0',target);
996+
dostr(epos,vallen- (epos-convert),target);
997+
}
998+
else
999+
{
1000+
/* no exponent, pad after the digits */
1001+
dostr(convert,vallen,target);
1002+
while (zeropadlen-->0)
1003+
dopr_outch('0',target);
1004+
}
1005+
}
1006+
else
1007+
{
1008+
/* no zero padding, just emit the number as-is */
1009+
dostr(convert,vallen,target);
1010+
}
9561011

9571012
trailing_pad(&padlen,target);
9581013
}

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp