*** a/src/backend/utils/adt/xml.c
--- b/src/backend/utils/adt/xml.c
***************
*** 1844,1850 **** escape_xml(const char *str)
--- 1844,1865 ----
  			case '\r':
  				appendStringInfoString(&buf, "&#x0d;");
  				break;
+ 			case '\n':
+ 			case '\t':
+ 				appendStringInfoCharMacro(&buf, *p);
+ 				break;
  			default:
+ 				/* 
+ 				 * Any control char we haven't already explicitly handled
+ 				 * (i.e. TAB, NL and CR)is an error. 
+ 				 * If we ever support XML 1.1 they will be allowed,
+ 				 * but will have to be escaped.
+ 				 */
+ 				if (*p < '\x20')
+ 					ereport(ERROR,
+ 							(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
+ 							 errmsg("character out of range"),
+ 							 errdetail("XML does not support control characters.")));
  				appendStringInfoCharMacro(&buf, *p);
  				break;
  		}
