You are viewing a plain text version of this content. The canonical link for it is here.
Posted to derby-commits@db.apache.org by kr...@apache.org on 2010/07/13 12:54:08 UTC

svn commit: r963673 - in /db/derby/code/branches/10.6: ./ java/client/org/apache/derby/client/am/SignedBinary.java java/client/org/apache/derby/client/net/NetStatementRequest.java java/client/org/apache/derby/client/net/Request.java

Author: kristwaa
Date: Tue Jul 13 10:54:07 2010
New Revision: 963673

URL: http://svn.apache.org/viewvc?rev=963673&view=rev
Log:
DERBY-1595: Network server fails with DRDAProtocolException if a BLOB with size 2147483647 is streamed from client

Merged fix from trunk (revisions 955540 and 958939).

Modified:
    db/derby/code/branches/10.6/   (props changed)
    db/derby/code/branches/10.6/java/client/org/apache/derby/client/am/SignedBinary.java
    db/derby/code/branches/10.6/java/client/org/apache/derby/client/net/NetStatementRequest.java
    db/derby/code/branches/10.6/java/client/org/apache/derby/client/net/Request.java

Propchange: db/derby/code/branches/10.6/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Tue Jul 13 10:54:07 2010
@@ -1,2 +1,2 @@
-/db/derby/code/trunk:938547,938796,938959,939231,940462,940469,941627,942031,942286,942476,942480,942587,944152,946794,948045,948069,951346,951366,952138,952237,952581,954344,954421,954544,954748,955001,955634,956075,956234,956445,956569,956659,957260,958163,958522,958618,959550,962716
+/db/derby/code/trunk:938547,938796,938959,939231,940462,940469,941627,942031,942286,942476,942480,942587,944152,946794,948045,948069,951346,951366,952138,952237,952581,954344,954421,954544,954748,955001,955540,955634,956075,956234,956445,956569,956659,957260,958163,958522,958618,958939,959550,962716
 /db/derby/docs/trunk:954344

Modified: db/derby/code/branches/10.6/java/client/org/apache/derby/client/am/SignedBinary.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.6/java/client/org/apache/derby/client/am/SignedBinary.java?rev=963673&r1=963672&r2=963673&view=diff
==============================================================================
--- db/derby/code/branches/10.6/java/client/org/apache/derby/client/am/SignedBinary.java (original)
+++ db/derby/code/branches/10.6/java/client/org/apache/derby/client/am/SignedBinary.java Tue Jul 13 10:54:07 2010
@@ -25,6 +25,9 @@ public class SignedBinary {
     private SignedBinary() {
     }
 
+    /** Maximum value that cen be encoded by 6 bytes (signed). */
+    public static final long MAX_LONG_6_BYTES_SIGNED = 0x7FFFFFFFFFFFL;
+
     /**
      * Unix byte-order for signed binary representations.
      */
@@ -94,6 +97,30 @@ public class SignedBinary {
     }
 
     /**
+     * Writes a Java long to a 6-byte big endian signed binary representation.
+     *
+     * @param buffer the buffer to write into
+     * @param offset the offset at which to start writing
+     * @param v the value to be written
+     *
+     * @throws IllegalArgumentException if the long value is too large to be
+     *      represented by six bytes.
+     */
+    public static void long6BytesToBigEndianBytes(byte[] buffer, int offset,
+                                                  long v) {
+        if (v > MAX_LONG_6_BYTES_SIGNED) {
+            throw new IllegalArgumentException("value too large to be " +
+                    "represented by six bytes (signed): " + v);
+        }
+        buffer[offset++] = (byte) ((v >>> 40) & 0xFF);
+        buffer[offset++] = (byte) ((v >>> 32) & 0xFF);
+        buffer[offset++] = (byte) ((v >>> 24) & 0xFF);
+        buffer[offset++] = (byte) ((v >>> 16) & 0xFF);
+        buffer[offset++] = (byte) ((v >>> 8) & 0xFF);
+        buffer[offset++] = (byte) ((v >>> 0) & 0xFF);
+    }
+
+    /**
      * Write a Java long to an 8-byte big endian signed binary representation.
      */
     public static final void longToBigEndianBytes(byte[] buffer, int offset, long v) {

Modified: db/derby/code/branches/10.6/java/client/org/apache/derby/client/net/NetStatementRequest.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.6/java/client/org/apache/derby/client/net/NetStatementRequest.java?rev=963673&r1=963672&r2=963673&view=diff
==============================================================================
--- db/derby/code/branches/10.6/java/client/org/apache/derby/client/net/NetStatementRequest.java (original)
+++ db/derby/code/branches/10.6/java/client/org/apache/derby/client/net/NetStatementRequest.java Tue Jul 13 10:54:07 2010
@@ -1746,14 +1746,10 @@ public class NetStatementRequest extends
             writeShort((short) dataLength);
         } else if (protocolTypesAndLengths[i][1] == 0x8004) {
             writeInt((int) dataLength);  // 4 bytes to encode the length
-        } else if (protocolTypesAndLengths[i][1] == 0x8006)// 6 bytes to encode the length
-        {
-            writeLong(dataLength);
-        }
-        //throw new SqlException (netAgent_.logWriter_, "0x8006 lob place holders not yet supported");
-        else if (protocolTypesAndLengths[i][1] == 0x8008)// 8 bytes to encode the length
-        {
-            writeLong(dataLength);
+        } else if (protocolTypesAndLengths[i][1] == 0x8006) {
+            writeLong6Bytes(dataLength); // 6 bytes to encode the length
+        } else if (protocolTypesAndLengths[i][1] == 0x8008) {
+            writeLong(dataLength); // 8 bytes to encode the length
         }
 
         if (dataLength != 0) {

Modified: db/derby/code/branches/10.6/java/client/org/apache/derby/client/net/Request.java
URL: http://svn.apache.org/viewvc/db/derby/code/branches/10.6/java/client/org/apache/derby/client/net/Request.java?rev=963673&r1=963672&r2=963673&view=diff
==============================================================================
--- db/derby/code/branches/10.6/java/client/org/apache/derby/client/net/Request.java (original)
+++ db/derby/code/branches/10.6/java/client/org/apache/derby/client/net/Request.java Tue Jul 13 10:54:07 2010
@@ -21,18 +21,19 @@
 package org.apache.derby.client.net;
 
 import org.apache.derby.client.am.DateTime;
+import org.apache.derby.client.am.DateTimeValue;
 import org.apache.derby.client.am.DisconnectException;
 import org.apache.derby.client.am.ClientMessageId;
 import org.apache.derby.client.am.SqlException;
 import org.apache.derby.shared.common.reference.SQLState;
+import org.apache.derby.shared.common.sanity.SanityManager;
 import org.apache.derby.iapi.reference.DRDAConstants;
 
 import java.io.BufferedInputStream;
+import java.io.IOException;
 import java.io.ObjectOutputStream;
 import java.io.UnsupportedEncodingException;
 
-import java.io.IOException;
-import org.apache.derby.client.am.DateTimeValue;
 
 public class Request {
 
@@ -245,11 +246,11 @@ public class Request {
 	final void writeScalarStream(boolean chained,
                                  boolean chainedWithSameCorrelator,
                                  int codePoint,
-                                 int length,
+                                 long length,
                                  java.io.InputStream in,
                                  boolean writeNullByte,
                                  int parameterIndex) throws DisconnectException, SqlException {
-		
+
 		if (netAgent_.netConnection_.getSecurityMechanism() == NetConfiguration.SECMEC_EUSRIDDTA ||
 			netAgent_.netConnection_.getSecurityMechanism() == NetConfiguration.SECMEC_EUSRPWDDTA) {
             // DERBY-4706
@@ -297,7 +298,7 @@ public class Request {
 	final private void writePlainScalarStream(boolean chained,
                                               boolean chainedWithSameCorrelator,
                                               int codePoint,
-                                              int length,
+                                              long length,
                                               java.io.InputStream in,
                                               boolean writeNullByte,
                                               int parameterIndex) throws DisconnectException, SqlException {
@@ -309,19 +310,16 @@ public class Request {
 
         // If the Derby specific status byte is sent, the number of bytes to
         // send differs from the number of bytes to read (off by one byte).
-		int leftToRead = length;
-        int bytesToSend = writeEXTDTAStatusByte ? leftToRead + 1 : leftToRead;
+        long leftToRead = length;
+        long bytesToSend = writeEXTDTAStatusByte ? leftToRead + 1 : leftToRead;
 		int extendedLengthByteCount = prepScalarStream(chained,
 													   chainedWithSameCorrelator,
 													   writeNullByte,
                                                        bytesToSend);
-		int bytesToRead;
-				
-		if (writeNullByte) {
-            bytesToRead = Math.min(bytesToSend, DssConstants.MAX_DSS_LEN - 6 - 4 - 1 - extendedLengthByteCount);
-		} else {
-            bytesToRead = Math.min(bytesToSend, DssConstants.MAX_DSS_LEN - 6 - 4 - extendedLengthByteCount);
-		}
+        int nullIndicatorSize = writeNullByte ? 1 : 0;
+        int dssMaxDataLength = DssConstants.MAX_DSS_LEN - 6 - 4 -
+                nullIndicatorSize - extendedLengthByteCount;
+        int bytesToRead = (int)Math.min(bytesToSend, dssMaxDataLength);
 
         // If we are sending the status byte and we can send the user value as
         // one DSS, correct for the status byte (otherwise we read one byte too
@@ -519,11 +517,11 @@ public class Request {
                                  boolean writeNullByte,
                                  int parameterIndex) throws DisconnectException, 
                                                             SqlException{
-        
+
         writeScalarStream(chained,
                           chainedWithSameCorrelator,
                           codePoint,
-                          length * 2,
+                          length * 2L,
                           EncodedInputStream.createUTF16BEStream(r),
                           writeNullByte,
                           parameterIndex);
@@ -553,21 +551,15 @@ public class Request {
     protected final int prepScalarStream(boolean chained,
                                          boolean chainedWithSameCorrelator,
                                          boolean writeNullByte,
-                                         int leftToRead) throws DisconnectException {
-        int extendedLengthByteCount;
-
-        int nullIndicatorSize = 0;
-        if (writeNullByte) {
-            // leftToRead is cast to (long) on the off chance that +4+1 pushes it outside the range of int
-            extendedLengthByteCount = calculateExtendedLengthByteCount((long) leftToRead + 4 + 1);
-            nullIndicatorSize = 1;
-        } else {
-            extendedLengthByteCount = calculateExtendedLengthByteCount(leftToRead + 4);
-        }
+                                         long leftToRead)
+            throws DisconnectException {
+        int nullIndicatorSize = writeNullByte ? 1 : 0;
+        int extendedLengthByteCount = calculateExtendedLengthByteCount(
+                    leftToRead + 4 + nullIndicatorSize);
 
         // flush the existing DSS segment if this stream will not fit in the send buffer
-        // leftToRead is cast to (long) on the off chance that +4+1 pushes it outside the range of int
-        if (10 + extendedLengthByteCount + nullIndicatorSize + (long) leftToRead + offset_ > DssConstants.MAX_DSS_LEN) {
+        if ((10 + extendedLengthByteCount + nullIndicatorSize +
+                leftToRead + offset_) > DssConstants.MAX_DSS_LEN) {
             try {
                 if (simpleDssFinalize) {
                     finalizeDssLength();
@@ -621,7 +613,7 @@ public class Request {
 
     // Writes out a scalar stream DSS segment, along with DSS continuation headers,
     // if necessary.
-    protected final int flushScalarStreamSegment(int leftToRead,
+    protected final int flushScalarStreamSegment(long leftToRead,
                                                  int bytesToRead) throws DisconnectException {
         int newBytesToRead = bytesToRead;
 
@@ -638,7 +630,7 @@ public class Request {
             dssLengthLocation_ = offset_;
             bytes_[offset_++] = (byte) (0xff);
             bytes_[offset_++] = (byte) (0xff);
-            newBytesToRead = Math.min(leftToRead, 32765);
+            newBytesToRead = (int)Math.min(leftToRead, 32765L);
         }
 
         return newBytesToRead;
@@ -675,7 +667,7 @@ public class Request {
      *      {@code writeStatus} is {@code false}
      * @throws DisconnectException if flushing the buffer fails
      */
-    protected final void padScalarStreamForError(int leftToRead,
+    protected final void padScalarStreamForError(long leftToRead,
                                                  int bytesToRead,
                                                  boolean writeStatus,
                                                  byte status)
@@ -1365,6 +1357,20 @@ public class Request {
         offset_ += 4;
     }
 
+    /**
+     * Writes a long into the buffer, using six bytes.
+     *
+     * @param v the value to write
+     * @throws IllegalArgumentException if the long value is too large to be
+     *      represented by six bytes.
+     */
+    final void writeLong6Bytes(long v) {
+        ensureLength(offset_ + 6);
+        org.apache.derby.client.am.SignedBinary.long6BytesToBigEndianBytes(
+                bytes_, offset_, v);
+        offset_ += 6;
+    }
+
     // insert a java long into the buffer.
     final void writeLong(long v) {
         ensureLength(offset_ + 8);
@@ -1563,24 +1569,22 @@ public class Request {
     }
 
     private void buildLengthAndCodePointForLob(int codePoint,
-                                               int leftToRead,
+                                               long leftToRead,
                                                boolean writeNullByte,
                                                int extendedLengthByteCount) throws DisconnectException {
+        int nullIndicatorSize = writeNullByte ? 1 : 0;
         if (extendedLengthByteCount > 0) {
             // method should never ensure length
             writeLengthCodePoint(0x8004 + extendedLengthByteCount, codePoint);
-
-            if (writeNullByte) {
-                writeExtendedLengthBytes(extendedLengthByteCount, leftToRead + 1);
-            } else {
-                writeExtendedLengthBytes(extendedLengthByteCount, leftToRead);
-            }
+            writeExtendedLengthBytes(
+                    extendedLengthByteCount, leftToRead + nullIndicatorSize);
         } else {
-            if (writeNullByte) {
-                writeLengthCodePoint(leftToRead + 4 + 1, codePoint);
-            } else {
-                writeLengthCodePoint(leftToRead + 4, codePoint);
+            if (SanityManager.DEBUG) {
+                SanityManager.ASSERT(leftToRead +4 + nullIndicatorSize <=
+                        DssConstants.MAX_DSS_LEN);
             }
+            writeLengthCodePoint((int)(leftToRead + 4 + nullIndicatorSize),
+                    codePoint);
         }
 
         // write the null byte, if necessary