From 5e51297104047169ec3272c34a756c9b6ea66b76 Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Tue, 6 Nov 2007 03:06:28 +0000 Subject: [PATCH] Some code review for xml.c: Add some more xml_init() calls that might not be necessary, but seem like a good idea to avoid possible problems like we saw in xmlelement(). Fix unsafe assumption that you can keep using the tupledesc of a relcache entry you don't have open. Add missing error checks for SearchSysCache failure. Get rid of handwritten array traversal in xpath() and O(N^2), broken-for-nulls array access code in map_sql_value_to_xml_value(), in favor of using deconstruct_array. Manually adjust a lot of line breaks in places where the code is otherwise gonna look pretty awful after pg_indent hacks it up (original author seems to have liked to lay out code for a 200-column window). --- src/backend/utils/adt/xml.c | 521 ++++++++++++++++++++++++++------------------ 1 file changed, 314 insertions(+), 207 deletions(-) diff --git a/src/backend/utils/adt/xml.c b/src/backend/utils/adt/xml.c index 5f5654c232..9e9d0e1af5 100644 --- a/src/backend/utils/adt/xml.c +++ b/src/backend/utils/adt/xml.c @@ -7,7 +7,7 @@ * Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $PostgreSQL: pgsql/src/backend/utils/adt/xml.c,v 1.50 2007/11/05 22:23:07 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/utils/adt/xml.c,v 1.51 2007/11/06 03:06:28 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -86,27 +86,38 @@ static void *xml_palloc(size_t size); static void *xml_repalloc(void *ptr, size_t size); static void xml_pfree(void *ptr); static char *xml_pstrdup(const char *string); -static void xml_ereport(int level, int sqlcode, - const char *msg); +static void xml_ereport(int level, int sqlcode, const char *msg); static void xml_errorHandler(void *ctxt, const char *msg, ...); static void xml_ereport_by_code(int level, int sqlcode, const char *msg, int errcode); static xmlChar *xml_text2xmlChar(text *in); -static int parse_xml_decl(const xmlChar *str, size_t *lenp, xmlChar **version, xmlChar **encoding, int *standalone); -static bool print_xml_decl(StringInfo buf, const xmlChar *version, pg_enc encoding, int standalone); -static xmlDocPtr xml_parse(text *data, XmlOptionType xmloption_arg, bool preserve_whitespace, xmlChar *encoding); +static int parse_xml_decl(const xmlChar *str, size_t *lenp, + xmlChar **version, xmlChar **encoding, int *standalone); +static bool print_xml_decl(StringInfo buf, const xmlChar *version, + pg_enc encoding, int standalone); +static xmlDocPtr xml_parse(text *data, XmlOptionType xmloption_arg, + bool preserve_whitespace, xmlChar *encoding); static text *xml_xmlnodetoxmltype(xmlNodePtr cur); #endif /* USE_LIBXML */ -static StringInfo query_to_xml_internal(const char *query, char *tablename, const char *xmlschema, bool nulls, bool tableforest, const char *targetns, bool top_level); -static const char * map_sql_table_to_xmlschema(TupleDesc tupdesc, Oid relid, bool nulls, bool tableforest, const char *targetns); -static const char * map_sql_schema_to_xmlschema_types(Oid nspid, List *relid_list, bool nulls, bool tableforest, const char *targetns); -static const char * map_sql_catalog_to_xmlschema_types(List *nspid_list, bool nulls, bool tableforest, const char *targetns); +static StringInfo query_to_xml_internal(const char *query, char *tablename, + const char *xmlschema, bool nulls, bool tableforest, + const char *targetns, bool top_level); +static const char *map_sql_table_to_xmlschema(TupleDesc tupdesc, Oid relid, + bool nulls, bool tableforest, const char *targetns); +static const char *map_sql_schema_to_xmlschema_types(Oid nspid, + List *relid_list, bool nulls, + bool tableforest, const char *targetns); +static const char *map_sql_catalog_to_xmlschema_types(List *nspid_list, + bool nulls, bool tableforest, + const char *targetns); static const char * map_sql_type_to_xml_name(Oid typeoid, int typmod); static const char * map_sql_typecoll_to_xmlschema_types(List *tupdesc_list); static const char * map_sql_type_to_xmlschema_type(Oid typeoid, int typmod); -static void SPI_sql_row_to_xmlelement(int rownum, StringInfo result, char *tablename, bool nulls, bool tableforest, const char *targetns, bool top_level); +static void SPI_sql_row_to_xmlelement(int rownum, StringInfo result, + char *tablename, bool nulls, bool tableforest, + const char *targetns, bool top_level); #define NO_XML_SUPPORT() \ ereport(ERROR, \ @@ -194,7 +205,8 @@ xml_out_internal(xmltype *x, pg_enc target_encoding) str[len] = '\0'; #ifdef USE_LIBXML - if ((res_code = parse_xml_decl((xmlChar *) str, &len, &version, &encoding, &standalone)) == 0) + if ((res_code = parse_xml_decl((xmlChar *) str, + &len, &version, &encoding, &standalone)) == 0) { StringInfoData buf; @@ -388,17 +400,23 @@ xmlcomment(PG_FUNCTION_ARGS) { #ifdef USE_LIBXML text *arg = PG_GETARG_TEXT_P(0); + char *argdata = VARDATA(arg); int len = VARSIZE(arg) - VARHDRSZ; StringInfoData buf; int i; /* check for "--" in string or "-" at the end */ for (i = 1; i < len; i++) - if ((VARDATA(arg)[i] == '-' && VARDATA(arg)[i - 1] == '-') - || (VARDATA(arg)[i] == '-' && i == len - 1)) - ereport(ERROR, - (errcode(ERRCODE_INVALID_XML_COMMENT), - errmsg("invalid XML comment"))); + { + if (argdata[i] == '-' && argdata[i - 1] == '-') + ereport(ERROR, + (errcode(ERRCODE_INVALID_XML_COMMENT), + errmsg("invalid XML comment"))); + } + if (len > 0 && argdata[len - 1] == '-') + ereport(ERROR, + (errcode(ERRCODE_INVALID_XML_COMMENT), + errmsg("invalid XML comment"))); initStringInfo(&buf); appendStringInfo(&buf, "