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

Commit3d8c2b4

Browse files
committed
Fix broken allocation logic in recently-rewritten jsonb_util.c.
reserveFromBuffer() failed to consider the possibility that it needs tomore-than-double the current buffer size. Beyond that, it seems likelythat we'd someday need to worry about integer overflow of the bufferlength variable. Rather than reinvent the logic that's already beendebugged in stringinfo.c, let's go back to using that logic. We canstill have the same targeted API, but we'll rely on stringinfo.c tomanage reallocation.Per report from Alexander Korotkov.
1 parent0b92a77 commit3d8c2b4

File tree

1 file changed

+35
-43
lines changed

1 file changed

+35
-43
lines changed

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

Lines changed: 35 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -32,30 +32,20 @@
3232
#defineJSONB_MAX_ELEMS (Min(MaxAllocSize / sizeof(JsonbValue), JB_CMASK))
3333
#defineJSONB_MAX_PAIRS (Min(MaxAllocSize / sizeof(JsonbPair), JB_CMASK))
3434

35-
/*
36-
* convertState: a resizeable buffer used when constructing a Jsonb datum
37-
*/
38-
typedefstruct
39-
{
40-
char*buffer;
41-
intlen;
42-
intallocatedsz;
43-
}convertState;
44-
4535
staticvoidfillJsonbValue(JEntry*array,intindex,char*base_addr,
4636
JsonbValue*result);
4737
staticintcompareJsonbScalarValue(JsonbValue*a,JsonbValue*b);
4838
staticintlexicalCompareJsonbStringValue(constvoid*a,constvoid*b);
4939
staticJsonb*convertToJsonb(JsonbValue*val);
50-
staticvoidconvertJsonbValue(convertState*buffer,JEntry*header,JsonbValue*val,intlevel);
51-
staticvoidconvertJsonbArray(convertState*buffer,JEntry*header,JsonbValue*val,intlevel);
52-
staticvoidconvertJsonbObject(convertState*buffer,JEntry*header,JsonbValue*val,intlevel);
53-
staticvoidconvertJsonbScalar(convertState*buffer,JEntry*header,JsonbValue*scalarVal);
40+
staticvoidconvertJsonbValue(StringInfobuffer,JEntry*header,JsonbValue*val,intlevel);
41+
staticvoidconvertJsonbArray(StringInfobuffer,JEntry*header,JsonbValue*val,intlevel);
42+
staticvoidconvertJsonbObject(StringInfobuffer,JEntry*header,JsonbValue*val,intlevel);
43+
staticvoidconvertJsonbScalar(StringInfobuffer,JEntry*header,JsonbValue*scalarVal);
5444

55-
staticintreserveFromBuffer(convertState*buffer,intlen);
56-
staticvoidappendToBuffer(convertState*buffer,char*data,intlen);
57-
staticvoidcopyToBuffer(convertState*buffer,intoffset,char*data,intlen);
58-
staticshortpadBufferToInt(convertState*buffer);
45+
staticintreserveFromBuffer(StringInfobuffer,intlen);
46+
staticvoidappendToBuffer(StringInfobuffer,constchar*data,intlen);
47+
staticvoidcopyToBuffer(StringInfobuffer,intoffset,constchar*data,intlen);
48+
staticshortpadBufferToInt(StringInfobuffer);
5949

6050
staticJsonbIterator*iteratorFromContainer(JsonbContainer*container,JsonbIterator*parent);
6151
staticJsonbIterator*freeAndGetParent(JsonbIterator*it);
@@ -1175,44 +1165,46 @@ lexicalCompareJsonbStringValue(const void *a, const void *b)
11751165

11761166
/*
11771167
* Reserve 'len' bytes, at the end of the buffer, enlarging it if necessary.
1178-
* Returns the offset to the reserved area. The caller is expected tocopy
1179-
* thedata to thereserved area later with copyToBuffer()
1168+
* Returns the offset to the reserved area. The caller is expected tofill
1169+
* the reserved area later with copyToBuffer().
11801170
*/
11811171
staticint
1182-
reserveFromBuffer(convertState*buffer,intlen)
1172+
reserveFromBuffer(StringInfobuffer,intlen)
11831173
{
11841174
intoffset;
11851175

11861176
/* Make more room if needed */
1187-
if (buffer->len+len>buffer->allocatedsz)
1188-
{
1189-
buffer->allocatedsz *=2;
1190-
buffer->buffer=repalloc(buffer->buffer,buffer->allocatedsz);
1191-
}
1177+
enlargeStringInfo(buffer,len);
11921178

11931179
/* remember current offset */
11941180
offset=buffer->len;
11951181

11961182
/* reserve the space */
11971183
buffer->len+=len;
11981184

1185+
/*
1186+
* Keep a trailing null in place, even though it's not useful for us;
1187+
* it seems best to preserve the invariants of StringInfos.
1188+
*/
1189+
buffer->data[buffer->len]='\0';
1190+
11991191
returnoffset;
12001192
}
12011193

12021194
/*
12031195
* Copy 'len' bytes to a previously reserved area in buffer.
12041196
*/
12051197
staticvoid
1206-
copyToBuffer(convertState*buffer,intoffset,char*data,intlen)
1198+
copyToBuffer(StringInfobuffer,intoffset,constchar*data,intlen)
12071199
{
1208-
memcpy(buffer->buffer+offset,data,len);
1200+
memcpy(buffer->data+offset,data,len);
12091201
}
12101202

12111203
/*
12121204
* A shorthand for reserveFromBuffer + copyToBuffer.
12131205
*/
12141206
staticvoid
1215-
appendToBuffer(convertState*buffer,char*data,intlen)
1207+
appendToBuffer(StringInfobuffer,constchar*data,intlen)
12161208
{
12171209
intoffset;
12181210

@@ -1226,17 +1218,19 @@ appendToBuffer(convertState *buffer, char *data, int len)
12261218
* Returns the number of padding bytes appended.
12271219
*/
12281220
staticshort
1229-
padBufferToInt(convertState*buffer)
1221+
padBufferToInt(StringInfobuffer)
12301222
{
1231-
shortpadlen,
1232-
p;
1233-
intoffset;
1223+
intpadlen,
1224+
p,
1225+
offset;
12341226

12351227
padlen=INTALIGN(buffer->len)-buffer->len;
12361228

12371229
offset=reserveFromBuffer(buffer,padlen);
1230+
1231+
/* padlen must be small, so this is probably faster than a memset */
12381232
for (p=0;p<padlen;p++)
1239-
buffer->buffer[offset+p]=0;
1233+
buffer->data[offset+p]='\0';
12401234

12411235
returnpadlen;
12421236
}
@@ -1247,17 +1241,15 @@ padBufferToInt(convertState *buffer)
12471241
staticJsonb*
12481242
convertToJsonb(JsonbValue*val)
12491243
{
1250-
convertStatebuffer;
1244+
StringInfoDatabuffer;
12511245
JEntryjentry;
12521246
Jsonb*res;
12531247

12541248
/* Should not already have binary representation */
12551249
Assert(val->type!=jbvBinary);
12561250

12571251
/* Allocate an output buffer. It will be enlarged as needed */
1258-
buffer.buffer=palloc(128);
1259-
buffer.len=0;
1260-
buffer.allocatedsz=128;
1252+
initStringInfo(&buffer);
12611253

12621254
/* Make room for the varlena header */
12631255
reserveFromBuffer(&buffer,sizeof(VARHDRSZ));
@@ -1270,7 +1262,7 @@ convertToJsonb(JsonbValue *val)
12701262
* kind of value it is.
12711263
*/
12721264

1273-
res= (Jsonb*)buffer.buffer;
1265+
res= (Jsonb*)buffer.data;
12741266

12751267
SET_VARSIZE(res,buffer.len);
12761268

@@ -1289,7 +1281,7 @@ convertToJsonb(JsonbValue *val)
12891281
* for debugging purposes.
12901282
*/
12911283
staticvoid
1292-
convertJsonbValue(convertState*buffer,JEntry*header,JsonbValue*val,intlevel)
1284+
convertJsonbValue(StringInfobuffer,JEntry*header,JsonbValue*val,intlevel)
12931285
{
12941286
check_stack_depth();
12951287

@@ -1307,7 +1299,7 @@ convertJsonbValue(convertState *buffer, JEntry *header, JsonbValue *val, int lev
13071299
}
13081300

13091301
staticvoid
1310-
convertJsonbArray(convertState*buffer,JEntry*pheader,JsonbValue*val,intlevel)
1302+
convertJsonbArray(StringInfobuffer,JEntry*pheader,JsonbValue*val,intlevel)
13111303
{
13121304
intoffset;
13131305
intmetaoffset;
@@ -1366,7 +1358,7 @@ convertJsonbArray(convertState *buffer, JEntry *pheader, JsonbValue *val, int le
13661358
}
13671359

13681360
staticvoid
1369-
convertJsonbObject(convertState*buffer,JEntry*pheader,JsonbValue*val,intlevel)
1361+
convertJsonbObject(StringInfobuffer,JEntry*pheader,JsonbValue*val,intlevel)
13701362
{
13711363
uint32header;
13721364
intoffset;
@@ -1431,7 +1423,7 @@ convertJsonbObject(convertState *buffer, JEntry *pheader, JsonbValue *val, int l
14311423
}
14321424

14331425
staticvoid
1434-
convertJsonbScalar(convertState*buffer,JEntry*jentry,JsonbValue*scalarVal)
1426+
convertJsonbScalar(StringInfobuffer,JEntry*jentry,JsonbValue*scalarVal)
14351427
{
14361428
intnumlen;
14371429
shortpadlen;

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp