summaryrefslogtreecommitdiff
path: root/src/backend
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2007-10-13 20:18:42 +0000
committerTom Lane <tgl@sss.pgh.pa.us>2007-10-13 20:18:42 +0000
commit8468146b03c87f86162cee62e0de25f6e2d24b56 (patch)
tree907460ef4000b0a60d672af3726fe37657e2e95b /src/backend
parent537e92e41f8bd1b3ed56ea1096ceee225fb36923 (diff)
downloadpostgresql-8468146b03c87f86162cee62e0de25f6e2d24b56.tar.gz
Fix the inadvertent libpq ABI breakage discovered by Martin Pitt: the
renumbering of encoding IDs done between 8.2 and 8.3 turns out to break 8.2 initdb and psql if they are run with an 8.3beta1 libpq.so. For the moment we can rearrange the order of enum pg_enc to keep the same number for everything except PG_JOHAB, which isn't a problem since there are no direct references to it in the 8.2 programs anyway. (This does force initdb unfortunately.) Going forward, we want to fix things so that encoding IDs can be changed without an ABI break, and this commit includes the changes needed to allow libpq's encoding IDs to be treated as fully independent of the backend's. The main issue is that libpq clients should not include pg_wchar.h or otherwise assume they know the specific values of libpq's encoding IDs, since they might encounter version skew between pg_wchar.h and the libpq.so they are using. To fix, have libpq officially export functions needed for encoding name<=>ID conversion and validity checking; it was doing this anyway unofficially. It's still the case that we can't renumber backend encoding IDs until the next bump in libpq's major version number, since doing so will break the 8.2-era client programs. However the code is now prepared to avoid this type of problem in future. Note that initdb is no longer a libpq client: we just pull in the two source files we need directly. The patch also fixes a few places that were being sloppy about checking for an unrecognized encoding name.
Diffstat (limited to 'src/backend')
-rw-r--r--src/backend/commands/dbcommands.c6
-rw-r--r--src/backend/utils/adt/ascii.c15
-rw-r--r--src/backend/utils/adt/xml.c30
-rw-r--r--src/backend/utils/mb/encnames.c29
-rw-r--r--src/backend/utils/mb/mbutils.c8
5 files changed, 66 insertions, 22 deletions
diff --git a/src/backend/commands/dbcommands.c b/src/backend/commands/dbcommands.c
index 434e983894..ec0d02be6b 100644
--- a/src/backend/commands/dbcommands.c
+++ b/src/backend/commands/dbcommands.c
@@ -13,7 +13,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/commands/dbcommands.c,v 1.200 2007/10/12 18:55:12 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/commands/dbcommands.c,v 1.201 2007/10/13 20:18:41 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -178,12 +178,12 @@ createdb(const CreatedbStmt *stmt)
else if (IsA(dencoding->arg, String))
{
encoding_name = strVal(dencoding->arg);
- if (pg_valid_server_encoding(encoding_name) < 0)
+ encoding = pg_valid_server_encoding(encoding_name);
+ if (encoding < 0)
ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_OBJECT),
errmsg("%s is not a valid encoding name",
encoding_name)));
- encoding = pg_char_to_encoding(encoding_name);
}
else
elog(ERROR, "unrecognized node type: %d",
diff --git a/src/backend/utils/adt/ascii.c b/src/backend/utils/adt/ascii.c
index 3bd449dcc0..ce4bb6f004 100644
--- a/src/backend/utils/adt/ascii.c
+++ b/src/backend/utils/adt/ascii.c
@@ -5,7 +5,7 @@
* Portions Copyright (c) 1999-2007, PostgreSQL Global Development Group
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/utils/adt/ascii.c,v 1.30 2007/01/05 22:19:40 momjian Exp $
+ * $PostgreSQL: pgsql/src/backend/utils/adt/ascii.c,v 1.31 2007/10/13 20:18:41 tgl Exp $
*
*-----------------------------------------------------------------------
*/
@@ -117,7 +117,13 @@ Datum
to_ascii_encname(PG_FUNCTION_ARGS)
{
text *data = PG_GETARG_TEXT_P_COPY(0);
- int enc = pg_char_to_encoding(NameStr(*PG_GETARG_NAME(1)));
+ char *encname = NameStr(*PG_GETARG_NAME(1));
+ int enc = pg_char_to_encoding(encname);
+
+ if (enc < 0)
+ ereport(ERROR,
+ (errcode(ERRCODE_UNDEFINED_OBJECT),
+ errmsg("%s is not a valid encoding name", encname)));
PG_RETURN_TEXT_P(encode_to_ascii(data, enc));
}
@@ -132,6 +138,11 @@ to_ascii_enc(PG_FUNCTION_ARGS)
text *data = PG_GETARG_TEXT_P_COPY(0);
int enc = PG_GETARG_INT32(1);
+ if (!PG_VALID_ENCODING(enc))
+ ereport(ERROR,
+ (errcode(ERRCODE_UNDEFINED_OBJECT),
+ errmsg("%d is not a valid encoding code", enc)));
+
PG_RETURN_TEXT_P(encode_to_ascii(data, enc));
}
diff --git a/src/backend/utils/adt/xml.c b/src/backend/utils/adt/xml.c
index 0e656b2288..537340811c 100644
--- a/src/backend/utils/adt/xml.c
+++ b/src/backend/utils/adt/xml.c
@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/backend/utils/adt/xml.c,v 1.47 2007/09/23 21:36:42 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/utils/adt/xml.c,v 1.48 2007/10/13 20:18:41 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -127,6 +127,24 @@ XmlOptionType xmloption;
#define NAMESPACE_SQLXML "http://standards.iso.org/iso/9075/2003/sqlxml"
+#ifdef USE_LIBXML
+
+static int
+xmlChar_to_encoding(xmlChar *encoding_name)
+{
+ int encoding = pg_char_to_encoding((char *) encoding_name);
+
+ if (encoding < 0)
+ ereport(ERROR,
+ (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
+ errmsg("invalid encoding name \"%s\"",
+ (char *) encoding_name)));
+ return encoding;
+}
+
+#endif
+
+
Datum
xml_in(PG_FUNCTION_ARGS)
{
@@ -263,7 +281,9 @@ xml_recv(PG_FUNCTION_ARGS)
/* Now that we know what we're dealing with, convert to server encoding */
newstr = (char *) pg_do_encoding_conversion((unsigned char *) str,
nbytes,
- encoding ? pg_char_to_encoding((char *) encoding) : PG_UTF8,
+ encoding ?
+ xmlChar_to_encoding(encoding) :
+ PG_UTF8,
GetDatabaseEncoding());
if (newstr != str)
@@ -1084,9 +1104,9 @@ xml_parse(text *data, XmlOptionType xmloption_arg, bool preserve_whitespace, xml
utf8string = pg_do_encoding_conversion(string,
len,
- encoding
- ? pg_char_to_encoding((char *) encoding)
- : GetDatabaseEncoding(),
+ encoding ?
+ xmlChar_to_encoding(encoding) :
+ GetDatabaseEncoding(),
PG_UTF8);
xml_init();
diff --git a/src/backend/utils/mb/encnames.c b/src/backend/utils/mb/encnames.c
index 7e884fd4c5..f7ef85511c 100644
--- a/src/backend/utils/mb/encnames.c
+++ b/src/backend/utils/mb/encnames.c
@@ -2,7 +2,7 @@
* Encoding names and routines for work with it. All
* in this file is shared bedween FE and BE.
*
- * $PostgreSQL: pgsql/src/backend/utils/mb/encnames.c,v 1.34 2007/04/16 18:50:49 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/utils/mb/encnames.c,v 1.35 2007/10/13 20:18:41 tgl Exp $
*/
#ifdef FRONTEND
#include "postgres_fe.h"
@@ -12,10 +12,11 @@
#include "utils/builtins.h"
#endif
+#include <ctype.h>
#include <unistd.h>
#include "mb/pg_wchar.h"
-#include <ctype.h>
+
/* ----------
* All encoding names, sorted: *** A L P H A B E T I C ***
@@ -314,6 +315,9 @@ pg_enc2name pg_enc2name_tbl[] =
"EUC_TW", PG_EUC_TW
},
{
+ "EUC_JIS_2004", PG_EUC_JIS_2004
+ },
+ {
"UTF8", PG_UTF8
},
{
@@ -398,9 +402,6 @@ pg_enc2name pg_enc2name_tbl[] =
"WIN1257", PG_WIN1257
},
{
- "EUC_JIS_2004", PG_EUC_JIS_2004
- },
- {
"SJIS", PG_SJIS
},
{
@@ -413,10 +414,10 @@ pg_enc2name pg_enc2name_tbl[] =
"UHC", PG_UHC
},
{
- "JOHAB", PG_JOHAB
+ "GB18030", PG_GB18030
},
{
- "GB18030", PG_GB18030
+ "JOHAB", PG_JOHAB
},
{
"SHIFT_JIS_2004", PG_SHIFT_JIS_2004
@@ -455,6 +456,12 @@ pg_valid_server_encoding(const char *name)
return enc;
}
+int
+pg_valid_server_encoding_id(int encoding)
+{
+ return PG_VALID_BE_ENCODING(encoding);
+}
+
/* ----------
* Remove irrelevant chars from encoding name
* ----------
@@ -533,14 +540,14 @@ pg_char_to_encname_struct(const char *name)
* Returns encoding or -1 for error
*/
int
-pg_char_to_encoding(const char *s)
+pg_char_to_encoding(const char *name)
{
- pg_encname *p = NULL;
+ pg_encname *p;
- if (!s)
+ if (!name)
return -1;
- p = pg_char_to_encname_struct(s);
+ p = pg_char_to_encname_struct(name);
return p ? p->encoding : -1;
}
diff --git a/src/backend/utils/mb/mbutils.c b/src/backend/utils/mb/mbutils.c
index 4c7a7afca0..91f65df36a 100644
--- a/src/backend/utils/mb/mbutils.c
+++ b/src/backend/utils/mb/mbutils.c
@@ -4,7 +4,7 @@
* (currently mule internal code (mic) is used)
* Tatsuo Ishii
*
- * $PostgreSQL: pgsql/src/backend/utils/mb/mbutils.c,v 1.66 2007/09/24 16:38:24 adunstan Exp $
+ * $PostgreSQL: pgsql/src/backend/utils/mb/mbutils.c,v 1.67 2007/10/13 20:18:41 tgl Exp $
*/
#include "postgres.h"
@@ -421,6 +421,12 @@ length_in_encoding(PG_FUNCTION_ARGS)
int len = VARSIZE(string) - VARHDRSZ;
int retval;
+ if (src_encoding < 0)
+ ereport(ERROR,
+ (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
+ errmsg("invalid encoding name \"%s\"",
+ src_encoding_name)));
+
retval = pg_verify_mbstr_len(src_encoding, VARDATA(string), len, false);
PG_RETURN_INT32(retval);