Due to some code reshuffling, xmlconcat(NULL) will crash in 8.3 and 8.4.
The pfree(buf.data) in ExecEvalXml() frees a buffer that is actuall
only initialized in the XMLFOREST case. So then the xmlconcat(NULL)
falls through to the pfree() it crashes. I have attached a patch for
8.3 and 8.4 to clean this up.
diff -cr ../cvs-pgsql/src/backend/executor/execQual.c
./src/backend/executor/execQual.c
*** ../cvs-pgsql/src/backend/executor/execQual.c 2008-11-03
16:31:21.000000000 +0200
--- ./src/backend/executor/execQual.c 2008-11-14 16:31:52.000000000 +0200
***************
*** 3163,3175 ****
bool *isNull, ExprDoneCond *isDone)
{
XmlExpr *xexpr = (XmlExpr *) xmlExpr->xprstate.expr;
- text *result;
- StringInfoData buf;
Datum value;
bool isnull;
ListCell *arg;
ListCell *narg;
- int i;
if (isDone)
*isDone = ExprSingleResult;
--- 3163,3172 ----
***************
*** 3195,3206 ****
*isNull = false;
return
PointerGetDatum(xmlconcat(values));
}
}
break;
case IS_XMLFOREST:
initStringInfo(&buf);
- i = 0;
forboth(arg, xmlExpr->named_args, narg,
xexpr->arg_names)
{
ExprState *e = (ExprState *) lfirst(arg);
--- 3192,3207 ----
*isNull = false;
return
PointerGetDatum(xmlconcat(values));
}
+ else
+ return (Datum) 0;
}
break;
case IS_XMLFOREST:
+ {
+ StringInfoData buf;
+
initStringInfo(&buf);
forboth(arg, xmlExpr->named_args, narg,
xexpr->arg_names)
{
ExprState *e = (ExprState *) lfirst(arg);
***************
*** 3215,3225 ****
argname);
*isNull = false;
}
- i++;
}
break;
- /* The remaining cases don't need to set up buf */
case IS_XMLELEMENT:
*isNull = false;
return PointerGetDatum(xmlelement(xmlExpr, econtext));
--- 3216,3240 ----
argname);
*isNull = false;
}
}
+
+ if (*isNull)
+ {
+ pfree(buf.data);
+ return (Datum) 0;
+ }
+ else
+ {
+ text *result;
+
+ result = cstring_to_text_with_len(buf.data,
buf.len);
+ pfree(buf.data);
+
+ return PointerGetDatum(result);
+ }
+ }
break;
case IS_XMLELEMENT:
*isNull = false;
return PointerGetDatum(xmlelement(xmlExpr, econtext));
***************
*** 3354,3366 ****
break;
}
! if (*isNull)
! result = NULL;
! else
! result = cstring_to_text_with_len(buf.data, buf.len);
!
! pfree(buf.data);
! return PointerGetDatum(result);
}
/* ----------------------------------------------------------------
--- 3369,3376 ----
break;
}
! elog(ERROR, "unrecognized XML operation");
! return (Datum) 0;
}
/* ----------------------------------------------------------------
diff -cr ../cvs-pgsql/src/test/regress/expected/xml.out
./src/test/regress/expected/xml.out
*** ../cvs-pgsql/src/test/regress/expected/xml.out 2008-09-02
15:11:11.000000000 +0300
--- ./src/test/regress/expected/xml.out 2008-11-14 16:50:02.000000000 +0200
***************
*** 77,82 ****
--- 77,94 ----
<?xml version="1.1"?><foo/><bar/>
(1 row)
+ SELECT xmlconcat(NULL);
+ xmlconcat
+ -----------
+
+ (1 row)
+
+ SELECT xmlconcat(NULL, NULL);
+ xmlconcat
+ -----------
+
+ (1 row)
+
SELECT xmlelement(name element,
xmlattributes (1 as one, 'deuce' as two),
'content');
diff -cr ../cvs-pgsql/src/test/regress/expected/xml_1.out
./src/test/regress/expected/xml_1.out
*** ../cvs-pgsql/src/test/regress/expected/xml_1.out 2008-09-02
15:11:11.000000000 +0300
--- ./src/test/regress/expected/xml_1.out 2008-11-14 16:50:16.000000000
+0200
***************
*** 79,84 ****
--- 79,96 ----
^
DETAIL: This functionality requires the server to be built with libxml
support.
HINT: You need to rebuild PostgreSQL using --with-libxml.
+ SELECT xmlconcat(NULL);
+ xmlconcat
+ -----------
+
+ (1 row)
+
+ SELECT xmlconcat(NULL, NULL);
+ xmlconcat
+ -----------
+
+ (1 row)
+
SELECT xmlelement(name element,
xmlattributes (1 as one, 'deuce' as two),
'content');
diff -cr ../cvs-pgsql/src/test/regress/sql/xml.sql
./src/test/regress/sql/xml.sql
*** ../cvs-pgsql/src/test/regress/sql/xml.sql 2007-11-09 17:52:51.000000000
+0200
--- ./src/test/regress/sql/xml.sql 2008-11-14 16:49:41.000000000 +0200
***************
*** 26,31 ****
--- 26,33 ----
SELECT xmlconcat('bad', '<syntax');
SELECT xmlconcat('<foo/>', NULL, '<?xml version="1.1"
standalone="no"?><bar/>');
SELECT xmlconcat('<?xml version="1.1"?><foo/>', NULL, '<?xml version="1.1"
standalone="no"?><bar/>');
+ SELECT xmlconcat(NULL);
+ SELECT xmlconcat(NULL, NULL);
SELECT xmlelement(name element,
diff -cr ../cvs-pgsql/src/backend/executor/execQual.c
./src/backend/executor/execQual.c
*** ../cvs-pgsql/src/backend/executor/execQual.c 2008-09-04
15:15:17.000000000 +0300
--- ./src/backend/executor/execQual.c 2008-11-14 15:57:59.000000000 +0200
***************
*** 2848,2860 ****
bool *isNull, ExprDoneCond *isDone)
{
XmlExpr *xexpr = (XmlExpr *) xmlExpr->xprstate.expr;
- text *result;
- StringInfoData buf;
Datum value;
bool isnull;
ListCell *arg;
ListCell *narg;
- int i;
if (isDone)
*isDone = ExprSingleResult;
--- 2848,2857 ----
***************
*** 2880,2891 ****
*isNull = false;
return
PointerGetDatum(xmlconcat(values));
}
}
break;
case IS_XMLFOREST:
initStringInfo(&buf);
- i = 0;
forboth(arg, xmlExpr->named_args, narg,
xexpr->arg_names)
{
ExprState *e = (ExprState *) lfirst(arg);
--- 2877,2892 ----
*isNull = false;
return
PointerGetDatum(xmlconcat(values));
}
+ else
+ return (Datum) 0;
}
break;
case IS_XMLFOREST:
+ {
+ StringInfoData buf;
+
initStringInfo(&buf);
forboth(arg, xmlExpr->named_args, narg,
xexpr->arg_names)
{
ExprState *e = (ExprState *) lfirst(arg);
***************
*** 2900,2910 ****
argname);
*isNull = false;
}
- i++;
}
break;
- /* The remaining cases don't need to set up buf */
case IS_XMLELEMENT:
*isNull = false;
return PointerGetDatum(xmlelement(xmlExpr, econtext));
--- 2901,2930 ----
argname);
*isNull = false;
}
}
+
+ if (*isNull)
+ {
+ pfree(buf.data);
+ return (Datum) 0;
+ }
+ else
+ {
+ int len;
+ text *result;
+
+ len = buf.len + VARHDRSZ;
+
+ result = palloc(len);
+ SET_VARSIZE(result, len);
+ memcpy(VARDATA(result), buf.data, buf.len);
+ pfree(buf.data);
+
+ return PointerGetDatum(result);
+ }
+ }
break;
case IS_XMLELEMENT:
*isNull = false;
return PointerGetDatum(xmlelement(xmlExpr, econtext));
***************
*** 3039,3057 ****
break;
}
! if (*isNull)
! result = NULL;
! else
! {
! int len = buf.len + VARHDRSZ;
!
! result = palloc(len);
! SET_VARSIZE(result, len);
! memcpy(VARDATA(result), buf.data, buf.len);
! }
!
! pfree(buf.data);
! return PointerGetDatum(result);
}
/* ----------------------------------------------------------------
--- 3059,3066 ----
break;
}
! elog(ERROR, "unrecognized XML operation");
! return (Datum) 0;
}
/* ----------------------------------------------------------------
diff -cr ../cvs-pgsql/src/test/regress/expected/xml.out
./src/test/regress/expected/xml.out
*** ../cvs-pgsql/src/test/regress/expected/xml.out 2008-09-04
15:15:55.000000000 +0300
--- ./src/test/regress/expected/xml.out 2008-11-14 16:48:59.000000000 +0200
***************
*** 71,76 ****
--- 71,88 ----
<?xml version="1.1"?><foo/><bar/>
(1 row)
+ SELECT xmlconcat(NULL);
+ xmlconcat
+ -----------
+
+ (1 row)
+
+ SELECT xmlconcat(NULL, NULL);
+ xmlconcat
+ -----------
+
+ (1 row)
+
SELECT xmlelement(name element,
xmlattributes (1 as one, 'deuce' as two),
'content');
diff -cr ../cvs-pgsql/src/test/regress/expected/xml_1.out
./src/test/regress/expected/xml_1.out
*** ../cvs-pgsql/src/test/regress/expected/xml_1.out 2008-09-04
15:15:55.000000000 +0300
--- ./src/test/regress/expected/xml_1.out 2008-11-14 16:49:19.000000000
+0200
***************
*** 63,68 ****
--- 63,80 ----
ERROR: unsupported XML feature
DETAIL: This functionality requires the server to be built with libxml
support.
HINT: You need to rebuild PostgreSQL using --with-libxml.
+ SELECT xmlconcat(NULL);
+ xmlconcat
+ -----------
+
+ (1 row)
+
+ SELECT xmlconcat(NULL, NULL);
+ xmlconcat
+ -----------
+
+ (1 row)
+
SELECT xmlelement(name element,
xmlattributes (1 as one, 'deuce' as two),
'content');
diff -cr ../cvs-pgsql/src/test/regress/sql/xml.sql
./src/test/regress/sql/xml.sql
*** ../cvs-pgsql/src/test/regress/sql/xml.sql 2007-11-09 17:52:51.000000000
+0200
--- ./src/test/regress/sql/xml.sql 2008-11-14 16:48:31.000000000 +0200
***************
*** 26,31 ****
--- 26,33 ----
SELECT xmlconcat('bad', '<syntax');
SELECT xmlconcat('<foo/>', NULL, '<?xml version="1.1"
standalone="no"?><bar/>');
SELECT xmlconcat('<?xml version="1.1"?><foo/>', NULL, '<?xml version="1.1"
standalone="no"?><bar/>');
+ SELECT xmlconcat(NULL);
+ SELECT xmlconcat(NULL, NULL);
SELECT xmlelement(name element,
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers