psql-utf8bom_20091117.patch
application/octet-stream
Filename: psql-utf8bom_20091117.patch
Type: application/octet-stream
Part: 0
Message:
Re: UTF8 with BOM support in psql
Patch
Format: unified
| File | + | − |
|---|---|---|
| src/bin/psql/mainloop.c | 47 | 7 |
Index: src/bin/psql/mainloop.c
===================================================================
--- src/bin/psql/mainloop.c (HEAD)
+++ src/bin/psql/mainloop.c (working copy)
Index: src/bin/psql/mainloop.c
@@ -13,8 +13,33 @@
#include "common.h"
#include "input.h"
#include "settings.h"
+#include "mb/pg_wchar.h"
+static bool
+is_valid_encoding(int expected_encoding, const char *str)
+{
+ const char * s;
+
+ if (expected_encoding == PG_SQL_ASCII)
+ return true; /* always accepted */
+
+ if (expected_encoding == pset.encoding)
+ return true; /* matched */
+
+ for (s = str; *s; s++)
+ {
+ if (IS_HIGHBIT_SET(*s))
+ {
+ psql_error("explicit encoding is required: %s expected\n",
+ pg_encoding_to_char(expected_encoding));
+ return false;
+ }
+ }
+
+ return true; /* accepted because all characters are in ascii */
+}
+
/*
* Main processing loop for reading lines of input
* and sending them to the backend.
@@ -36,6 +61,7 @@
int added_nl_pos;
bool success;
bool line_saved_in_history;
+ int expected_encoding = PG_SQL_ASCII;
volatile int successResult = EXIT_SUCCESS;
volatile backslashResult slashCmdStatus = PSQL_CMD_UNKNOWN;
volatile promptStatus_t prompt_status = PROMPT_READY;
@@ -134,8 +160,17 @@
else
{
line = gets_fromFile(source);
- if (!line && ferror(source))
- successResult = EXIT_FAILURE;
+ if (!line)
+ {
+ if (ferror(source))
+ successResult = EXIT_FAILURE;
+ }
+ else if (pset.lineno == 0 && strncmp(line, "\xef\xbb\xbf", 3) == 0)
+ {
+ /* trim BOM sequence to whitespaces */
+ memmove(line, line + 3, strlen(line + 3) + 1);
+ expected_encoding = PG_UTF8;
+ }
}
/*
@@ -248,7 +283,8 @@
}
/* execute query */
- success = SendQuery(query_buf->data);
+ success = is_valid_encoding(expected_encoding, query_buf->data) &&
+ SendQuery(query_buf->data);
slashCmdStatus = success ? PSQL_CMD_SEND : PSQL_CMD_ERROR;
/* transfer query to previous_buf by pointer-swapping */
@@ -266,6 +302,7 @@
else if (scan_result == PSCAN_BACKSLASH)
{
/* handle backslash command */
+ PQExpBuffer buf;
/*
* If we added a newline to query_buf, and nothing else has
@@ -292,9 +329,11 @@
}
/* execute backslash command */
- slashCmdStatus = HandleSlashCmds(scan_state,
- query_buf->len > 0 ?
- query_buf : previous_buf);
+ buf = query_buf->len > 0 ? query_buf : previous_buf;
+ if (is_valid_encoding(expected_encoding, buf->data))
+ slashCmdStatus = HandleSlashCmds(scan_state, buf);
+ else
+ slashCmdStatus = PSQL_CMD_ERROR;
success = slashCmdStatus != PSQL_CMD_ERROR;
@@ -378,7 +417,8 @@
pg_send_history(history_buf);
/* execute query */
- success = SendQuery(query_buf->data);
+ success = is_valid_encoding(expected_encoding, query_buf->data) &&
+ SendQuery(query_buf->data);
if (!success && die_on_error)
successResult = EXIT_USER;