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)
232232xmlDocPtr doc ;
233233xmlChar * 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 );
238249SET_VARSIZE (result ,nbytes + VARHDRSZ );
239250memcpy (VARDATA (result ),str ,nbytes );
251+ str = VARDATA (result );
252+ str [nbytes ]= '\0' ;
240253
241254parse_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- * thatERROR occurred if parsing failed .
258+ * thatxml_parse will throw ERROR if not .
246259 */
247260doc = xml_parse (result ,xmloption , true,encoding );
248261xmlFreeDoc (doc );
249262
263+ /* Now that we know what we're dealing with, convert to server encoding */
250264newstr = (char * )pg_do_encoding_conversion ((unsignedchar * )str ,
251265nbytes ,
252266encoding ?pg_char_to_encoding ((char * )encoding ) :PG_UTF8 ,
253267GetDatabaseEncoding ());
254268
255- pfree (str );
256-
257269if (newstr != str )
258270{
259- free (result );
271+ pfree (result );
260272
261273nbytes = strlen (newstr );
262274
263275result = palloc (nbytes + VARHDRSZ );
264276SET_VARSIZE (result ,nbytes + VARHDRSZ );
265277memcpy (VARDATA (result ),newstr ,nbytes );
278+
279+ pfree (newstr );
266280}
267281
268282PG_RETURN_XML_P (result );
@@ -277,11 +291,18 @@ Datum
277291xml_send (PG_FUNCTION_ARGS )
278292{
279293xmltype * x = PG_GETARG_XML_P (0 );
280- char * outval = xml_out_internal ( x , pg_get_client_encoding ()) ;
294+ char * outval ;
281295StringInfoData 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
283303pq_begintypsend (& buf );
284- pq_sendstring (& buf ,outval );
304+ pq_sendtext (& buf ,outval ,strlen (outval ));
305+ pfree (outval );
285306PG_RETURN_BYTEA_P (pq_endtypsend (& buf ));
286307}
287308