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

Commit7ecdeb5

Browse files
committed
Fix over-allocation of space for array_out()'s result string.
array_out overestimated the space needed for its output, possibly bya very substantial amount if the array is multi-dimensional, becauseof wrong order of operations in the loop that counts the number ofcurly-brace pairs needed. While the output string is normallyshort-lived, this could still cause problems in extreme cases.An additional minor error was that it counted one more delimiter thanis actually needed.Repair those errors, add an Assert that the space is now correctlycalculated, and make some minor improvements in the comments.I also failed to resist the temptation to get rid of an integermodulus operation per array element; a simple comparison is sufficient.This bug dates clear back to Berkeley days, so back-patch to allsupported versions.Keiichi Hirobe, minor additional work by meDiscussion:https://postgr.es/m/CAH=EFxE9W0tRvQkixR2XJRRCToUYUEDkJZk6tnADXugPBRdcdg@mail.gmail.com
1 parent402da70 commit7ecdeb5

File tree

1 file changed

+22
-10
lines changed

1 file changed

+22
-10
lines changed

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

Lines changed: 22 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -976,8 +976,8 @@ array_out(PG_FUNCTION_ARGS)
976976
intbitmask;
977977
bool*needquotes,
978978
needdims= false;
979+
size_toverall_length;
979980
intnitems,
980-
overall_length,
981981
i,
982982
j,
983983
k,
@@ -1050,7 +1050,7 @@ array_out(PG_FUNCTION_ARGS)
10501050
*/
10511051
values= (char**)palloc(nitems*sizeof(char*));
10521052
needquotes= (bool*)palloc(nitems*sizeof(bool));
1053-
overall_length=1;/* don't forget to count \0 at end. */
1053+
overall_length=0;
10541054

10551055
p=ARR_DATA_PTR(v);
10561056
bitmap=ARR_NULLBITMAP(v);
@@ -1105,7 +1105,7 @@ array_out(PG_FUNCTION_ARGS)
11051105
/* Count the pair of double quotes, if needed */
11061106
if (needquote)
11071107
overall_length+=2;
1108-
/* and the comma */
1108+
/* and the comma(or other typdelim delimiter)*/
11091109
overall_length+=1;
11101110

11111111
/* advance bitmap pointer if any */
@@ -1121,14 +1121,19 @@ array_out(PG_FUNCTION_ARGS)
11211121
}
11221122

11231123
/*
1124-
* count total number of curly braces in output string
1124+
* The very last array element doesn't have a typdelim delimiter after it,
1125+
* but that's OK; that space is needed for the trailing '\0'.
1126+
*
1127+
* Now count total number of curly brace pairs in output string.
11251128
*/
11261129
for (i=j=0,k=1;i<ndim;i++)
1127-
k *=dims[i],j+=k;
1130+
{
1131+
j+=k,k *=dims[i];
1132+
}
1133+
overall_length+=2*j;
11281134

1135+
/* Format explicit dimensions if required */
11291136
dims_str[0]='\0';
1130-
1131-
/* add explicit dimensions if required */
11321137
if (needdims)
11331138
{
11341139
char*ptr=dims_str;
@@ -1140,9 +1145,11 @@ array_out(PG_FUNCTION_ARGS)
11401145
}
11411146
*ptr++=*ASSGN;
11421147
*ptr='\0';
1148+
overall_length+=ptr-dims_str;
11431149
}
11441150

1145-
retval= (char*)palloc(strlen(dims_str)+overall_length+2*j);
1151+
/* Now construct the output string */
1152+
retval= (char*)palloc(overall_length);
11461153
p=retval;
11471154

11481155
#defineAPPENDSTR(str)(strcpy(p, (str)), p += strlen(p))
@@ -1180,21 +1187,26 @@ array_out(PG_FUNCTION_ARGS)
11801187

11811188
for (i=ndim-1;i >=0;i--)
11821189
{
1183-
indx[i]= (indx[i]+1) %dims[i];
1184-
if (indx[i])
1190+
if (++(indx[i])<dims[i])
11851191
{
11861192
APPENDCHAR(typdelim);
11871193
break;
11881194
}
11891195
else
1196+
{
1197+
indx[i]=0;
11901198
APPENDCHAR('}');
1199+
}
11911200
}
11921201
j=i;
11931202
}while (j!=-1);
11941203

11951204
#undef APPENDSTR
11961205
#undef APPENDCHAR
11971206

1207+
/* Assert that we calculated the string length accurately */
1208+
Assert(overall_length== (p-retval+1));
1209+
11981210
pfree(values);
11991211
pfree(needquotes);
12001212

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp