mirror of
https://github.com/postgres/postgres.git
synced 2025-06-16 06:01:02 +03:00
The attached patch fixes problems with the JDBC driver handling long
null terminated strings. The FE/BE protocol sends in some cases null terminated strings to the client. The docs for the FE/BE protocol state that there is no limit on the size of a null terminated string sent to the client and a client should be coded using an expanding buffer to deal with large strings. The old code did not do this and gave an error if a null terminated string was greater than either 4 or 8K. It appears that with the advent of TOAST very long SQL statements are becoming more common, and apparently some error messages from the backend include the SQL statement thus easily exceeding the 8K limit in the old code. In fixing I also cleaned up some calls in the JDBC fastpath code that were not doing character set conversion under multibyte, and removed some methods that were no longer needed. I also removed a potential threading problem with a shared variable that was being used in Connection.java. Thanks to Steve Wampler for discovering the problem and sending the initial diffs that were the basis of this patch. thanks, --Barry
This commit is contained in:
@ -23,6 +23,7 @@ public class PG_Stream
|
||||
private Socket connection;
|
||||
private InputStream pg_input;
|
||||
private BufferedOutputStream pg_output;
|
||||
private byte[] byte_buf = new byte[8*1024];
|
||||
|
||||
BytePoolDim1 bytePoolDim1 = new BytePoolDim1();
|
||||
BytePoolDim2 bytePoolDim2 = new BytePoolDim2();
|
||||
@ -200,72 +201,45 @@ public class PG_Stream
|
||||
}
|
||||
|
||||
/**
|
||||
* Receives a null-terminated string from the backend. Maximum of
|
||||
* maxsiz bytes - if we don't see a null, then we assume something
|
||||
* has gone wrong.
|
||||
* Receives a null-terminated string from the backend. If we don't see a
|
||||
* null, then we assume something has gone wrong.
|
||||
*
|
||||
* @param maxsiz maximum length of string
|
||||
* @return string from back end
|
||||
* @exception SQLException if an I/O error occurs
|
||||
*/
|
||||
public String ReceiveString(int maxsiz) throws SQLException
|
||||
{
|
||||
byte[] rst = bytePoolDim1.allocByte(maxsiz);
|
||||
return ReceiveString(rst, maxsiz, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Receives a null-terminated string from the backend. Maximum of
|
||||
* maxsiz bytes - if we don't see a null, then we assume something
|
||||
* has gone wrong.
|
||||
*
|
||||
* @param maxsiz maximum length of string
|
||||
* @param encoding the charset encoding to use.
|
||||
* @param maxsiz maximum length of string in bytes
|
||||
* @return string from back end
|
||||
* @exception SQLException if an I/O error occurs
|
||||
*/
|
||||
public String ReceiveString(int maxsiz, String encoding) throws SQLException
|
||||
{
|
||||
byte[] rst = bytePoolDim1.allocByte(maxsiz);
|
||||
return ReceiveString(rst, maxsiz, encoding);
|
||||
}
|
||||
|
||||
/**
|
||||
* Receives a null-terminated string from the backend. Maximum of
|
||||
* maxsiz bytes - if we don't see a null, then we assume something
|
||||
* has gone wrong.
|
||||
*
|
||||
* @param rst byte array to read the String into. rst.length must
|
||||
* equal to or greater than maxsize.
|
||||
* @param maxsiz maximum length of string in bytes
|
||||
* @param encoding the charset encoding to use.
|
||||
* @return string from back end
|
||||
* @exception SQLException if an I/O error occurs
|
||||
* @exception SQLException if an I/O error occurs, or end of file
|
||||
*/
|
||||
public String ReceiveString(byte rst[], int maxsiz, String encoding)
|
||||
public String ReceiveString(String encoding)
|
||||
throws SQLException
|
||||
{
|
||||
int s = 0;
|
||||
|
||||
try
|
||||
{
|
||||
while (s < maxsiz)
|
||||
{
|
||||
byte[] rst = byte_buf;
|
||||
try {
|
||||
int buflen = rst.length;
|
||||
boolean done = false;
|
||||
while (!done) {
|
||||
while (s < buflen) {
|
||||
int c = pg_input.read();
|
||||
if (c < 0)
|
||||
throw new PSQLException("postgresql.stream.eof");
|
||||
else if (c == 0) {
|
||||
rst[s] = 0;
|
||||
done = true;
|
||||
break;
|
||||
} else
|
||||
} else {
|
||||
rst[s++] = (byte)c;
|
||||
}
|
||||
if (s >= maxsiz)
|
||||
throw new PSQLException("postgresql.stream.toomuch");
|
||||
if (s >= buflen) { // Grow the buffer
|
||||
buflen = (int)(buflen*2); // 100% bigger
|
||||
byte[] newrst = new byte[buflen];
|
||||
System.arraycopy(rst, 0, newrst, 0, s);
|
||||
rst = newrst;
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (IOException e) {
|
||||
throw new PSQLException("postgresql.stream.ioerror",e);
|
||||
}
|
||||
|
||||
String v = null;
|
||||
if (encoding == null)
|
||||
v = new String(rst, 0, s);
|
||||
|
Reference in New Issue
Block a user