aboutsummaryrefslogtreecommitdiff
path: root/src/backend/utils/mb/wchar.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/utils/mb/wchar.c')
-rw-r--r--src/backend/utils/mb/wchar.c94
1 files changed, 47 insertions, 47 deletions
diff --git a/src/backend/utils/mb/wchar.c b/src/backend/utils/mb/wchar.c
index d22f7b88276..909a2ae8670 100644
--- a/src/backend/utils/mb/wchar.c
+++ b/src/backend/utils/mb/wchar.c
@@ -1,7 +1,7 @@
/*
* conversion functions between pg_wchar and multibyte streams.
* Tatsuo Ishii
- * $Id: wchar.c,v 1.31 2003/01/11 06:55:11 ishii Exp $
+ * $Id: wchar.c,v 1.32 2003/07/27 04:53:11 tgl Exp $
*
* WIN1250 client encoding updated by Pavel Behal
*
@@ -606,78 +606,78 @@ pg_encoding_max_length(int encoding)
}
#ifndef FRONTEND
+
/*
* Verify mbstr to make sure that it has a valid character sequence.
- * mbstr is not necessarily NULL terminated. length of mbstr is
- * specified by len. If an error was found, returns an error message.
- * Note that the message is kept in a static buffer, the next invocation
- * might break the message.
- * If no error was found, this function returns NULL.
+ * mbstr is not necessarily NULL terminated; length of mbstr is
+ * specified by len.
+ *
+ * If OK, return TRUE. If a problem is found, return FALSE when noError is
+ * true; when noError is false, ereport() a descriptive message.
*/
-char *
-pg_verifymbstr(const unsigned char *mbstr, int len)
+bool
+pg_verifymbstr(const unsigned char *mbstr, int len, bool noError)
{
int l;
- int i,
- j;
- static char buf[256];
- int slen = 0;
+ int i;
+ int encoding;
- /* we do not check single byte encodings */
+ /* we do not need any check in single-byte encodings */
if (pg_database_encoding_max_length() <= 1)
- return NULL;
+ return true;
+
+ encoding = GetDatabaseEncoding();
while (len > 0 && *mbstr)
{
/* special UTF-8 check */
- if (GetDatabaseEncoding() == PG_UTF8 &&
- (*mbstr & 0xf8) == 0xf0)
+ if (encoding == PG_UTF8 && (*mbstr & 0xf8) == 0xf0)
{
- snprintf(buf, sizeof(buf), "Unicode >= 0x10000 is not supported");
- return (buf);
+ if (noError)
+ return false;
+ ereport(ERROR,
+ (errcode(ERRCODE_CHARACTER_NOT_IN_REPERTOIRE),
+ errmsg("UNICODE characters >= 0x10000 are not supported")));
}
l = pg_mblen(mbstr);
- /* multibyte letter? */
- if (l > 1)
+ for (i = 1; i < l; i++)
{
- for (i = 1; i < l; i++)
+ /*
+ * we expect that every multibyte char consists of bytes
+ * having the 8th bit set
+ */
+ if (i >= len || (mbstr[i] & 0x80) == 0)
{
- if (i > len || *(mbstr + i) == '\0' ||
+ char buf[8 * 2 + 1];
+ char *p = buf;
+ int j,
+ jlimit;
+
+ if (noError)
+ return false;
- /*
- * we assume that every multibyte letter consists of bytes
- * being the 8th bit set
- */
- ((*(mbstr + i) & 0x80) == 0))
+ jlimit = Min(l, len);
+ jlimit = Min(jlimit, 8); /* prevent buffer overrun */
+
+ for (j = 0; j < jlimit; j++)
{
- int remains = sizeof(buf);
- char *p = buf;
-
- slen = snprintf(p, remains, "Invalid %s character sequence found (0x",
- GetDatabaseEncodingName());
- p += slen;
- remains -= slen;
-
- i = ((*(mbstr + i) & 0x80) == 0) ? l : i;
-
- for (j = 0; j < i; j++)
- {
- slen = snprintf(p, remains, "%02x",
- *(mbstr + j));
- p += slen;
- remains -= slen;
- }
- snprintf(p, remains, ")");
- return (buf);
+ p += sprintf(p, "%02x", mbstr[j]);
}
+
+ ereport(ERROR,
+ (errcode(ERRCODE_CHARACTER_NOT_IN_REPERTOIRE),
+ errmsg("invalid %s character sequence: 0x%s",
+ GetDatabaseEncodingName(), buf)));
}
}
+
len -= l;
mbstr += l;
}
- return NULL;
+
+ return true;
}
/*