Skip to content

Commit 1b0f58a

Browse files
committed
Fix crash in bytea-to-XML mapping when the source value is toasted.
Report and fix by Michael McMaster. Some minor code beautification by me, also avoid memory leaks in the special-case paths.
1 parent db31add commit 1b0f58a

File tree

1 file changed

+47
-34
lines changed
  • src/backend/utils/adt

1 file changed

+47
-34
lines changed

src/backend/utils/adt/xml.c

Lines changed: 47 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* Portions Copyright (c) 1996-2008, 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.77 2008/09/16 00:49:41 tgl Exp $
10+
* $PostgreSQL: pgsql/src/backend/utils/adt/xml.c,v 1.78 2008/10/09 15:49:04 tgl Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -1568,8 +1568,6 @@ map_sql_value_to_xml_value(Datum value, Oid type)
15681568
{
15691569
StringInfoData buf;
15701570

1571-
initStringInfo(&buf);
1572-
15731571
if (type_is_array(type))
15741572
{
15751573
ArrayType *array;
@@ -1591,6 +1589,8 @@ map_sql_value_to_xml_value(Datum value, Oid type)
15911589
&elem_values, &elem_nulls,
15921590
&num_elems);
15931591

1592+
initStringInfo(&buf);
1593+
15941594
for (i = 0; i < num_elems; i++)
15951595
{
15961596
if (elem_nulls[i])
@@ -1604,6 +1604,8 @@ map_sql_value_to_xml_value(Datum value, Oid type)
16041604

16051605
pfree(elem_values);
16061606
pfree(elem_nulls);
1607+
1608+
return buf.data;
16071609
}
16081610
else
16091611
{
@@ -1687,62 +1689,73 @@ map_sql_value_to_xml_value(Datum value, Oid type)
16871689

16881690
return pstrdup(buf);
16891691
}
1692+
1693+
#ifdef USE_LIBXML
1694+
case BYTEAOID:
1695+
{
1696+
bytea *bstr = DatumGetByteaPP(value);
1697+
xmlBufferPtr buf;
1698+
xmlTextWriterPtr writer;
1699+
char *result;
1700+
1701+
xml_init();
1702+
1703+
buf = xmlBufferCreate();
1704+
writer = xmlNewTextWriterMemory(buf, 0);
1705+
1706+
if (xmlbinary == XMLBINARY_BASE64)
1707+
xmlTextWriterWriteBase64(writer, VARDATA_ANY(bstr),
1708+
0, VARSIZE_ANY_EXHDR(bstr));
1709+
else
1710+
xmlTextWriterWriteBinHex(writer, VARDATA_ANY(bstr),
1711+
0, VARSIZE_ANY_EXHDR(bstr));
1712+
1713+
xmlFreeTextWriter(writer);
1714+
result = pstrdup((const char *) xmlBufferContent(buf));
1715+
xmlBufferFree(buf);
1716+
return result;
1717+
}
1718+
#endif /* USE_LIBXML */
1719+
16901720
}
16911721

1722+
/*
1723+
* otherwise, just use the type's native text representation
1724+
*/
16921725
getTypeOutputInfo(type, &typeOut, &isvarlena);
16931726
str = OidOutputFunctionCall(typeOut, value);
16941727

1728+
/* ... exactly as-is for XML */
16951729
if (type == XMLOID)
16961730
return str;
16971731

1698-
#ifdef USE_LIBXML
1699-
if (type == BYTEAOID)
1700-
{
1701-
xmlBufferPtr buf;
1702-
xmlTextWriterPtr writer;
1703-
char *result;
1704-
1705-
xml_init();
1706-
1707-
buf = xmlBufferCreate();
1708-
writer = xmlNewTextWriterMemory(buf, 0);
1709-
1710-
if (xmlbinary == XMLBINARY_BASE64)
1711-
xmlTextWriterWriteBase64(writer, VARDATA(value), 0, VARSIZE(value) - VARHDRSZ);
1712-
else
1713-
xmlTextWriterWriteBinHex(writer, VARDATA(value), 0, VARSIZE(value) - VARHDRSZ);
1714-
1715-
xmlFreeTextWriter(writer);
1716-
result = pstrdup((const char *) xmlBufferContent(buf));
1717-
xmlBufferFree(buf);
1718-
return result;
1719-
}
1720-
#endif /* USE_LIBXML */
1732+
/* otherwise, translate special characters as needed */
1733+
initStringInfo(&buf);
17211734

1722-
for (p = str; *p; p += pg_mblen(p))
1735+
for (p = str; *p; p++)
17231736
{
17241737
switch (*p)
17251738
{
17261739
case '&':
1727-
appendStringInfo(&buf, "&amp;");
1740+
appendStringInfoString(&buf, "&amp;");
17281741
break;
17291742
case '<':
1730-
appendStringInfo(&buf, "&lt;");
1743+
appendStringInfoString(&buf, "&lt;");
17311744
break;
17321745
case '>':
1733-
appendStringInfo(&buf, "&gt;");
1746+
appendStringInfoString(&buf, "&gt;");
17341747
break;
17351748
case '\r':
1736-
appendStringInfo(&buf, "&#x0d;");
1749+
appendStringInfoString(&buf, "&#x0d;");
17371750
break;
17381751
default:
1739-
appendBinaryStringInfo(&buf, p, pg_mblen(p));
1752+
appendStringInfoCharMacro(&buf, *p);
17401753
break;
17411754
}
17421755
}
1743-
}
17441756

1745-
return buf.data;
1757+
return buf.data;
1758+
}
17461759
}
17471760

17481761

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy