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

Commit4a2516a

Browse files
committed
Fix significant memory leak in contrib/xml2 functions.
Most of the functions that execute XPath queries leaked the data structurescreated by libxml2. This memory would not be recovered until end ofsession, so it mounts up pretty quickly in any serious use of the feature.Per report from Pavel Stehule, though this isn't his patch.Back-patch to all supported branches.
1 parente6e38b4 commit4a2516a

File tree

1 file changed

+90
-72
lines changed

1 file changed

+90
-72
lines changed

‎contrib/xml2/xpath.c

Lines changed: 90 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,15 @@ Datumxpath_table(PG_FUNCTION_ARGS);
4040

4141
voidpgxml_parser_init(void);
4242

43+
/* workspace for pgxml_xpath() */
44+
45+
typedefstruct
46+
{
47+
xmlDocPtrdoctree;
48+
xmlXPathContextPtrctxt;
49+
xmlXPathObjectPtrres;
50+
}xpath_workspace;
51+
4352
/* local declarations */
4453

4554
staticxmlChar*pgxmlNodeSetToText(xmlNodeSetPtrnodeset,
@@ -51,7 +60,10 @@ static text *pgxml_result_to_text(xmlXPathObjectPtr res, xmlChar *toptag,
5160

5261
staticxmlChar*pgxml_texttoxmlchar(text*textstring);
5362

54-
staticxmlXPathObjectPtrpgxml_xpath(text*document,xmlChar*xpath);
63+
staticxmlXPathObjectPtrpgxml_xpath(text*document,xmlChar*xpath,
64+
xpath_workspace*workspace);
65+
66+
staticvoidcleanup_workspace(xpath_workspace*workspace);
5567

5668

5769
/*
@@ -221,25 +233,22 @@ PG_FUNCTION_INFO_V1(xpath_nodeset);
221233
Datum
222234
xpath_nodeset(PG_FUNCTION_ARGS)
223235
{
224-
xmlChar*xpath,
225-
*toptag,
226-
*septag;
227-
int32pathsize;
228-
text*xpathsupp,
229-
*xpres;
230-
231-
/* PG_GETARG_TEXT_P(0) is document buffer */
232-
xpathsupp=PG_GETARG_TEXT_P(1);/* XPath expression */
236+
text*document=PG_GETARG_TEXT_P(0);
237+
text*xpathsupp=PG_GETARG_TEXT_P(1);/* XPath expression */
238+
xmlChar*toptag=pgxml_texttoxmlchar(PG_GETARG_TEXT_P(2));
239+
xmlChar*septag=pgxml_texttoxmlchar(PG_GETARG_TEXT_P(3));
240+
xmlChar*xpath;
241+
text*xpres;
242+
xmlXPathObjectPtrres;
243+
xpath_workspaceworkspace;
233244

234-
toptag=pgxml_texttoxmlchar(PG_GETARG_TEXT_P(2));
235-
septag=pgxml_texttoxmlchar(PG_GETARG_TEXT_P(3));
245+
xpath=pgxml_texttoxmlchar(xpathsupp);
236246

237-
pathsize=VARSIZE(xpathsupp)-VARHDRSZ;
247+
res=pgxml_xpath(document,xpath,&workspace);
238248

239-
xpath=pgxml_texttoxmlchar(xpathsupp);
249+
xpres=pgxml_result_to_text(res,toptag,septag,NULL);
240250

241-
xpres=pgxml_result_to_text(pgxml_xpath(PG_GETARG_TEXT_P(0),xpath),
242-
toptag,septag,NULL);
251+
cleanup_workspace(&workspace);
243252

244253
pfree(xpath);
245254

@@ -257,23 +266,21 @@ PG_FUNCTION_INFO_V1(xpath_list);
257266
Datum
258267
xpath_list(PG_FUNCTION_ARGS)
259268
{
260-
xmlChar*xpath,
261-
*plainsep;
262-
int32pathsize;
263-
text*xpathsupp,
264-
*xpres;
265-
266-
/* PG_GETARG_TEXT_P(0) is document buffer */
267-
xpathsupp=PG_GETARG_TEXT_P(1);/* XPath expression */
269+
text*document=PG_GETARG_TEXT_P(0);
270+
text*xpathsupp=PG_GETARG_TEXT_P(1);/* XPath expression */
271+
xmlChar*plainsep=pgxml_texttoxmlchar(PG_GETARG_TEXT_P(2));
272+
xmlChar*xpath;
273+
text*xpres;
274+
xmlXPathObjectPtrres;
275+
xpath_workspaceworkspace;
268276

269-
plainsep=pgxml_texttoxmlchar(PG_GETARG_TEXT_P(2));
277+
xpath=pgxml_texttoxmlchar(xpathsupp);
270278

271-
pathsize=VARSIZE(xpathsupp)-VARHDRSZ;
279+
res=pgxml_xpath(document,xpath,&workspace);
272280

273-
xpath=pgxml_texttoxmlchar(xpathsupp);
281+
xpres=pgxml_result_to_text(res,NULL,NULL,plainsep);
274282

275-
xpres=pgxml_result_to_text(pgxml_xpath(PG_GETARG_TEXT_P(0),xpath),
276-
NULL,NULL,plainsep);
283+
cleanup_workspace(&workspace);
277284

278285
pfree(xpath);
279286

@@ -288,13 +295,13 @@ PG_FUNCTION_INFO_V1(xpath_string);
288295
Datum
289296
xpath_string(PG_FUNCTION_ARGS)
290297
{
298+
text*document=PG_GETARG_TEXT_P(0);
299+
text*xpathsupp=PG_GETARG_TEXT_P(1);/* XPath expression */
291300
xmlChar*xpath;
292301
int32pathsize;
293-
text*xpathsupp,
294-
*xpres;
295-
296-
/* PG_GETARG_TEXT_P(0) is document buffer */
297-
xpathsupp=PG_GETARG_TEXT_P(1);/* XPath expression */
302+
text*xpres;
303+
xmlXPathObjectPtrres;
304+
xpath_workspaceworkspace;
298305

299306
pathsize=VARSIZE(xpathsupp)-VARHDRSZ;
300307

@@ -305,13 +312,16 @@ xpath_string(PG_FUNCTION_ARGS)
305312
/* We could try casting to string using the libxml function? */
306313

307314
xpath= (xmlChar*)palloc(pathsize+9);
308-
memcpy((char*) (xpath+7),VARDATA(xpathsupp),pathsize);
309315
strncpy((char*)xpath,"string(",7);
316+
memcpy((char*) (xpath+7),VARDATA(xpathsupp),pathsize);
310317
xpath[pathsize+7]=')';
311318
xpath[pathsize+8]='\0';
312319

313-
xpres=pgxml_result_to_text(pgxml_xpath(PG_GETARG_TEXT_P(0),xpath),
314-
NULL,NULL,NULL);
320+
res=pgxml_xpath(document,xpath,&workspace);
321+
322+
xpres=pgxml_result_to_text(res,NULL,NULL,NULL);
323+
324+
cleanup_workspace(&workspace);
315325

316326
pfree(xpath);
317327

@@ -326,28 +336,26 @@ PG_FUNCTION_INFO_V1(xpath_number);
326336
Datum
327337
xpath_number(PG_FUNCTION_ARGS)
328338
{
339+
text*document=PG_GETARG_TEXT_P(0);
340+
text*xpathsupp=PG_GETARG_TEXT_P(1);/* XPath expression */
329341
xmlChar*xpath;
330-
int32pathsize;
331-
text*xpathsupp;
332342
float4fRes;
333-
334343
xmlXPathObjectPtrres;
335-
336-
/* PG_GETARG_TEXT_P(0) is document buffer */
337-
xpathsupp=PG_GETARG_TEXT_P(1);/* XPath expression */
338-
339-
pathsize=VARSIZE(xpathsupp)-VARHDRSZ;
344+
xpath_workspaceworkspace;
340345

341346
xpath=pgxml_texttoxmlchar(xpathsupp);
342347

343-
res=pgxml_xpath(PG_GETARG_TEXT_P(0),xpath);
348+
res=pgxml_xpath(document,xpath,&workspace);
349+
344350
pfree(xpath);
345351

346352
if (res==NULL)
347353
PG_RETURN_NULL();
348354

349355
fRes=xmlXPathCastToNumber(res);
350356

357+
cleanup_workspace(&workspace);
358+
351359
if (xmlXPathIsNaN(fRes))
352360
PG_RETURN_NULL();
353361

@@ -360,28 +368,26 @@ PG_FUNCTION_INFO_V1(xpath_bool);
360368
Datum
361369
xpath_bool(PG_FUNCTION_ARGS)
362370
{
371+
text*document=PG_GETARG_TEXT_P(0);
372+
text*xpathsupp=PG_GETARG_TEXT_P(1);/* XPath expression */
363373
xmlChar*xpath;
364-
int32pathsize;
365-
text*xpathsupp;
366374
intbRes;
367-
368375
xmlXPathObjectPtrres;
369-
370-
/* PG_GETARG_TEXT_P(0) is document buffer */
371-
xpathsupp=PG_GETARG_TEXT_P(1);/* XPath expression */
372-
373-
pathsize=VARSIZE(xpathsupp)-VARHDRSZ;
376+
xpath_workspaceworkspace;
374377

375378
xpath=pgxml_texttoxmlchar(xpathsupp);
376379

377-
res=pgxml_xpath(PG_GETARG_TEXT_P(0),xpath);
380+
res=pgxml_xpath(document,xpath,&workspace);
381+
378382
pfree(xpath);
379383

380384
if (res==NULL)
381385
PG_RETURN_BOOL(false);
382386

383387
bRes=xmlXPathCastToBoolean(res);
384388

389+
cleanup_workspace(&workspace);
390+
385391
PG_RETURN_BOOL(bRes);
386392
}
387393

@@ -390,49 +396,61 @@ xpath_bool(PG_FUNCTION_ARGS)
390396
/* Core function to evaluate XPath query */
391397

392398
staticxmlXPathObjectPtr
393-
pgxml_xpath(text*document,xmlChar*xpath)
399+
pgxml_xpath(text*document,xmlChar*xpath,xpath_workspace*workspace)
394400
{
395-
xmlDocPtrdoctree;
396-
xmlXPathContextPtrctxt;
401+
int32docsize=VARSIZE(document)-VARHDRSZ;
397402
xmlXPathObjectPtrres;
398403
xmlXPathCompExprPtrcomppath;
399-
int32docsize;
400404

401-
docsize=VARSIZE(document)-VARHDRSZ;
405+
workspace->doctree=NULL;
406+
workspace->ctxt=NULL;
407+
workspace->res=NULL;
402408

403409
pgxml_parser_init();
404410

405-
doctree=xmlParseMemory((char*)VARDATA(document),docsize);
406-
if (doctree==NULL)
411+
workspace->doctree=xmlParseMemory((char*)VARDATA(document),docsize);
412+
if (workspace->doctree==NULL)
407413
returnNULL;/* not well-formed */
408414

409-
ctxt=xmlXPathNewContext(doctree);
410-
ctxt->node=xmlDocGetRootElement(doctree);
415+
workspace->ctxt=xmlXPathNewContext(workspace->doctree);
416+
workspace->ctxt->node=xmlDocGetRootElement(workspace->doctree);
411417

412418
/* compile the path */
413419
comppath=xmlXPathCompile(xpath);
414420
if (comppath==NULL)
415421
{
416-
xmlFreeDoc(doctree);
422+
cleanup_workspace(workspace);
417423
xml_ereport(ERROR,ERRCODE_EXTERNAL_ROUTINE_EXCEPTION,
418424
"XPath Syntax Error");
419425
}
420426

421427
/* Now evaluate the path expression. */
422-
res=xmlXPathCompiledEval(comppath,ctxt);
428+
res=xmlXPathCompiledEval(comppath,workspace->ctxt);
429+
workspace->res=res;
430+
423431
xmlXPathFreeCompExpr(comppath);
424432

425433
if (res==NULL)
426-
{
427-
xmlXPathFreeContext(ctxt);
428-
xmlFreeDoc(doctree);
434+
cleanup_workspace(workspace);
429435

430-
returnNULL;
431-
}
432-
/* xmlFreeDoc(doctree); */
433436
returnres;
434437
}
435438

439+
/* Clean up after processing the result of pgxml_xpath() */
440+
staticvoid
441+
cleanup_workspace(xpath_workspace*workspace)
442+
{
443+
if (workspace->res)
444+
xmlXPathFreeObject(workspace->res);
445+
workspace->res=NULL;
446+
if (workspace->ctxt)
447+
xmlXPathFreeContext(workspace->ctxt);
448+
workspace->ctxt=NULL;
449+
if (workspace->doctree)
450+
xmlFreeDoc(workspace->doctree);
451+
workspace->doctree=NULL;
452+
}
453+
436454
statictext*
437455
pgxml_result_to_text(xmlXPathObjectPtrres,
438456
xmlChar*toptag,

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp