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

Commit175c3b8

Browse files
committed
Fix a passel of ancient bugs in to_char(), including two distinct buffer
overruns (neither of which seem likely to be exploitable as security holes,fortunately, since the provoker can't control the data written). One ofthese is due to choosing to stomp on the output of a called function, whichis bad news in any case; make it treat the called functions' results asread-only. Avoid some unnecessary palloc/pfree traffic too; it's notreally helpful to free small temporary objects, and again this is presumingmore than it ought to about the nature of the results of called functions.Per report from Patrick Welche and additional code-reading by Imad.
1 parent01e570e commit175c3b8

File tree

1 file changed

+49
-86
lines changed

1 file changed

+49
-86
lines changed

‎src/backend/utils/adt/formatting.c

Lines changed: 49 additions & 86 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/* -----------------------------------------------------------------------
22
* formatting.c
33
*
4-
* $Header: /cvsroot/pgsql/src/backend/utils/adt/formatting.c,v 1.56.2.3 2005/03/26 00:42:44 tgl Exp $
4+
* $Header: /cvsroot/pgsql/src/backend/utils/adt/formatting.c,v 1.56.2.4 2007/06/29 01:52:21 tgl Exp $
55
*
66
*
77
* Portions Copyright (c) 1999-2002, PostgreSQL Global Development Group
@@ -75,6 +75,7 @@
7575
#include<locale.h>
7676
#include<math.h>
7777
#include<float.h>
78+
#include<limits.h>
7879

7980
#include"utils/builtins.h"
8081
#include"utils/date.h"
@@ -109,8 +110,8 @@
109110
* More is in float.c
110111
* ----------
111112
*/
112-
#defineMAXFLOATWIDTH64
113-
#defineMAXDOUBLEWIDTH128
113+
#defineMAXFLOATWIDTH60
114+
#defineMAXDOUBLEWIDTH500
114115

115116
/* ----------
116117
* External (defined in PgSQL dt.c (timestamp utils))
@@ -1417,7 +1418,7 @@ str_numth(char *dest, char *num, int type)
14171418
}
14181419

14191420
/* ----------
1420-
* Convert string to upper-string. Input string is modified in place.
1421+
* Convert string to upper case. Input string is modified in place.
14211422
* ----------
14221423
*/
14231424
staticchar*
@@ -1437,7 +1438,7 @@ str_toupper(char *buff)
14371438
}
14381439

14391440
/* ----------
1440-
* Convert string to lower-string. Input string is modified in place.
1441+
* Convert string to lower case. Input string is modified in place.
14411442
* ----------
14421443
*/
14431444
staticchar*
@@ -1963,19 +1964,16 @@ dch_time(int arg, char *inout, int suf, int flag, FormatNode *node, void *data)
19631964
caseDCH_TZ:
19641965
if (flag==TO_CHAR&&tmtcTzn(tmtc))
19651966
{
1966-
intsiz=strlen(tmtcTzn(tmtc));
1967-
19681967
if (arg==DCH_TZ)
19691968
strcpy(inout,tmtcTzn(tmtc));
19701969
else
19711970
{
1972-
char*p=palloc(siz);
1971+
char*p=pstrdup(tmtcTzn(tmtc));
19731972

1974-
strcpy(p,tmtcTzn(tmtc));
19751973
strcpy(inout,str_tolower(p));
19761974
pfree(p);
19771975
}
1978-
returnsiz-1;
1976+
returnstrlen(inout)-1;
19791977
}
19801978
elseif (flag==FROM_CHAR)
19811979
elog(ERROR,"to_timestamp(): TZ/tz not supported.");
@@ -3155,7 +3153,7 @@ static char *
31553153
fill_str(char*str,intc,intmax)
31563154
{
31573155
memset(str,c,max);
3158-
*(str+max+1)='\0';
3156+
*(str+max)='\0';
31593157
returnstr;
31603158
}
31613159

@@ -4286,9 +4284,9 @@ NUM_processor(FormatNode *node, NUMDesc *Num, char *inout, char *number,
42864284
#defineNUM_TOCHAR_prepare \
42874285
do { \
42884286
len = VARSIZE(fmt) - VARHDRSZ;\
4289-
if (len <= 0)\
4287+
if (len <= 0 || len >= (INT_MAX-VARHDRSZ)/NUM_MAX_ITEM_SIZ)\
42904288
return DirectFunctionCall1(textin, CStringGetDatum(""));\
4291-
result= (text *) palloc((len * NUM_MAX_ITEM_SIZ) + 1 + VARHDRSZ);\
4289+
result= (text *) palloc((len * NUM_MAX_ITEM_SIZ) + 1 + VARHDRSZ);\
42924290
format= NUM_cache(len, &Num, VARDATA(fmt), &shouldFree);\
42934291
} while (0)
42944292

@@ -4300,28 +4298,18 @@ do { \
43004298
do { \
43014299
NUM_processor(format, &Num, VARDATA(result),\
43024300
numstr, plen, sign, TO_CHAR);\
4303-
pfree(orgnum);\
43044301
\
4305-
if (shouldFree)\
4306-
pfree(format);\
4302+
if (shouldFree)\
4303+
pfree(format);\
43074304
\
4308-
/*
4309-
* for result is allocated max memory, which current format-picture\
4310-
* needs, now it must be re-allocate to result real size\
4305+
/*\
4306+
* Convert null-terminated representation of result to standard text. \
4307+
* The result is usually much bigger than it needs to be, but there \
4308+
* seems little point in realloc'ing it smaller. \
43114309
*/\
4312-
if (!(len=strlen(VARDATA(result))))\
4313-
{\
4314-
pfree(result);\
4315-
PG_RETURN_NULL();\
4316-
}\
4317-
\
4318-
result_tmp=result;\
4319-
result= (text*)palloc(len+1+VARHDRSZ);\
4320-
\
4321-
strcpy(VARDATA(result),VARDATA(result_tmp));\
4322-
VARATT_SIZEP(result)=len+VARHDRSZ;\
4323-
pfree(result_tmp);\
4324-
}while(0)
4310+
len=strlen(VARDATA(result));\
4311+
VARATT_SIZEP(result)=len+VARHDRSZ;\
4312+
}while (0)
43254313

43264314
/* -------------------
43274315
* NUMERIC to_number() (convert string to numeric)
@@ -4343,7 +4331,7 @@ numeric_to_number(PG_FUNCTION_ARGS)
43434331

43444332
len=VARSIZE(fmt)-VARHDRSZ;
43454333

4346-
if (len <=0)
4334+
if (len <=0||len >=INT_MAX/NUM_MAX_ITEM_SIZ)
43474335
PG_RETURN_NULL();
43484336

43494337
format=NUM_cache(len,&Num,VARDATA(fmt),&shouldFree);
@@ -4378,8 +4366,7 @@ numeric_to_char(PG_FUNCTION_ARGS)
43784366
text*fmt=PG_GETARG_TEXT_P(1);
43794367
NUMDescNum;
43804368
FormatNode*format;
4381-
text*result,
4382-
*result_tmp;
4369+
text*result;
43834370
boolshouldFree;
43844371
intlen=0,
43854372
plen=0,
@@ -4402,7 +4389,6 @@ numeric_to_char(PG_FUNCTION_ARGS)
44024389
numstr=orgnum=
44034390
int_to_roman(DatumGetInt32(DirectFunctionCall1(numeric_int4,
44044391
NumericGetDatum(x))));
4405-
pfree(x);
44064392
}
44074393
else
44084394
{
@@ -4421,9 +4407,6 @@ numeric_to_char(PG_FUNCTION_ARGS)
44214407
val=DatumGetNumeric(DirectFunctionCall2(numeric_mul,
44224408
NumericGetDatum(value),
44234409
NumericGetDatum(x)));
4424-
pfree(x);
4425-
pfree(a);
4426-
pfree(b);
44274410
Num.pre+=Num.multi;
44284411
}
44294412

@@ -4432,10 +4415,9 @@ numeric_to_char(PG_FUNCTION_ARGS)
44324415
Int32GetDatum(Num.post)));
44334416
orgnum=DatumGetCString(DirectFunctionCall1(numeric_out,
44344417
NumericGetDatum(x)));
4435-
pfree(x);
44364418

44374419
if (*orgnum=='-')
4438-
{/* < 0 */
4420+
{
44394421
sign='-';
44404422
numstr=orgnum+1;
44414423
}
@@ -4454,13 +4436,10 @@ numeric_to_char(PG_FUNCTION_ARGS)
44544436

44554437
elseif (len>Num.pre)
44564438
{
4457-
fill_str(numstr,'#',Num.pre);
4439+
numstr= (char*)palloc(Num.pre+Num.post+2);
4440+
fill_str(numstr,'#',Num.pre+Num.post+1);
44584441
*(numstr+Num.pre)='.';
4459-
fill_str(numstr+1+Num.pre,'#',Num.post);
44604442
}
4461-
4462-
if (IS_MULTI(&Num))
4463-
pfree(val);
44644443
}
44654444

44664445
NUM_TOCHAR_finish;
@@ -4478,8 +4457,7 @@ int4_to_char(PG_FUNCTION_ARGS)
44784457
text*fmt=PG_GETARG_TEXT_P(1);
44794458
NUMDescNum;
44804459
FormatNode*format;
4481-
text*result,
4482-
*result_tmp;
4460+
text*result;
44834461
boolshouldFree;
44844462
intlen=0,
44854463
plen=0,
@@ -4507,40 +4485,34 @@ int4_to_char(PG_FUNCTION_ARGS)
45074485
orgnum=DatumGetCString(DirectFunctionCall1(int4out,
45084486
Int32GetDatum(value)));
45094487
}
4510-
len=strlen(orgnum);
45114488

45124489
if (*orgnum=='-')
4513-
{/* < 0 */
4490+
{
45144491
sign='-';
4515-
--len;
4492+
orgnum++;
45164493
}
45174494
else
45184495
sign='+';
4496+
len=strlen(orgnum);
45194497

45204498
if (Num.post)
45214499
{
4522-
inti;
4523-
45244500
numstr= (char*)palloc(len+Num.post+2);
4525-
strcpy(numstr,orgnum+ (*orgnum=='-' ?1 :0));
4501+
strcpy(numstr,orgnum);
45264502
*(numstr+len)='.';
4527-
4528-
for (i=len+1;i <=len+Num.post;i++)
4529-
*(numstr+i)='0';
4503+
memset(numstr+len+1,'0',Num.post);
45304504
*(numstr+len+Num.post+1)='\0';
4531-
pfree(orgnum);
4532-
orgnum=numstr;
45334505
}
45344506
else
4535-
numstr=orgnum+ (*orgnum=='-' ?1 :0);
4507+
numstr=orgnum;
45364508

45374509
if (Num.pre>len)
45384510
plen=Num.pre-len;
45394511
elseif (len>Num.pre)
45404512
{
4541-
fill_str(numstr,'#',Num.pre);
4513+
numstr= (char*)palloc(Num.pre+Num.post+2);
4514+
fill_str(numstr,'#',Num.pre+Num.post+1);
45424515
*(numstr+Num.pre)='.';
4543-
fill_str(numstr+1+Num.pre,'#',Num.post);
45444516
}
45454517
}
45464518

@@ -4559,8 +4531,7 @@ int8_to_char(PG_FUNCTION_ARGS)
45594531
text*fmt=PG_GETARG_TEXT_P(1);
45604532
NUMDescNum;
45614533
FormatNode*format;
4562-
text*result,
4563-
*result_tmp;
4534+
text*result;
45644535
boolshouldFree;
45654536
intlen=0,
45664537
plen=0,
@@ -4594,40 +4565,34 @@ int8_to_char(PG_FUNCTION_ARGS)
45944565

45954566
orgnum=DatumGetCString(DirectFunctionCall1(int8out,
45964567
Int64GetDatum(value)));
4597-
len=strlen(orgnum);
45984568

45994569
if (*orgnum=='-')
4600-
{/* < 0 */
4570+
{
46014571
sign='-';
4602-
--len;
4572+
orgnum++;
46034573
}
46044574
else
46054575
sign='+';
4576+
len=strlen(orgnum);
46064577

46074578
if (Num.post)
46084579
{
4609-
inti;
4610-
46114580
numstr= (char*)palloc(len+Num.post+2);
4612-
strcpy(numstr,orgnum+ (*orgnum=='-' ?1 :0));
4581+
strcpy(numstr,orgnum);
46134582
*(numstr+len)='.';
4614-
4615-
for (i=len+1;i <=len+Num.post;i++)
4616-
*(numstr+i)='0';
4583+
memset(numstr+len+1,'0',Num.post);
46174584
*(numstr+len+Num.post+1)='\0';
4618-
pfree(orgnum);
4619-
orgnum=numstr;
46204585
}
46214586
else
4622-
numstr=orgnum+ (*orgnum=='-' ?1 :0);
4587+
numstr=orgnum;
46234588

46244589
if (Num.pre>len)
46254590
plen=Num.pre-len;
46264591
elseif (len>Num.pre)
46274592
{
4628-
fill_str(numstr,'#',Num.pre);
4593+
numstr= (char*)palloc(Num.pre+Num.post+2);
4594+
fill_str(numstr,'#',Num.pre+Num.post+1);
46294595
*(numstr+Num.pre)='.';
4630-
fill_str(numstr+1+Num.pre,'#',Num.post);
46314596
}
46324597
}
46334598

@@ -4646,8 +4611,7 @@ float4_to_char(PG_FUNCTION_ARGS)
46464611
text*fmt=PG_GETARG_TEXT_P(1);
46474612
NUMDescNum;
46484613
FormatNode*format;
4649-
text*result,
4650-
*result_tmp;
4614+
text*result;
46514615
boolshouldFree;
46524616
intlen=0,
46534617
plen=0,
@@ -4706,9 +4670,9 @@ float4_to_char(PG_FUNCTION_ARGS)
47064670

47074671
elseif (len>Num.pre)
47084672
{
4709-
fill_str(numstr,'#',Num.pre);
4673+
numstr= (char*)palloc(Num.pre+Num.post+2);
4674+
fill_str(numstr,'#',Num.pre+Num.post+1);
47104675
*(numstr+Num.pre)='.';
4711-
fill_str(numstr+1+Num.pre,'#',Num.post);
47124676
}
47134677
}
47144678

@@ -4727,8 +4691,7 @@ float8_to_char(PG_FUNCTION_ARGS)
47274691
text*fmt=PG_GETARG_TEXT_P(1);
47284692
NUMDescNum;
47294693
FormatNode*format;
4730-
text*result,
4731-
*result_tmp;
4694+
text*result;
47324695
boolshouldFree;
47334696
intlen=0,
47344697
plen=0,
@@ -4785,9 +4748,9 @@ float8_to_char(PG_FUNCTION_ARGS)
47854748

47864749
elseif (len>Num.pre)
47874750
{
4788-
fill_str(numstr,'#',Num.pre);
4751+
numstr= (char*)palloc(Num.pre+Num.post+2);
4752+
fill_str(numstr,'#',Num.pre+Num.post+1);
47894753
*(numstr+Num.pre)='.';
4790-
fill_str(numstr+1+Num.pre,'#',Num.post);
47914754
}
47924755
}
47934756

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp