8153490: Cannot setBytes() if incoming buffer's length is bigger than number of elements we want to insert.

Reviewed-by: lancea
This commit is contained in:
Mitsuru Kariya 2021-10-28 15:56:17 +00:00 committed by Lance Andersen
parent cb989cf3a1
commit 63b9f8c0da
4 changed files with 257 additions and 98 deletions

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2003, 2020, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2003, 2021, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -298,22 +298,21 @@ public class SerialBlob implements Blob, Serializable, Cloneable {
}
/**
* Writes the given array of bytes to the <code>BLOB</code> value that
* this <code>Blob</code> object represents, starting at position
* <code>pos</code>, and returns the number of bytes written.
* Writes the given array of bytes to the {@code BLOB} value that
* this {@code Blob} object represents, starting at position
* {@code pos}, and returns the number of bytes written.
*
* @param pos the position in the SQL <code>BLOB</code> value at which
* to start writing. The first position is <code>1</code>;
* must not be less than <code>1</code> nor greater than
* the length of this <code>SerialBlob</code> object.
* @param bytes the array of bytes to be written to the <code>BLOB</code>
* value that this <code>Blob</code> object represents
* @param pos the position in the SQL {@code BLOB} value at which
* to start writing. The first position is {@code 1};
* must not be less than {@code 1} nor greater than
* the length+1 of this {@code SerialBlob} object.
* @param bytes the array of bytes to be written to the {@code BLOB}
* value that this {@code Blob} object represents
* @return the number of bytes written
* @throws SerialException if there is an error accessing the
* <code>BLOB</code> value; or if an invalid position is set; if an
* invalid offset value is set;
* {@code BLOB} value; or if an invalid position is set;
* if {@code free} had previously been called on this object
* @throws SQLException if there is an error accessing the <code>BLOB</code>
* @throws SQLException if there is an error accessing the {@code BLOB}
* value from the database
* @see #getBytes
*/
@ -323,33 +322,33 @@ public class SerialBlob implements Blob, Serializable, Cloneable {
}
/**
* Writes all or part of the given <code>byte</code> array to the
* <code>BLOB</code> value that this <code>Blob</code> object represents
* Writes all or part of the given {@code byte} array to the
* {@code BLOB} value that this {@code Blob} object represents
* and returns the number of bytes written.
* Writing starts at position <code>pos</code> in the <code>BLOB</code>
* value; <i>len</i> bytes from the given byte array are written.
* Writing starts at position {@code pos} in the {@code BLOB}
* value; {@code length} bytes from the given byte array are written.
*
* @param pos the position in the <code>BLOB</code> object at which
* to start writing. The first position is <code>1</code>;
* must not be less than <code>1</code> nor greater than
* the length of this <code>SerialBlob</code> object.
* @param bytes the array of bytes to be written to the <code>BLOB</code>
* @param pos the position in the {@code BLOB} object at which
* to start writing. The first position is {@code 1};
* must not be less than {@code 1} nor greater than
* the length+1 of this {@code SerialBlob} object.
* @param bytes the array of bytes to be written to the {@code BLOB}
* value
* @param offset the offset in the <code>byte</code> array at which
* to start reading the bytes. The first offset position is
* <code>0</code>; must not be less than <code>0</code> nor greater
* than the length of the <code>byte</code> array
* @param offset the offset into the array {@code byte}s at which
* to start reading the bytes to be set. The first offset position is
* {@code 0}; must not be less than {@code 0} nor greater
* than the length of the array {@code byte}s
* @param length the number of bytes to be written to the
* <code>BLOB</code> value from the array of bytes <i>bytes</i>.
* {@code BLOB} value from the array of bytes {@code byte}s
*
* @return the number of bytes written
* @throws SerialException if there is an error accessing the
* <code>BLOB</code> value; if an invalid position is set; if an
* invalid offset value is set; if number of bytes to be written
* is greater than the <code>SerialBlob</code> length; or the combined
* values of the length and offset is greater than the Blob buffer;
* {@code BLOB} value; if an invalid position is set; if an
* invalid offset value is set; or the combined values of the
* {@code length} and {@code offset} is greater than the length of
* {@code byte}s;
* if {@code free} had previously been called on this object
* @throws SQLException if there is an error accessing the <code>BLOB</code>
* @throws SQLException if there is an error accessing the {@code BLOB}
* value from the database.
* @see #getBytes
*/
@ -361,26 +360,34 @@ public class SerialBlob implements Blob, Serializable, Cloneable {
throw new SerialException("Invalid offset in byte array set");
}
if (pos < 1 || pos > this.length()) {
if (length < 0) {
throw new SerialException("Invalid arguments: length cannot be "
+ "negative");
}
if (pos < 1 || pos > len + 1) {
throw new SerialException("Invalid position in BLOB object set");
}
if ((long)(length) > origLen) {
throw new SerialException("Buffer is not sufficient to hold the value");
}
if ((length + offset) > bytes.length) {
if (length > bytes.length - offset) {
throw new SerialException("Invalid OffSet. Cannot have combined offset " +
"and length that is greater that the Blob buffer");
"and length that is greater than the length of bytes");
}
int i = 0;
pos--; // correct to array indexing
while ( i < length || (offset + i +1) < (bytes.length-offset) ) {
this.buf[(int)pos + i] = bytes[offset + i ];
i++;
if (pos - 1 + length > Integer.MAX_VALUE) {
throw new SerialException("Invalid length. Cannot have combined pos " +
"and length that is greater than Integer.MAX_VALUE");
}
return i;
pos--; // correct to array indexing
if (pos + length > len) {
len = pos + length;
byte[] newbuf = new byte[(int)len];
System.arraycopy(buf, 0, newbuf, 0, (int)pos);
buf = newbuf;
}
System.arraycopy(bytes, offset, buf, (int)pos, length);
return length;
}
/**

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2003, 2020, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2003, 2021, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -361,22 +361,19 @@ public class SerialClob implements Clob, Serializable, Cloneable {
}
/**
* Writes the given Java <code>String</code> to the <code>CLOB</code>
* value that this <code>SerialClob</code> object represents, at the position
* <code>pos</code>.
* Writes the given Java {@code String} to the {@code CLOB}
* value that this {@code SerialClob} object represents, at the position
* {@code pos}.
*
* @param pos the position at which to start writing to the <code>CLOB</code>
* value that this <code>SerialClob</code> object represents; the first
* position is <code>1</code>; must not be less than <code>1</code> nor
* greater than the length of this <code>SerialClob</code> object
* @param str the string to be written to the <code>CLOB</code>
* value that this <code>SerialClob</code> object represents
* @param pos the position at which to start writing to the {@code CLOB}
* value that this {@code SerialClob} object represents; the first
* position is {@code 1}; must not be less than {@code 1} nor
* greater than the length+1 of this {@code SerialClob} object
* @param str the string to be written to the {@code CLOB}
* value that this {@code SerialClob} object represents
* @return the number of characters written
* @throws SerialException if there is an error accessing the
* <code>CLOB</code> value; if an invalid position is set; if an
* invalid offset value is set; if number of bytes to be written
* is greater than the <code>SerialClob</code> length; or the combined
* values of the length and offset is greater than the Clob buffer;
* {@code CLOB} value; if an invalid position is set;
* if the {@code free} method had been previously called on this object
*/
public int setString(long pos, String str) throws SerialException {
@ -384,58 +381,66 @@ public class SerialClob implements Clob, Serializable, Cloneable {
}
/**
* Writes <code>len</code> characters of <code>str</code>, starting
* at character <code>offset</code>, to the <code>CLOB</code> value
* that this <code>Clob</code> represents.
* Writes {@code len} characters of {@code str}, starting
* at character {@code offset}, to the {@code CLOB} value
* that this {@code Clob} represents.
*
* @param pos the position at which to start writing to the <code>CLOB</code>
* value that this <code>SerialClob</code> object represents; the first
* position is <code>1</code>; must not be less than <code>1</code> nor
* greater than the length of this <code>SerialClob</code> object
* @param str the string to be written to the <code>CLOB</code>
* value that this <code>Clob</code> object represents
* @param offset the offset into <code>str</code> to start reading
* @param pos the position at which to start writing to the {@code CLOB}
* value that this {@code SerialClob} object represents; the first
* position is {@code 1}; must not be less than {@code 1} nor
* greater than the length+1 of this {@code SerialClob} object
* @param str the string to be written to the {@code CLOB}
* value that this {@code Clob} object represents
* @param offset the offset into {@code str} to start reading
* the characters to be written
* @param length the number of characters to be written
* @return the number of characters written
* @throws SerialException if there is an error accessing the
* <code>CLOB</code> value; if an invalid position is set; if an
* invalid offset value is set; if number of bytes to be written
* is greater than the <code>SerialClob</code> length; or the combined
* values of the length and offset is greater than the Clob buffer;
* {@code CLOB} value; if an invalid position is set; if an
* invalid offset value is set; or the combined values of the
* {@code length} and {@code offset} is greater than the length of
* {@code str};
* if the {@code free} method had been previously called on this object
*/
public int setString(long pos, String str, int offset, int length)
throws SerialException {
isValid();
String temp = str.substring(offset);
char cPattern[] = temp.toCharArray();
if (offset < 0 || offset > str.length()) {
throw new SerialException("Invalid offset in byte array set");
throw new SerialException("Invalid offset in String object set");
}
if (pos < 1 || pos > this.length()) {
if (length < 0) {
throw new SerialException("Invalid arguments: length cannot be "
+ "negative");
}
if (pos < 1 || pos > len + 1) {
throw new SerialException("Invalid position in Clob object set");
}
if ((long)(length) > origLen) {
throw new SerialException("Buffer is not sufficient to hold the value");
}
if ((length + offset) > str.length()) {
// need check to ensure length + offset !> bytes.length
if (length > str.length() - offset) {
// need check to ensure length + offset !> str.length
throw new SerialException("Invalid OffSet. Cannot have combined offset " +
" and length that is greater that the Blob buffer");
" and length that is greater than the length of str");
}
int i = 0;
pos--; //values in the array are at position one less
while ( i < length || (offset + i +1) < (str.length() - offset ) ) {
this.buf[(int)pos + i ] = cPattern[offset + i ];
i++;
if (pos - 1 + length > Integer.MAX_VALUE) {
throw new SerialException("Invalid length. Cannot have combined pos " +
"and length that is greater than Integer.MAX_VALUE");
}
return i;
pos--; //values in the array are at position one less
if (pos + length > len) {
len = pos + length;
char[] newbuf = new char[(int)len];
System.arraycopy(buf, 0, newbuf, 0, (int)pos);
buf = newbuf;
}
String temp = str.substring(offset, offset + length);
char cPattern[] = temp.toCharArray();
System.arraycopy(cPattern, 0, buf, (int)pos, length);
return length;
}
/**