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

Commit35a3def

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 parent268da29 commit35a3def

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
@@ -32,6 +32,15 @@ Datumxpath_table(PG_FUNCTION_ARGS);
3232
voidelog_error(constchar*explain,boolforce);
3333
voidpgxml_parser_init(void);
3434

35+
/* workspace for pgxml_xpath() */
36+
37+
typedefstruct
38+
{
39+
xmlDocPtrdoctree;
40+
xmlXPathContextPtrctxt;
41+
xmlXPathObjectPtrres;
42+
}xpath_workspace;
43+
3544
/* local declarations */
3645

3746
staticvoidpgxml_errorHandler(void*ctxt,constchar*msg,...);
@@ -45,7 +54,10 @@ static text *pgxml_result_to_text(xmlXPathObjectPtr res, xmlChar *toptag,
4554

4655
staticxmlChar*pgxml_texttoxmlchar(text*textstring);
4756

48-
staticxmlXPathObjectPtrpgxml_xpath(text*document,xmlChar*xpath);
57+
staticxmlXPathObjectPtrpgxml_xpath(text*document,xmlChar*xpath,
58+
xpath_workspace*workspace);
59+
60+
staticvoidcleanup_workspace(xpath_workspace*workspace);
4961

5062
/* Global variables */
5163
staticchar*pgxml_errorMsg=NULL;/* overall error message */
@@ -289,25 +301,22 @@ PG_FUNCTION_INFO_V1(xpath_nodeset);
289301
Datum
290302
xpath_nodeset(PG_FUNCTION_ARGS)
291303
{
292-
xmlChar*xpath,
293-
*toptag,
294-
*septag;
295-
int32pathsize;
296-
text*xpathsupp,
297-
*xpres;
298-
299-
/* PG_GETARG_TEXT_P(0) is document buffer */
300-
xpathsupp=PG_GETARG_TEXT_P(1);/* XPath expression */
304+
text*document=PG_GETARG_TEXT_P(0);
305+
text*xpathsupp=PG_GETARG_TEXT_P(1);/* XPath expression */
306+
xmlChar*toptag=pgxml_texttoxmlchar(PG_GETARG_TEXT_P(2));
307+
xmlChar*septag=pgxml_texttoxmlchar(PG_GETARG_TEXT_P(3));
308+
xmlChar*xpath;
309+
text*xpres;
310+
xmlXPathObjectPtrres;
311+
xpath_workspaceworkspace;
301312

302-
toptag=pgxml_texttoxmlchar(PG_GETARG_TEXT_P(2));
303-
septag=pgxml_texttoxmlchar(PG_GETARG_TEXT_P(3));
313+
xpath=pgxml_texttoxmlchar(xpathsupp);
304314

305-
pathsize=VARSIZE(xpathsupp)-VARHDRSZ;
315+
res=pgxml_xpath(document,xpath,&workspace);
306316

307-
xpath=pgxml_texttoxmlchar(xpathsupp);
317+
xpres=pgxml_result_to_text(res,toptag,septag,NULL);
308318

309-
xpres=pgxml_result_to_text(pgxml_xpath(PG_GETARG_TEXT_P(0),xpath),
310-
toptag,septag,NULL);
319+
cleanup_workspace(&workspace);
311320

312321
pfree(xpath);
313322

@@ -325,23 +334,21 @@ PG_FUNCTION_INFO_V1(xpath_list);
325334
Datum
326335
xpath_list(PG_FUNCTION_ARGS)
327336
{
328-
xmlChar*xpath,
329-
*plainsep;
330-
int32pathsize;
331-
text*xpathsupp,
332-
*xpres;
333-
334-
/* PG_GETARG_TEXT_P(0) is document buffer */
335-
xpathsupp=PG_GETARG_TEXT_P(1);/* XPath expression */
337+
text*document=PG_GETARG_TEXT_P(0);
338+
text*xpathsupp=PG_GETARG_TEXT_P(1);/* XPath expression */
339+
xmlChar*plainsep=pgxml_texttoxmlchar(PG_GETARG_TEXT_P(2));
340+
xmlChar*xpath;
341+
text*xpres;
342+
xmlXPathObjectPtrres;
343+
xpath_workspaceworkspace;
336344

337-
plainsep=pgxml_texttoxmlchar(PG_GETARG_TEXT_P(2));
345+
xpath=pgxml_texttoxmlchar(xpathsupp);
338346

339-
pathsize=VARSIZE(xpathsupp)-VARHDRSZ;
347+
res=pgxml_xpath(document,xpath,&workspace);
340348

341-
xpath=pgxml_texttoxmlchar(xpathsupp);
349+
xpres=pgxml_result_to_text(res,NULL,NULL,plainsep);
342350

343-
xpres=pgxml_result_to_text(pgxml_xpath(PG_GETARG_TEXT_P(0),xpath),
344-
NULL,NULL,plainsep);
351+
cleanup_workspace(&workspace);
345352

346353
pfree(xpath);
347354

@@ -356,13 +363,13 @@ PG_FUNCTION_INFO_V1(xpath_string);
356363
Datum
357364
xpath_string(PG_FUNCTION_ARGS)
358365
{
366+
text*document=PG_GETARG_TEXT_P(0);
367+
text*xpathsupp=PG_GETARG_TEXT_P(1);/* XPath expression */
359368
xmlChar*xpath;
360369
int32pathsize;
361-
text*xpathsupp,
362-
*xpres;
363-
364-
/* PG_GETARG_TEXT_P(0) is document buffer */
365-
xpathsupp=PG_GETARG_TEXT_P(1);/* XPath expression */
370+
text*xpres;
371+
xmlXPathObjectPtrres;
372+
xpath_workspaceworkspace;
366373

367374
pathsize=VARSIZE(xpathsupp)-VARHDRSZ;
368375

@@ -373,13 +380,16 @@ xpath_string(PG_FUNCTION_ARGS)
373380
/* We could try casting to string using the libxml function? */
374381

375382
xpath= (xmlChar*)palloc(pathsize+9);
376-
memcpy((char*) (xpath+7),VARDATA(xpathsupp),pathsize);
377383
strncpy((char*)xpath,"string(",7);
384+
memcpy((char*) (xpath+7),VARDATA(xpathsupp),pathsize);
378385
xpath[pathsize+7]=')';
379386
xpath[pathsize+8]='\0';
380387

381-
xpres=pgxml_result_to_text(pgxml_xpath(PG_GETARG_TEXT_P(0),xpath),
382-
NULL,NULL,NULL);
388+
res=pgxml_xpath(document,xpath,&workspace);
389+
390+
xpres=pgxml_result_to_text(res,NULL,NULL,NULL);
391+
392+
cleanup_workspace(&workspace);
383393

384394
pfree(xpath);
385395

@@ -394,28 +404,26 @@ PG_FUNCTION_INFO_V1(xpath_number);
394404
Datum
395405
xpath_number(PG_FUNCTION_ARGS)
396406
{
407+
text*document=PG_GETARG_TEXT_P(0);
408+
text*xpathsupp=PG_GETARG_TEXT_P(1);/* XPath expression */
397409
xmlChar*xpath;
398-
int32pathsize;
399-
text*xpathsupp;
400410
float4fRes;
401-
402411
xmlXPathObjectPtrres;
403-
404-
/* PG_GETARG_TEXT_P(0) is document buffer */
405-
xpathsupp=PG_GETARG_TEXT_P(1);/* XPath expression */
406-
407-
pathsize=VARSIZE(xpathsupp)-VARHDRSZ;
412+
xpath_workspaceworkspace;
408413

409414
xpath=pgxml_texttoxmlchar(xpathsupp);
410415

411-
res=pgxml_xpath(PG_GETARG_TEXT_P(0),xpath);
416+
res=pgxml_xpath(document,xpath,&workspace);
417+
412418
pfree(xpath);
413419

414420
if (res==NULL)
415421
PG_RETURN_NULL();
416422

417423
fRes=xmlXPathCastToNumber(res);
418424

425+
cleanup_workspace(&workspace);
426+
419427
if (xmlXPathIsNaN(fRes))
420428
PG_RETURN_NULL();
421429

@@ -428,28 +436,26 @@ PG_FUNCTION_INFO_V1(xpath_bool);
428436
Datum
429437
xpath_bool(PG_FUNCTION_ARGS)
430438
{
439+
text*document=PG_GETARG_TEXT_P(0);
440+
text*xpathsupp=PG_GETARG_TEXT_P(1);/* XPath expression */
431441
xmlChar*xpath;
432-
int32pathsize;
433-
text*xpathsupp;
434442
intbRes;
435-
436443
xmlXPathObjectPtrres;
437-
438-
/* PG_GETARG_TEXT_P(0) is document buffer */
439-
xpathsupp=PG_GETARG_TEXT_P(1);/* XPath expression */
440-
441-
pathsize=VARSIZE(xpathsupp)-VARHDRSZ;
444+
xpath_workspaceworkspace;
442445

443446
xpath=pgxml_texttoxmlchar(xpathsupp);
444447

445-
res=pgxml_xpath(PG_GETARG_TEXT_P(0),xpath);
448+
res=pgxml_xpath(document,xpath,&workspace);
449+
446450
pfree(xpath);
447451

448452
if (res==NULL)
449453
PG_RETURN_BOOL(false);
450454

451455
bRes=xmlXPathCastToBoolean(res);
452456

457+
cleanup_workspace(&workspace);
458+
453459
PG_RETURN_BOOL(bRes);
454460
}
455461

@@ -458,48 +464,60 @@ xpath_bool(PG_FUNCTION_ARGS)
458464
/* Core function to evaluate XPath query */
459465

460466
staticxmlXPathObjectPtr
461-
pgxml_xpath(text*document,xmlChar*xpath)
467+
pgxml_xpath(text*document,xmlChar*xpath,xpath_workspace*workspace)
462468
{
463-
xmlDocPtrdoctree;
464-
xmlXPathContextPtrctxt;
469+
int32docsize=VARSIZE(document)-VARHDRSZ;
465470
xmlXPathObjectPtrres;
466471
xmlXPathCompExprPtrcomppath;
467-
int32docsize;
468472

469-
docsize=VARSIZE(document)-VARHDRSZ;
473+
workspace->doctree=NULL;
474+
workspace->ctxt=NULL;
475+
workspace->res=NULL;
470476

471477
pgxml_parser_init();
472478

473-
doctree=xmlParseMemory((char*)VARDATA(document),docsize);
474-
if (doctree==NULL)
479+
workspace->doctree=xmlParseMemory((char*)VARDATA(document),docsize);
480+
if (workspace->doctree==NULL)
475481
returnNULL;/* not well-formed */
476482

477-
ctxt=xmlXPathNewContext(doctree);
478-
ctxt->node=xmlDocGetRootElement(doctree);
483+
workspace->ctxt=xmlXPathNewContext(workspace->doctree);
484+
workspace->ctxt->node=xmlDocGetRootElement(workspace->doctree);
479485

480486
/* compile the path */
481487
comppath=xmlXPathCompile(xpath);
482488
if (comppath==NULL)
483489
{
484-
xmlFreeDoc(doctree);
490+
cleanup_workspace(workspace);
485491
elog_error("XPath Syntax Error", true);
486492
}
487493

488494
/* Now evaluate the path expression. */
489-
res=xmlXPathCompiledEval(comppath,ctxt);
495+
res=xmlXPathCompiledEval(comppath,workspace->ctxt);
496+
workspace->res=res;
497+
490498
xmlXPathFreeCompExpr(comppath);
491499

492500
if (res==NULL)
493-
{
494-
xmlXPathFreeContext(ctxt);
495-
xmlFreeDoc(doctree);
501+
cleanup_workspace(workspace);
496502

497-
returnNULL;
498-
}
499-
/* xmlFreeDoc(doctree); */
500503
returnres;
501504
}
502505

506+
/* Clean up after processing the result of pgxml_xpath() */
507+
staticvoid
508+
cleanup_workspace(xpath_workspace*workspace)
509+
{
510+
if (workspace->res)
511+
xmlXPathFreeObject(workspace->res);
512+
workspace->res=NULL;
513+
if (workspace->ctxt)
514+
xmlXPathFreeContext(workspace->ctxt);
515+
workspace->ctxt=NULL;
516+
if (workspace->doctree)
517+
xmlFreeDoc(workspace->doctree);
518+
workspace->doctree=NULL;
519+
}
520+
503521
statictext*
504522
pgxml_result_to_text(xmlXPathObjectPtrres,
505523
xmlChar*toptag,

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp