postgresql-jdbc.git / summary / log / commit / refs
commit 82067330ba1d5cdf0bfe1902a16d412f3a08d7d2
Author: Kris Jurka <books@ejurka.com>
Date: Sat Jul 17 07:39:43 2004 +0000
I managed to completely mangle decodeUTF8() in my changes that went into
build 303. It would incorrectly decode any multibyte UTF8
representation. Don't know what I was thinking there..
Anyway, here is a patch to repair the damage, and a testcase to check
that the driver reads/writes unicode strings correctly.
Thanks to Dario Fassi for helping diagnose this.
Oliver Jowett
org/postgresql/core/Encoding.java | 8 +-
.../test/jdbc2/DatabaseEncodingTest.java | 100 +++++++++++++++++++++
org/postgresql/test/jdbc2/Jdbc2TestSuite.java | 1 +
3 files changed, 106 insertions(+), 3 deletions(-)
diff --git a/org/postgresql/core/Encoding.java b/org/postgresql/core/Encoding.java
index 3cf9b607..c019c5d1 100644
--- a/org/postgresql/core/Encoding.java
+++ b/org/postgresql/core/Encoding.java
@@ -286,11 +286,13 @@ public class Encoding
// Length 1: \u00000 .. \u0007f
} else if (ch < 0xe0) {
// Length 2: \u00080 .. \u007ff
- ch = ch | ((data[in++] & 0x7f) << 6);
+ ch = ((ch & 0x1f) << 6);
+ ch = ch | (data[in++] & 0x3f);
} else {
// Length 3: \u00800 .. \u0ffff
- ch = ch | ((data[in++] & 0x7f) << 12);
- ch = ch | ((data[in++] & 0x7f) << 6);
+ ch = ((ch & 0x0f) << 12);
+ ch = ch | ((data[in++] & 0x3f) << 6);
+ ch = ch | (data[in++] & 0x3f);
}
cdata[out++] = (char)ch;
}
diff --git a/org/postgresql/test/jdbc2/DatabaseEncodingTest.java b/org/postgresql/test/jdbc2/DatabaseEncodingTest.java
new file mode 100644
index 00000000..bc5eb62c
--- /dev/null
+++ b/org/postgresql/test/jdbc2/DatabaseEncodingTest.java
@@ -0,0 +1,100 @@
+package org.postgresql.test.jdbc2;
+
+import org.postgresql.test.TestUtil;
+import junit.framework.TestCase;
+import java.sql.*;
+
+/*
+ * Test case for Dario's encoding problems.
+ */
+public class DatabaseEncodingTest extends TestCase
+{
+ private Connection con;
+
+ public DatabaseEncodingTest(String name)
+ {
+ super(name);
+ }
+
+ private static final int STEP = 30;
+
+ // Set up the fixture for this testcase: a connection to a database with
+ // a table for this test.
+ protected void setUp() throws Exception
+ {
+ con = TestUtil.openDB();
+ TestUtil.createTable(con,
+ "testdbencoding",
+ "unicode_ordinal integer primary key not null, unicode_string varchar(" + STEP + ")");
+ }
+
+ // Tear down the fixture for this test case.
+ protected void tearDown() throws Exception
+ {
+ TestUtil.dropTable(con, "testdbencoding");
+ TestUtil.closeDB(con);
+ }
+
+ private static String dumpString(String s) {
+ StringBuffer sb = new StringBuffer(s.length() * 6);
+ for (int i = 0; i < s.length(); ++i) {
+ sb.append("\\u");
+ char c = s.charAt(i);
+ sb.append(Integer.toHexString((c>>12)&15));
+ sb.append(Integer.toHexString((c>>8)&15));
+ sb.append(Integer.toHexString((c>>4)&15));
+ sb.append(Integer.toHexString(c&15));
+ }
+ return sb.toString();
+ }
+
+ public void testEncoding() throws Exception {
+ // Check that we have a UNICODE server encoding, or we must skip this test.
+ Statement stmt = con.createStatement();
+ ResultSet rs = stmt.executeQuery("SELECT getdatabaseencoding()");
+ assertTrue(rs.next());
+ if (!"UNICODE".equals(rs.getString(1))) {
+ rs.close();
+ return; // not a UNICODE database.
+ }
+
+ rs.close();
+
+ con.setAutoCommit(false); // Go faster!
+
+ // Create data.
+ // NB: we only test up to d800 as code points above that are
+ // reserved for surrogates in UTF-16
+ PreparedStatement insert = con.prepareStatement("INSERT INTO testdbencoding(unicode_ordinal, unicode_string) VALUES (?,?)");
+ for (int i = 1; i < 0xd800; i += STEP) {
+ int count = (i+STEP) > 0xd800 ? 0xd800-i : STEP;
+ char[] testChars = new char[count];
+ for (int j = 0; j < count; ++j)
+ testChars[j] = (char)(i+j);
+
+ String testString = new String(testChars);
+
+ insert.setInt(1, i);
+ insert.setString(2, testString);
+ assertEquals(1, insert.executeUpdate());
+ }
+
+ con.commit();
+
+ // Check data.
+ rs = stmt.executeQuery("SELECT unicode_ordinal, unicode_string FROM testdbencoding ORDER BY unicode_ordinal");
+ for (int i = 1; i < 0xd800; i += STEP) {
+ assertTrue(rs.next());
+ assertEquals(i, rs.getInt(1));
+
+ int count = (i+STEP) > 0xd800 ? 0xd800-i : STEP;
+ char[] testChars = new char[count];
+ for (int j = 0; j < count; ++j)
+ testChars[j] = (char)(i+j);
+
+ String testString = new String(testChars);
+
+ assertEquals(dumpString(testString), dumpString(rs.getString(2)));
+ }
+ }
+}
diff --git a/org/postgresql/test/jdbc2/Jdbc2TestSuite.java b/org/postgresql/test/jdbc2/Jdbc2TestSuite.java
index cd4af026..7ae92ea2 100644
--- a/org/postgresql/test/jdbc2/Jdbc2TestSuite.java
+++ b/org/postgresql/test/jdbc2/Jdbc2TestSuite.java
@@ -59,6 +59,7 @@ public class Jdbc2TestSuite extends TestSuite
suite.addTestSuite(JBuilderTest.class);
suite.addTestSuite(MiscTest.class);
suite.addTestSuite(NotifyTest.class);
+ suite.addTestSuite(DatabaseEncodingTest.class);
// Fastpath/LargeObject
suite.addTestSuite(BlobTest.class);
[parent: 6e294c7dd8fc]