Skip to content

Commit f71c7b9

Browse files
committed
Fix bugs in XML binary I/O functions. Heikki and Tom
1 parent a8da576 commit f71c7b9

File tree

1 file changed

+30
-9
lines changed
  • src/backend/utils/adt

1 file changed

+30
-9
lines changed

src/backend/utils/adt/xml.c

Lines changed: 30 additions & 9 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.46 2007/07/13 03:43:23 tgl Exp $
10+
* $PostgreSQL: pgsql/src/backend/utils/adt/xml.c,v 1.47 2007/09/23 21:36:42 tgl Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -232,37 +232,51 @@ xml_recv(PG_FUNCTION_ARGS)
232232
xmlDocPtr doc;
233233
xmlChar *encoding = NULL;
234234

235-
str = pq_getmsgtext(buf, buf->len - buf->cursor, &nbytes);
235+
/*
236+
* Read the data in raw format. We don't know yet what the encoding
237+
* is, as that information is embedded in the xml declaration; so we
238+
* have to parse that before converting to server encoding.
239+
*/
240+
nbytes = buf->len - buf->cursor;
241+
str = (char *) pq_getmsgbytes(buf, nbytes);
236242

237-
result = palloc(nbytes + VARHDRSZ);
243+
/*
244+
* We need a null-terminated string to pass to parse_xml_decl(). Rather
245+
* than make a separate copy, make the temporary result one byte bigger
246+
* than it needs to be.
247+
*/
248+
result = palloc(nbytes + 1 + VARHDRSZ);
238249
SET_VARSIZE(result, nbytes + VARHDRSZ);
239250
memcpy(VARDATA(result), str, nbytes);
251+
str = VARDATA(result);
252+
str[nbytes] = '\0';
240253

241254
parse_xml_decl((xmlChar *) str, NULL, NULL, &encoding, NULL);
242255

243256
/*
244257
* Parse the data to check if it is well-formed XML data. Assume
245-
* that ERROR occurred if parsing failed.
258+
* that xml_parse will throw ERROR if not.
246259
*/
247260
doc = xml_parse(result, xmloption, true, encoding);
248261
xmlFreeDoc(doc);
249262

263+
/* Now that we know what we're dealing with, convert to server encoding */
250264
newstr = (char *) pg_do_encoding_conversion((unsigned char *) str,
251265
nbytes,
252266
encoding ? pg_char_to_encoding((char *) encoding) : PG_UTF8,
253267
GetDatabaseEncoding());
254268

255-
pfree(str);
256-
257269
if (newstr != str)
258270
{
259-
free(result);
271+
pfree(result);
260272

261273
nbytes = strlen(newstr);
262274

263275
result = palloc(nbytes + VARHDRSZ);
264276
SET_VARSIZE(result, nbytes + VARHDRSZ);
265277
memcpy(VARDATA(result), newstr, nbytes);
278+
279+
pfree(newstr);
266280
}
267281

268282
PG_RETURN_XML_P(result);
@@ -277,11 +291,18 @@ Datum
277291
xml_send(PG_FUNCTION_ARGS)
278292
{
279293
xmltype *x = PG_GETARG_XML_P(0);
280-
char *outval = xml_out_internal(x, pg_get_client_encoding());
294+
char *outval;
281295
StringInfoData buf;
296+
297+
/*
298+
* xml_out_internal doesn't convert the encoding, it just prints
299+
* the right declaration. pq_sendtext will do the conversion.
300+
*/
301+
outval = xml_out_internal(x, pg_get_client_encoding());
282302

283303
pq_begintypsend(&buf);
284-
pq_sendstring(&buf, outval);
304+
pq_sendtext(&buf, outval, strlen(outval));
305+
pfree(outval);
285306
PG_RETURN_BYTEA_P(pq_endtypsend(&buf));
286307
}
287308

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