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

Commite6fa73e

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 parent317a568 commite6fa73e

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
/*
@@ -214,25 +226,22 @@ PG_FUNCTION_INFO_V1(xpath_nodeset);
214226
Datum
215227
xpath_nodeset(PG_FUNCTION_ARGS)
216228
{
217-
xmlChar*xpath,
218-
*toptag,
219-
*septag;
220-
int32pathsize;
221-
text*xpathsupp,
222-
*xpres;
223-
224-
/* PG_GETARG_TEXT_P(0) is document buffer */
225-
xpathsupp=PG_GETARG_TEXT_P(1);/* XPath expression */
229+
text*document=PG_GETARG_TEXT_P(0);
230+
text*xpathsupp=PG_GETARG_TEXT_P(1);/* XPath expression */
231+
xmlChar*toptag=pgxml_texttoxmlchar(PG_GETARG_TEXT_P(2));
232+
xmlChar*septag=pgxml_texttoxmlchar(PG_GETARG_TEXT_P(3));
233+
xmlChar*xpath;
234+
text*xpres;
235+
xmlXPathObjectPtrres;
236+
xpath_workspaceworkspace;
226237

227-
toptag=pgxml_texttoxmlchar(PG_GETARG_TEXT_P(2));
228-
septag=pgxml_texttoxmlchar(PG_GETARG_TEXT_P(3));
238+
xpath=pgxml_texttoxmlchar(xpathsupp);
229239

230-
pathsize=VARSIZE(xpathsupp)-VARHDRSZ;
240+
res=pgxml_xpath(document,xpath,&workspace);
231241

232-
xpath=pgxml_texttoxmlchar(xpathsupp);
242+
xpres=pgxml_result_to_text(res,toptag,septag,NULL);
233243

234-
xpres=pgxml_result_to_text(pgxml_xpath(PG_GETARG_TEXT_P(0),xpath),
235-
toptag,septag,NULL);
244+
cleanup_workspace(&workspace);
236245

237246
pfree(xpath);
238247

@@ -250,23 +259,21 @@ PG_FUNCTION_INFO_V1(xpath_list);
250259
Datum
251260
xpath_list(PG_FUNCTION_ARGS)
252261
{
253-
xmlChar*xpath,
254-
*plainsep;
255-
int32pathsize;
256-
text*xpathsupp,
257-
*xpres;
258-
259-
/* PG_GETARG_TEXT_P(0) is document buffer */
260-
xpathsupp=PG_GETARG_TEXT_P(1);/* XPath expression */
262+
text*document=PG_GETARG_TEXT_P(0);
263+
text*xpathsupp=PG_GETARG_TEXT_P(1);/* XPath expression */
264+
xmlChar*plainsep=pgxml_texttoxmlchar(PG_GETARG_TEXT_P(2));
265+
xmlChar*xpath;
266+
text*xpres;
267+
xmlXPathObjectPtrres;
268+
xpath_workspaceworkspace;
261269

262-
plainsep=pgxml_texttoxmlchar(PG_GETARG_TEXT_P(2));
270+
xpath=pgxml_texttoxmlchar(xpathsupp);
263271

264-
pathsize=VARSIZE(xpathsupp)-VARHDRSZ;
272+
res=pgxml_xpath(document,xpath,&workspace);
265273

266-
xpath=pgxml_texttoxmlchar(xpathsupp);
274+
xpres=pgxml_result_to_text(res,NULL,NULL,plainsep);
267275

268-
xpres=pgxml_result_to_text(pgxml_xpath(PG_GETARG_TEXT_P(0),xpath),
269-
NULL,NULL,plainsep);
276+
cleanup_workspace(&workspace);
270277

271278
pfree(xpath);
272279

@@ -281,13 +288,13 @@ PG_FUNCTION_INFO_V1(xpath_string);
281288
Datum
282289
xpath_string(PG_FUNCTION_ARGS)
283290
{
291+
text*document=PG_GETARG_TEXT_P(0);
292+
text*xpathsupp=PG_GETARG_TEXT_P(1);/* XPath expression */
284293
xmlChar*xpath;
285294
int32pathsize;
286-
text*xpathsupp,
287-
*xpres;
288-
289-
/* PG_GETARG_TEXT_P(0) is document buffer */
290-
xpathsupp=PG_GETARG_TEXT_P(1);/* XPath expression */
295+
text*xpres;
296+
xmlXPathObjectPtrres;
297+
xpath_workspaceworkspace;
291298

292299
pathsize=VARSIZE(xpathsupp)-VARHDRSZ;
293300

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

300307
xpath= (xmlChar*)palloc(pathsize+9);
301-
memcpy((char*) (xpath+7),VARDATA(xpathsupp),pathsize);
302308
strncpy((char*)xpath,"string(",7);
309+
memcpy((char*) (xpath+7),VARDATA(xpathsupp),pathsize);
303310
xpath[pathsize+7]=')';
304311
xpath[pathsize+8]='\0';
305312

306-
xpres=pgxml_result_to_text(pgxml_xpath(PG_GETARG_TEXT_P(0),xpath),
307-
NULL,NULL,NULL);
313+
res=pgxml_xpath(document,xpath,&workspace);
314+
315+
xpres=pgxml_result_to_text(res,NULL,NULL,NULL);
316+
317+
cleanup_workspace(&workspace);
308318

309319
pfree(xpath);
310320

@@ -319,28 +329,26 @@ PG_FUNCTION_INFO_V1(xpath_number);
319329
Datum
320330
xpath_number(PG_FUNCTION_ARGS)
321331
{
332+
text*document=PG_GETARG_TEXT_P(0);
333+
text*xpathsupp=PG_GETARG_TEXT_P(1);/* XPath expression */
322334
xmlChar*xpath;
323-
int32pathsize;
324-
text*xpathsupp;
325335
float4fRes;
326-
327336
xmlXPathObjectPtrres;
328-
329-
/* PG_GETARG_TEXT_P(0) is document buffer */
330-
xpathsupp=PG_GETARG_TEXT_P(1);/* XPath expression */
331-
332-
pathsize=VARSIZE(xpathsupp)-VARHDRSZ;
337+
xpath_workspaceworkspace;
333338

334339
xpath=pgxml_texttoxmlchar(xpathsupp);
335340

336-
res=pgxml_xpath(PG_GETARG_TEXT_P(0),xpath);
341+
res=pgxml_xpath(document,xpath,&workspace);
342+
337343
pfree(xpath);
338344

339345
if (res==NULL)
340346
PG_RETURN_NULL();
341347

342348
fRes=xmlXPathCastToNumber(res);
343349

350+
cleanup_workspace(&workspace);
351+
344352
if (xmlXPathIsNaN(fRes))
345353
PG_RETURN_NULL();
346354

@@ -353,28 +361,26 @@ PG_FUNCTION_INFO_V1(xpath_bool);
353361
Datum
354362
xpath_bool(PG_FUNCTION_ARGS)
355363
{
364+
text*document=PG_GETARG_TEXT_P(0);
365+
text*xpathsupp=PG_GETARG_TEXT_P(1);/* XPath expression */
356366
xmlChar*xpath;
357-
int32pathsize;
358-
text*xpathsupp;
359367
intbRes;
360-
361368
xmlXPathObjectPtrres;
362-
363-
/* PG_GETARG_TEXT_P(0) is document buffer */
364-
xpathsupp=PG_GETARG_TEXT_P(1);/* XPath expression */
365-
366-
pathsize=VARSIZE(xpathsupp)-VARHDRSZ;
369+
xpath_workspaceworkspace;
367370

368371
xpath=pgxml_texttoxmlchar(xpathsupp);
369372

370-
res=pgxml_xpath(PG_GETARG_TEXT_P(0),xpath);
373+
res=pgxml_xpath(document,xpath,&workspace);
374+
371375
pfree(xpath);
372376

373377
if (res==NULL)
374378
PG_RETURN_BOOL(false);
375379

376380
bRes=xmlXPathCastToBoolean(res);
377381

382+
cleanup_workspace(&workspace);
383+
378384
PG_RETURN_BOOL(bRes);
379385
}
380386

@@ -383,49 +389,61 @@ xpath_bool(PG_FUNCTION_ARGS)
383389
/* Core function to evaluate XPath query */
384390

385391
staticxmlXPathObjectPtr
386-
pgxml_xpath(text*document,xmlChar*xpath)
392+
pgxml_xpath(text*document,xmlChar*xpath,xpath_workspace*workspace)
387393
{
388-
xmlDocPtrdoctree;
389-
xmlXPathContextPtrctxt;
394+
int32docsize=VARSIZE(document)-VARHDRSZ;
390395
xmlXPathObjectPtrres;
391396
xmlXPathCompExprPtrcomppath;
392-
int32docsize;
393397

394-
docsize=VARSIZE(document)-VARHDRSZ;
398+
workspace->doctree=NULL;
399+
workspace->ctxt=NULL;
400+
workspace->res=NULL;
395401

396402
pgxml_parser_init();
397403

398-
doctree=xmlParseMemory((char*)VARDATA(document),docsize);
399-
if (doctree==NULL)
404+
workspace->doctree=xmlParseMemory((char*)VARDATA(document),docsize);
405+
if (workspace->doctree==NULL)
400406
returnNULL;/* not well-formed */
401407

402-
ctxt=xmlXPathNewContext(doctree);
403-
ctxt->node=xmlDocGetRootElement(doctree);
408+
workspace->ctxt=xmlXPathNewContext(workspace->doctree);
409+
workspace->ctxt->node=xmlDocGetRootElement(workspace->doctree);
404410

405411
/* compile the path */
406412
comppath=xmlXPathCompile(xpath);
407413
if (comppath==NULL)
408414
{
409-
xmlFreeDoc(doctree);
415+
cleanup_workspace(workspace);
410416
xml_ereport(ERROR,ERRCODE_EXTERNAL_ROUTINE_EXCEPTION,
411417
"XPath Syntax Error");
412418
}
413419

414420
/* Now evaluate the path expression. */
415-
res=xmlXPathCompiledEval(comppath,ctxt);
421+
res=xmlXPathCompiledEval(comppath,workspace->ctxt);
422+
workspace->res=res;
423+
416424
xmlXPathFreeCompExpr(comppath);
417425

418426
if (res==NULL)
419-
{
420-
xmlXPathFreeContext(ctxt);
421-
xmlFreeDoc(doctree);
427+
cleanup_workspace(workspace);
422428

423-
returnNULL;
424-
}
425-
/* xmlFreeDoc(doctree); */
426429
returnres;
427430
}
428431

432+
/* Clean up after processing the result of pgxml_xpath() */
433+
staticvoid
434+
cleanup_workspace(xpath_workspace*workspace)
435+
{
436+
if (workspace->res)
437+
xmlXPathFreeObject(workspace->res);
438+
workspace->res=NULL;
439+
if (workspace->ctxt)
440+
xmlXPathFreeContext(workspace->ctxt);
441+
workspace->ctxt=NULL;
442+
if (workspace->doctree)
443+
xmlFreeDoc(workspace->doctree);
444+
workspace->doctree=NULL;
445+
}
446+
429447
statictext*
430448
pgxml_result_to_text(xmlXPathObjectPtrres,
431449
xmlChar*toptag,

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp