Here's the patch..
Robert
Robert Fleming wrote:
<snip>
Anyway, I would like to point out this wiki note:
http://www.dbmail.org/dokuwiki/doku.php?id=unicode_postgresql_database
to whomever is working on bug 218:
http://www.dbmail.org/mantis/view.php?id=218
In response to the last note there, I would say that this issue *will*
persist, because basically dbmail is trying to submit arbitrary octet
sequences as values for columns of type "text", and Postgres will
always try to interpret the input according to the defined encoding
for that database. I have patches to fix this if there is interest.
The patches change the column type to "bytea", which tells Postgres to
not try to decode the text, but just store it.
diff -ru ../dbmail-2.0.7/db.c ./db.c
--- ../dbmail-2.0.7/db.c 2005-08-19 07:30:42.000000000 -0700
+++ ./db.c 2005-10-29 16:47:45.000000000 -0700
@@ -1119,7 +1119,8 @@
blocktype_t is_header)
{
char *escaped_query = NULL;
- unsigned maxesclen = (READ_BLOCK_SIZE + 1) * 2 + DEF_QUERYSIZE;
+ // worst case: all bytes must be escaped; PostgreSQL bytea e.g. "\\176"
+ const unsigned maxesclen = (READ_BLOCK_SIZE + 1) * 5 + DEF_QUERYSIZE;
unsigned startlen = 0;
unsigned esclen = 0;
@@ -1884,7 +1885,7 @@
}
snprintf(query, DEF_QUERYSIZE,
- "SELECT messageblk FROM dbmail_messageblks "
+ "SELECT encode(messageblk, 'escape') AS messageblk FROM dbmail_messageblks "
"WHERE physmessage_id='%llu' "
"ORDER BY messageblk_idnr ASC", physmessage_id);
trace(TRACE_DEBUG, "%s,%s: executing query [%s]",
@@ -3915,7 +3916,7 @@
list_init(hdrlist);
snprintf(query, DEF_QUERYSIZE,
- "SELECT messageblk "
+ "SELECT encode(messageblk, 'escape') AS messageblk "
"FROM dbmail_messageblks blk, dbmail_messages msg "
"WHERE blk.physmessage_id = msg.physmessage_id "
"AND msg.message_idnr = '%llu' "
diff -ru ../dbmail-2.0.7/dbmsgbuf.c ./dbmsgbuf.c
--- ../dbmail-2.0.7/dbmsgbuf.c 2005-08-19 07:30:42.000000000 -0700
+++ ./dbmsgbuf.c 2005-10-27 23:55:25.000000000 -0700
@@ -148,7 +148,7 @@
int db_init_fetch_headers(u64_t msg_idnr)
{
- char *query_template = "SELECT block.messageblk "
+ char *query_template = "SELECT encode(block.messageblk, 'escape') AS messageblk "
"FROM dbmail_messageblks block, dbmail_messages msg "
"WHERE block.physmessage_id = msg.physmessage_id "
"AND dbmail_messageblks.is_header = 1"
@@ -159,7 +159,7 @@
}
int db_init_fetch_message(u64_t msg_idnr)
{
- char *query_template = "SELECT block.messageblk "
+ char *query_template = "SELECT encode(block.messageblk, 'escape') AS messageblk "
"FROM dbmail_messageblks block, dbmail_messages msg "
"WHERE block.physmessage_id = msg.physmessage_id "
"AND msg.message_idnr = '%llu' "
@@ -372,7 +372,7 @@
}
snprintf(query, DEF_QUERYSIZE,
- "SELECT block.messageblk "
+ "SELECT encode(block.messageblk, 'escape') AS messageblk "
"FROM dbmail_messageblks block, dbmail_messages msg "
"WHERE block.physmessage_id = msg.physmessage_id "
"AND msg.message_idnr = '%llu' "
diff -ru ../dbmail-2.0.7/dbsearch.c ./dbsearch.c
--- ../dbmail-2.0.7/dbsearch.c 2005-08-19 07:30:42.000000000 -0700
+++ ./dbsearch.c 2005-10-27 23:57:14.000000000 -0700
@@ -456,7 +456,7 @@
}
snprintf(query, DEF_QUERYSIZE,
- "SELECT block.messageblk "
+ "SELECT encode(block.messageblk, 'escape') AS messageblk "
"FROM dbmail_messageblks block, dbmail_messages msg "
"WHERE block.physmessage_id = msg.physmessage_id "
"AND msg.message_idnr = '%llu' "
diff -ru ../dbmail-2.0.7/pgsql/dbpgsql.c ./pgsql/dbpgsql.c
--- ../dbmail-2.0.7/pgsql/dbpgsql.c 2005-08-19 07:30:42.000000000 -0700
+++ ./pgsql/dbpgsql.c 2005-10-28 00:00:21.000000000 -0700
@@ -240,7 +247,11 @@
unsigned long db_escape_direct(char *to,
const char *from, unsigned long length)
{
- return PQescapeString(to, from, length);
+ size_t to_length;
+ char* to2 = PQescapeBytea(from, length, &to_length);
+ strcpy(to, to2); // FIXME: strncpy, but n would need to be passed in
+ PQfreemem(to2);
+ return strlen(to);
}
int db_do_cleanup(const char **tables, int num_tables)
diff -ru ../dbmail-2.0.7/sql/postgresql/create_tables.pgsql ./sql/postgresql/create_tables.pgsql
--- ../dbmail-2.0.7/sql/postgresql/create_tables.pgsql 2005-09-05 07:52:57.000000000 -0700
+++ ./sql/postgresql/create_tables.pgsql 2005-10-28 00:49:34.000000000 -0700
@@ -132,7 +135,7 @@
messageblk_idnr INT8 DEFAULT nextval('dbmail_messageblk_idnr_seq'),
physmessage_id INT8 REFERENCES dbmail_physmessage(id)
ON DELETE CASCADE,
- messageblk TEXT NOT NULL,
+ messageblk bytea NOT NULL,
blocksize INT8 DEFAULT '0' NOT NULL,
is_header INT2 DEFAULT '0' NOT NULL,
PRIMARY KEY (messageblk_idnr)