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

Commit19749fb

Browse files
committed
Replace xmlroot with a properly functioning version that parses the value,
sets the items, and serializes the value back (rather than adding anarbitrary number of XML preambles as before).The libxml memory management via palloc had to be disabled because itcrashes when libxml tries to access memory that was helpfully freedearlier by PostgreSQL. This needs further thought.
1 parent063560b commit19749fb

File tree

4 files changed

+103
-28
lines changed

4 files changed

+103
-28
lines changed

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

Lines changed: 65 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
88
* Portions Copyright (c) 1994, Regents of the University of California
99
*
10-
* $PostgreSQL: pgsql/src/backend/utils/adt/xml.c,v 1.10 2007/01/05 22:19:42 momjian Exp $
10+
* $PostgreSQL: pgsql/src/backend/utils/adt/xml.c,v 1.11 2007/01/0619:18:36 petere Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -31,6 +31,7 @@
3131
#include<libxml/tree.h>
3232
#include<libxml/uri.h>
3333
#include<libxml/xmlerror.h>
34+
#include<libxml/xmlsave.h>
3435
#endif/* USE_LIBXML */
3536

3637
#include"fmgr.h"
@@ -49,10 +50,12 @@
4950
staticStringInfoxml_err_buf=NULL;
5051

5152
staticvoidxml_init(void);
53+
#ifdefNOT_USED
5254
staticvoid*xml_palloc(size_tsize);
5355
staticvoid*xml_repalloc(void*ptr,size_tsize);
5456
staticvoidxml_pfree(void*ptr);
5557
staticchar*xml_pstrdup(constchar*string);
58+
#endif
5659
staticvoidxml_ereport(intlevel,intsqlcode,
5760
constchar*msg,void*ctxt);
5861
staticvoidxml_errorHandler(void*ctxt,constchar*msg, ...);
@@ -76,6 +79,7 @@ xml_in(PG_FUNCTION_ARGS)
7679
char*s=PG_GETARG_CSTRING(0);
7780
size_tlen;
7881
xmltype*vardata;
82+
xmlDocPtrdoc;
7983

8084
len=strlen(s);
8185
vardata=palloc(len+VARHDRSZ);
@@ -86,7 +90,8 @@ xml_in(PG_FUNCTION_ARGS)
8690
* Parse the data to check if it is well-formed XML data. Assume
8791
* that ERROR occurred if parsing failed.
8892
*/
89-
xml_parse(vardata, false, true);
93+
doc=xml_parse(vardata, false, true);
94+
xmlFreeDoc(doc);
9095

9196
PG_RETURN_XML_P(vardata);
9297
#else
@@ -120,6 +125,7 @@ xml_recv(PG_FUNCTION_ARGS)
120125
xmltype*result;
121126
char*str;
122127
intnbytes;
128+
xmlDocPtrdoc;
123129

124130
str=pq_getmsgtext(buf,buf->len-buf->cursor,&nbytes);
125131

@@ -132,7 +138,8 @@ xml_recv(PG_FUNCTION_ARGS)
132138
* Parse the data to check if it is well-formed XML data. Assume
133139
* that ERROR occurred if parsing failed.
134140
*/
135-
xml_parse(result, false, true);
141+
doc=xml_parse(result, false, true);
142+
xmlFreeDoc(doc);
136143

137144
PG_RETURN_XML_P(result);
138145
#else
@@ -175,6 +182,21 @@ stringinfo_to_xmltype(StringInfo buf)
175182

176183
returnresult;
177184
}
185+
186+
187+
staticxmltype*
188+
xmlBuffer_to_xmltype(xmlBufferPtrbuf)
189+
{
190+
int32len;
191+
xmltype*result;
192+
193+
len=xmlBufferLength(buf)+VARHDRSZ;
194+
result=palloc(len);
195+
VARATT_SIZEP(result)=len;
196+
memcpy(VARDATA(result),xmlBufferContent(buf),len-VARHDRSZ);
197+
198+
returnresult;
199+
}
178200
#endif
179201

180202

@@ -221,7 +243,10 @@ xmltype *
221243
xmlparse(text*data,boolis_document,boolpreserve_whitespace)
222244
{
223245
#ifdefUSE_LIBXML
224-
xml_parse(data,is_document,preserve_whitespace);
246+
xmlDocPtrdoc;
247+
248+
doc=xml_parse(data,is_document,preserve_whitespace);
249+
xmlFreeDoc(doc);
225250

226251
return (xmltype*)data;
227252
#else
@@ -280,31 +305,38 @@ xmltype *
280305
xmlroot(xmltype*data,text*version,intstandalone)
281306
{
282307
#ifdefUSE_LIBXML
283-
xmltype*result;
284-
StringInfoDatabuf;
308+
xmlDocPtrdoc;
309+
xmlBufferPtrbuffer;
310+
xmlSaveCtxtPtrsave;
285311

286-
initStringInfo(&buf);
312+
doc=xml_parse((text*)data, true, true);
287313

288-
/*
289-
* FIXME: This is probably supposed to be cleverer if there
290-
* already is an XML preamble.
291-
*/
292-
appendStringInfo(&buf,"<?xml");
293314
if (version)
315+
doc->version=xmlStrdup(xml_text2xmlChar(version));
316+
else
317+
doc->version=NULL;
318+
319+
switch (standalone)
294320
{
295-
appendStringInfo(&buf," version=\"");
296-
appendStringInfoText(&buf,version);
297-
appendStringInfo(&buf,"\"");
321+
case1:
322+
doc->standalone=1;
323+
break;
324+
case-1:
325+
doc->standalone=0;
326+
break;
327+
default:
328+
doc->standalone=-1;
329+
break;
298330
}
299-
if (standalone)
300-
appendStringInfo(&buf," standalone=\"%s\"",
301-
(standalone==1 ?"yes" :"no"));
302-
appendStringInfo(&buf,"?>");
303-
appendStringInfoText(&buf, (text*)data);
304331

305-
result=stringinfo_to_xmltype(&buf);
306-
pfree(buf.data);
307-
returnresult;
332+
buffer=xmlBufferCreate();
333+
save=xmlSaveToBuffer(buffer,NULL,0);
334+
xmlSaveDoc(save,doc);
335+
xmlSaveClose(save);
336+
337+
xmlFreeDoc(doc);
338+
339+
returnxmlBuffer_to_xmltype(buffer);
308340
#else
309341
NO_XML_SUPPORT();
310342
returnNULL;
@@ -444,7 +476,14 @@ xml_init(void)
444476
/* Now that xml_err_buf exists, safe to call xml_errorHandler */
445477
xmlSetGenericErrorFunc(NULL,xml_errorHandler);
446478

479+
#ifdefNOT_USED
480+
/*
481+
* FIXME: This doesn't work because libxml assumes that whatever
482+
* libxml allocates, only libxml will free, so we can't just drop
483+
* memory contexts behind it. This needs to be refined.
484+
*/
447485
xmlMemSetup(xml_pfree,xml_palloc,xml_repalloc,xml_pstrdup);
486+
#endif
448487
xmlInitParser();
449488
LIBXML_TEST_VERSION;
450489
}
@@ -528,8 +567,6 @@ xml_parse(text *data, bool is_document, bool preserve_whitespace)
528567
* ) */
529568
/* ... */
530569

531-
if (doc)
532-
xmlFreeDoc(doc);
533570
if (ctxt)
534571
xmlFreeParserCtxt(ctxt);
535572
xmlCleanupParser();
@@ -538,6 +575,7 @@ xml_parse(text *data, bool is_document, bool preserve_whitespace)
538575
{
539576
if (doc)
540577
xmlFreeDoc(doc);
578+
doc=NULL;
541579
if (ctxt)
542580
xmlFreeParserCtxt(ctxt);
543581
xmlCleanupParser();
@@ -567,6 +605,7 @@ xml_text2xmlChar(text *in)
567605
}
568606

569607

608+
#ifdefNOT_USED
570609
/*
571610
* Wrappers for memory management functions
572611
*/
@@ -596,6 +635,7 @@ xml_pstrdup(const char *string)
596635
{
597636
returnpstrdup(string);
598637
}
638+
#endif/* NOT_USED */
599639

600640

601641
/*

‎src/test/regress/expected/xml.out

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,30 @@ SELECT xmlpi(name foo, 'bar');
124124
SELECT xmlpi(name foo, 'in?>valid');
125125
ERROR: invalid XML processing instruction
126126
DETAIL: XML processing instruction cannot contain "?>".
127+
SELECT xmlroot(xml '<foo/>', version no value, standalone no value);
128+
xmlroot
129+
-----------------------
130+
<?xml version="1.0"?>
131+
<foo/>
132+
133+
(1 row)
134+
135+
SELECT xmlroot(xml '<foo/>', version '2.0');
136+
xmlroot
137+
-----------------------
138+
<?xml version="2.0"?>
139+
<foo/>
140+
141+
(1 row)
142+
143+
SELECT xmlroot(xmlroot(xml '<foo/>', version '1.0'), version '1.1', standalone no);
144+
xmlroot
145+
---------------------------------------
146+
<?xml version="1.1" standalone="no"?>
147+
<foo/>
148+
149+
(1 row)
150+
127151
SELECT xmlroot (
128152
xmlelement (
129153
name gazonk,
@@ -139,9 +163,11 @@ SELECT xmlroot (
139163
version '1.0',
140164
standalone yes
141165
);
142-
xmlroot
143-
------------------------------------------------------------------------------------------
144-
<?xml version="1.0" standalone="yes"?><gazonk name="val" num="2"><qux>foo</qux></gazonk>
166+
xmlroot
167+
----------------------------------------------------
168+
<?xml version="1.0" standalone="yes"?>
169+
<gazonk name="val" num="2"><qux>foo</qux></gazonk>
170+
145171
(1 row)
146172

147173
SELECT xmlserialize(content data as character varying) FROM xmltest;

‎src/test/regress/expected/xml_1.out

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,12 @@ SELECT xmlpi(name foo, 'bar');
6262
ERROR: no XML support in this installation
6363
SELECT xmlpi(name foo, 'in?>valid');
6464
ERROR: no XML support in this installation
65+
SELECT xmlroot(xml '<foo/>', version no value, standalone no value);
66+
ERROR: no XML support in this installation
67+
SELECT xmlroot(xml '<foo/>', version '2.0');
68+
ERROR: no XML support in this installation
69+
SELECT xmlroot(xmlroot(xml '<foo/>', version '1.0'), version '1.1', standalone no);
70+
ERROR: no XML support in this installation
6571
SELECT xmlroot (
6672
xmlelement (
6773
name gazonk,

‎src/test/regress/sql/xml.sql

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,9 @@ SELECT xmlpi(name xmlstuff);
5252
SELECT xmlpi(name foo,'bar');
5353
SELECT xmlpi(name foo,'in?>valid');
5454

55+
SELECT xmlroot(xml'<foo/>', version no value, standalone no value);
56+
SELECT xmlroot(xml'<foo/>', version'2.0');
57+
SELECT xmlroot(xmlroot(xml'<foo/>', version'1.0'), version'1.1', standalone no);
5558

5659
SELECT xmlroot (
5760
xmlelement (

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp