Fix machine-dependent crash in sqlchar_to_unicode(). Get rid of

bletcherous and unsafe manipulation of global encoding setting.
Clean up libxml reporting mechanism a bit (it still looks like a
dangling-pointer crash waiting to happen, though, not to mention
being far less than sane from a localization standpoint).
This commit is contained in:
Tom Lane 2006-12-24 00:57:48 +00:00
parent c957c0bac7
commit e9da20ab4d
3 changed files with 30 additions and 22 deletions

View File

@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $PostgreSQL: pgsql/src/backend/utils/adt/xml.c,v 1.3 2006/12/24 00:29:19 tgl Exp $
* $PostgreSQL: pgsql/src/backend/utils/adt/xml.c,v 1.4 2006/12/24 00:57:48 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@ -42,7 +42,6 @@
#ifdef USE_LIBXML
#define PG_XML_DEFAULT_URI "dummy.xml"
#define XML_ERRBUF_SIZE 200
static void xml_init(void);
@ -60,8 +59,7 @@ static xmlDocPtr xml_parse(text *data, int opts, bool is_document);
/* Global variables */
/* taken from contrib/xml2 */
/* FIXME: DO NOT USE global vars !!! */
char *xml_errbuf; /* per line error buffer */
char *xml_errmsg = NULL; /* overall error message */
static char *xml_errmsg = NULL; /* overall error message */
#endif /* USE_LIBXML */
@ -376,8 +374,6 @@ xml_init(void)
/* do not flood PG's logfile with libxml error messages - reset error handler*/
xmlSetGenericErrorFunc(NULL, xml_errorHandler);
xml_errmsg = NULL;
xml_errbuf = palloc(XML_ERRBUF_SIZE);
memset(xml_errbuf, 0, XML_ERRBUF_SIZE);
}
@ -563,6 +559,7 @@ xml_ereport(int level, char *msg, void *ctxt)
{
ereport(DEBUG1, (errmsg("%s", xml_errmsg)));
pfree(xml_errmsg);
xml_errmsg = NULL;
}
if (ctxt != NULL)
@ -605,23 +602,26 @@ xml_ereport(int level, char *msg, void *ctxt)
static void
xml_errorHandler(void *ctxt, const char *msg,...)
{
char xml_errbuf[256];
va_list args;
/* Format this message ... */
va_start(args, msg);
vsnprintf(xml_errbuf, XML_ERRBUF_SIZE, msg, args);
vsnprintf(xml_errbuf, sizeof(xml_errbuf)-1, msg, args);
va_end(args);
/* Now copy the argument across */
xml_errbuf[sizeof(xml_errbuf)-1] = '\0';
/* ... and append to xml_errbuf */
if (xml_errmsg == NULL)
xml_errmsg = pstrdup(xml_errbuf);
else
{
int32 xsize = strlen(xml_errmsg);
xml_errmsg = repalloc(xml_errmsg, (size_t) (xsize + strlen(xml_errbuf) + 1));
strncpy(&xml_errmsg[xsize - 1], xml_errbuf, strlen(xml_errbuf));
xml_errmsg[xsize + strlen(xml_errbuf) - 1] = '\0';
xml_errmsg = repalloc(xml_errmsg,
(size_t) (xsize + strlen(xml_errbuf) + 1));
strcpy(&xml_errmsg[xsize - 1], xml_errbuf);
}
memset(xml_errbuf, 0, XML_ERRBUF_SIZE);
}
@ -800,13 +800,15 @@ xml_ereport_by_code(int level, char *msg, int code)
break;
default:
det = "Unregistered error (libxml error code: %d)";
ereport(DEBUG1, (errmsg("Check out \"libxml/xmlerror.h\" and bring errcode \"%d\" processing to \"xml.c\".", code)));
ereport(DEBUG1,
(errmsg_internal("Check out \"libxml/xmlerror.h\" and bring errcode \"%d\" processing to \"xml.c\".", code)));
}
if (xml_errmsg != NULL)
{
ereport(DEBUG1, (errmsg("%s", xml_errmsg)));
pfree(xml_errmsg);
xml_errmsg = NULL;
}
ereport(level, (errmsg(msg), errdetail(det, code)));
@ -820,21 +822,17 @@ xml_ereport_by_code(int level, char *msg, int code)
static pg_wchar
sqlchar_to_unicode(char *s)
{
int save_enc;
pg_wchar ret;
char *utf8string;
pg_wchar ret[2]; /* need space for trailing zero */
utf8string = (char *) pg_do_encoding_conversion((unsigned char *) s,
pg_mblen(s),
GetDatabaseEncoding(),
PG_UTF8);
save_enc = GetDatabaseEncoding();
SetDatabaseEncoding(PG_UTF8);
pg_mb2wchar_with_len(utf8string, &ret, pg_mblen(s));
SetDatabaseEncoding(save_enc);
pg_encoding_mb2wchar_with_len(PG_UTF8, utf8string, ret, pg_mblen(s));
return ret;
return ret[0];
}

View File

@ -4,7 +4,7 @@
* (currently mule internal code (mic) is used)
* Tatsuo Ishii
*
* $PostgreSQL: pgsql/src/backend/utils/mb/mbutils.c,v 1.60 2006/12/21 16:05:15 petere Exp $
* $PostgreSQL: pgsql/src/backend/utils/mb/mbutils.c,v 1.61 2006/12/24 00:57:48 tgl Exp $
*/
#include "postgres.h"
@ -483,6 +483,14 @@ pg_mb2wchar_with_len(const char *from, pg_wchar *to, int len)
return (*pg_wchar_table[DatabaseEncoding->encoding].mb2wchar_with_len) ((const unsigned char *) from, to, len);
}
/* same, with any encoding */
int
pg_encoding_mb2wchar_with_len(int encoding,
const char *from, pg_wchar *to, int len)
{
return (*pg_wchar_table[encoding].mb2wchar_with_len) ((const unsigned char *) from, to, len);
}
/* returns the byte length of a multibyte word */
int
pg_mblen(const char *mbstr)

View File

@ -1,4 +1,4 @@
/* $PostgreSQL: pgsql/src/include/mb/pg_wchar.h,v 1.69 2006/10/04 00:30:09 momjian Exp $ */
/* $PostgreSQL: pgsql/src/include/mb/pg_wchar.h,v 1.70 2006/12/24 00:57:48 tgl Exp $ */
#ifndef PG_WCHAR_H
#define PG_WCHAR_H
@ -293,6 +293,8 @@ typedef struct
extern int pg_mb2wchar(const char *from, pg_wchar *to);
extern int pg_mb2wchar_with_len(const char *from, pg_wchar *to, int len);
extern int pg_encoding_mb2wchar_with_len(int encoding,
const char *from, pg_wchar *to, int len);
extern int pg_char_and_wchar_strcmp(const char *s1, const pg_wchar *s2);
extern int pg_wchar_strncmp(const pg_wchar *s1, const pg_wchar *s2, size_t n);
extern int pg_char_and_wchar_strncmp(const char *s1, const pg_wchar *s2, size_t n);