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:
parent
c957c0bac7
commit
e9da20ab4d
@ -7,7 +7,7 @@
|
|||||||
* Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* 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
|
#ifdef USE_LIBXML
|
||||||
|
|
||||||
#define PG_XML_DEFAULT_URI "dummy.xml"
|
#define PG_XML_DEFAULT_URI "dummy.xml"
|
||||||
#define XML_ERRBUF_SIZE 200
|
|
||||||
|
|
||||||
|
|
||||||
static void xml_init(void);
|
static void xml_init(void);
|
||||||
@ -60,8 +59,7 @@ static xmlDocPtr xml_parse(text *data, int opts, bool is_document);
|
|||||||
/* Global variables */
|
/* Global variables */
|
||||||
/* taken from contrib/xml2 */
|
/* taken from contrib/xml2 */
|
||||||
/* FIXME: DO NOT USE global vars !!! */
|
/* FIXME: DO NOT USE global vars !!! */
|
||||||
char *xml_errbuf; /* per line error buffer */
|
static char *xml_errmsg = NULL; /* overall error message */
|
||||||
char *xml_errmsg = NULL; /* overall error message */
|
|
||||||
|
|
||||||
#endif /* USE_LIBXML */
|
#endif /* USE_LIBXML */
|
||||||
|
|
||||||
@ -376,8 +374,6 @@ xml_init(void)
|
|||||||
/* do not flood PG's logfile with libxml error messages - reset error handler*/
|
/* do not flood PG's logfile with libxml error messages - reset error handler*/
|
||||||
xmlSetGenericErrorFunc(NULL, xml_errorHandler);
|
xmlSetGenericErrorFunc(NULL, xml_errorHandler);
|
||||||
xml_errmsg = NULL;
|
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)));
|
ereport(DEBUG1, (errmsg("%s", xml_errmsg)));
|
||||||
pfree(xml_errmsg);
|
pfree(xml_errmsg);
|
||||||
|
xml_errmsg = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ctxt != NULL)
|
if (ctxt != NULL)
|
||||||
@ -605,23 +602,26 @@ xml_ereport(int level, char *msg, void *ctxt)
|
|||||||
static void
|
static void
|
||||||
xml_errorHandler(void *ctxt, const char *msg,...)
|
xml_errorHandler(void *ctxt, const char *msg,...)
|
||||||
{
|
{
|
||||||
|
char xml_errbuf[256];
|
||||||
va_list args;
|
va_list args;
|
||||||
|
|
||||||
|
/* Format this message ... */
|
||||||
va_start(args, msg);
|
va_start(args, msg);
|
||||||
vsnprintf(xml_errbuf, XML_ERRBUF_SIZE, msg, args);
|
vsnprintf(xml_errbuf, sizeof(xml_errbuf)-1, msg, args);
|
||||||
va_end(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)
|
if (xml_errmsg == NULL)
|
||||||
xml_errmsg = pstrdup(xml_errbuf);
|
xml_errmsg = pstrdup(xml_errbuf);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
int32 xsize = strlen(xml_errmsg);
|
int32 xsize = strlen(xml_errmsg);
|
||||||
|
|
||||||
xml_errmsg = repalloc(xml_errmsg, (size_t) (xsize + strlen(xml_errbuf) + 1));
|
xml_errmsg = repalloc(xml_errmsg,
|
||||||
strncpy(&xml_errmsg[xsize - 1], xml_errbuf, strlen(xml_errbuf));
|
(size_t) (xsize + strlen(xml_errbuf) + 1));
|
||||||
xml_errmsg[xsize + strlen(xml_errbuf) - 1] = '\0';
|
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;
|
break;
|
||||||
default:
|
default:
|
||||||
det = "Unregistered error (libxml error code: %d)";
|
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)
|
if (xml_errmsg != NULL)
|
||||||
{
|
{
|
||||||
ereport(DEBUG1, (errmsg("%s", xml_errmsg)));
|
ereport(DEBUG1, (errmsg("%s", xml_errmsg)));
|
||||||
pfree(xml_errmsg);
|
pfree(xml_errmsg);
|
||||||
|
xml_errmsg = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
ereport(level, (errmsg(msg), errdetail(det, code)));
|
ereport(level, (errmsg(msg), errdetail(det, code)));
|
||||||
@ -820,21 +822,17 @@ xml_ereport_by_code(int level, char *msg, int code)
|
|||||||
static pg_wchar
|
static pg_wchar
|
||||||
sqlchar_to_unicode(char *s)
|
sqlchar_to_unicode(char *s)
|
||||||
{
|
{
|
||||||
int save_enc;
|
|
||||||
pg_wchar ret;
|
|
||||||
char *utf8string;
|
char *utf8string;
|
||||||
|
pg_wchar ret[2]; /* need space for trailing zero */
|
||||||
|
|
||||||
utf8string = (char *) pg_do_encoding_conversion((unsigned char *) s,
|
utf8string = (char *) pg_do_encoding_conversion((unsigned char *) s,
|
||||||
pg_mblen(s),
|
pg_mblen(s),
|
||||||
GetDatabaseEncoding(),
|
GetDatabaseEncoding(),
|
||||||
PG_UTF8);
|
PG_UTF8);
|
||||||
|
|
||||||
save_enc = GetDatabaseEncoding();
|
pg_encoding_mb2wchar_with_len(PG_UTF8, utf8string, ret, pg_mblen(s));
|
||||||
SetDatabaseEncoding(PG_UTF8);
|
|
||||||
pg_mb2wchar_with_len(utf8string, &ret, pg_mblen(s));
|
|
||||||
SetDatabaseEncoding(save_enc);
|
|
||||||
|
|
||||||
return ret;
|
return ret[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
* (currently mule internal code (mic) is used)
|
* (currently mule internal code (mic) is used)
|
||||||
* Tatsuo Ishii
|
* 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"
|
#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);
|
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 */
|
/* returns the byte length of a multibyte word */
|
||||||
int
|
int
|
||||||
pg_mblen(const char *mbstr)
|
pg_mblen(const char *mbstr)
|
||||||
|
@ -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
|
#ifndef PG_WCHAR_H
|
||||||
#define 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(const char *from, pg_wchar *to);
|
||||||
extern int pg_mb2wchar_with_len(const char *from, pg_wchar *to, int len);
|
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_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_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);
|
extern int pg_char_and_wchar_strncmp(const char *s1, const pg_wchar *s2, size_t n);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user