OSDN Git Service

Fix machine-dependent crash in sqlchar_to_unicode(). Get rid of
authorTom Lane <tgl@sss.pgh.pa.us>
Sun, 24 Dec 2006 00:57:48 +0000 (00:57 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Sun, 24 Dec 2006 00:57:48 +0000 (00:57 +0000)
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).

src/backend/utils/adt/xml.c
src/backend/utils/mb/mbutils.c
src/include/mb/pg_wchar.h

index a6dc1a6..dc6a7f1 100644 (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];
 }
 
 
index 89845b0..f462ba4 100644 (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)
index 2d465a1..78236c7 100644 (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);