Skip to content

Commit d17765d

Browse files
committed
#925 Fix using native client, password is limited to 255 bytes
1 parent 1979c16 commit d17765d

17 files changed

Lines changed: 357 additions & 17 deletions

src/docs/asciidoc/release_notes.adoc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ This results in two minor breaking changes:
5050
** Presence of the NUL character (U+0000) in an identifier passed to `enquoteIdentifier` will result in a `SQLSyntaxErrorException`
5151
* Fixed: JDBC escapes should not be parsed inside dialect 3 delimited identifiers or dialect 1 string literals (https://github.com/FirebirdSQL/jaybird/issues/921[#921])
5252
* Fixed: `IndexOutOfBoundsException` in `FBCachedBlob.getBytes(long, int)` for position or length beyond end of data (https://github.com/FirebirdSQL/jaybird/issues/923[#923])
53+
* Fixed: Using native client, password is limited to 255 bytes (https://github.com/FirebirdSQL/jaybird/issues/925[#925])
5354

5455
=== Jaybird 6.0.4
5556

src/main/org/firebirdsql/gds/impl/DatabaseParameterBufferImp.java

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,17 @@ public ParameterTagMapping getTagMapping() {
5555
}
5656

5757
public enum DpbMetaData implements ParameterBufferMetaData {
58-
DPB_VERSION_1(ISCConstants.isc_dpb_version1, ArgumentType.TraditionalDpb),
58+
DPB_VERSION_1(ISCConstants.isc_dpb_version1, ArgumentType.TraditionalDpb) {
59+
@Override
60+
public boolean isUpgradable() {
61+
return true;
62+
}
63+
64+
@Override
65+
public ParameterBufferMetaData upgradeMetaData() {
66+
return DPB_VERSION_2;
67+
}
68+
},
5969
DPB_VERSION_2(ISCConstants.isc_dpb_version2, ArgumentType.Wide);
6070

6171
private final int dpbVersion;

src/main/org/firebirdsql/gds/impl/ParameterBufferBase.java

Lines changed: 45 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ public abstract class ParameterBufferBase implements ParameterBuffer, Serializab
5050
private final List<Argument> arguments = new ArrayList<>();
5151

5252
private final String defaultEncodingName;
53-
private final ParameterBufferMetaData parameterBufferMetaData;
53+
private ParameterBufferMetaData parameterBufferMetaData;
5454
private transient Encoding defaultEncoding;
5555

5656
/**
@@ -99,8 +99,21 @@ public final void addArgument(int argumentType, String value) {
9999

100100
@Override
101101
public final void addArgument(int argumentType, String value, Encoding encoding) {
102-
addArgument(new StringArgument(
103-
argumentType, parameterBufferMetaData.getStringArgumentType(argumentType), value, encoding));
102+
addArgument(createStringArgument(argumentType, value, encoding));
103+
}
104+
105+
private StringArgument createStringArgument(int argumentType, String value, Encoding encoding) {
106+
try {
107+
return new StringArgument(
108+
argumentType, parameterBufferMetaData.getStringArgumentType(argumentType), value, encoding);
109+
} catch (LengthOverflowException e) {
110+
if (tryUpgradeMetaData()) {
111+
// Do not inline parameterBufferMetaData or argument type; they might be different here than in the try
112+
return new StringArgument(
113+
argumentType, parameterBufferMetaData.getStringArgumentType(argumentType), value, encoding);
114+
}
115+
throw e;
116+
}
104117
}
105118

106119
@Override
@@ -127,7 +140,19 @@ public final void addArgument(int argumentType) {
127140

128141
@Override
129142
public final void addArgument(int type, byte[] content) {
130-
addArgument(new ByteArrayArgument(type, parameterBufferMetaData.getByteArrayArgumentType(type), content));
143+
addArgument(createByteArrayArgument(type, content));
144+
}
145+
146+
private ByteArrayArgument createByteArrayArgument(int type, byte[] content) {
147+
try {
148+
return new ByteArrayArgument(type, parameterBufferMetaData.getByteArrayArgumentType(type), content);
149+
} catch (LengthOverflowException e) {
150+
if (tryUpgradeMetaData()) {
151+
// Do not inline parameterBufferMetaData or argument type; they might be different here than in the try
152+
return new ByteArrayArgument(type, parameterBufferMetaData.getByteArrayArgumentType(type), content);
153+
}
154+
throw e;
155+
}
131156
}
132157

133158
protected final void addArgument(Argument argument) {
@@ -227,6 +252,22 @@ public final boolean isEmpty() {
227252
return arguments.isEmpty();
228253
}
229254

255+
private boolean tryUpgradeMetaData() {
256+
if (!parameterBufferMetaData.isUpgradable()) return false;
257+
try {
258+
ParameterBufferMetaData newParameterBufferMetaData = parameterBufferMetaData.upgradeMetaData();
259+
List<Argument> newArguments = arguments.stream()
260+
.map(argument -> argument.transformTo(newParameterBufferMetaData))
261+
.toList();
262+
arguments.clear();
263+
arguments.addAll(newArguments);
264+
parameterBufferMetaData = newParameterBufferMetaData;
265+
return true;
266+
} catch (IllegalArgumentException e) {
267+
return false;
268+
}
269+
}
270+
230271
@Override
231272
@SuppressWarnings("java:S2097")
232273
public final boolean equals(Object other) {

src/main/org/firebirdsql/gds/impl/ParameterBufferMetaData.java

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,4 +108,31 @@ default ArgumentType getByteArgumentType(int tag) {
108108
return getIntegerArgumentType(tag);
109109
}
110110

111+
/**
112+
* Returns if this metadata type is upgradable.
113+
* <p>
114+
* The default implementation always returns {@code false}.
115+
* </p>
116+
*
117+
* @return {@code true} if this type is upgradable
118+
* @see #upgradeMetaData()
119+
* @since 6.0.5
120+
*/
121+
default boolean isUpgradable() {
122+
return false;
123+
}
124+
125+
/**
126+
* The parameter buffer metadata that can be upgraded to.
127+
* <p>
128+
* The default implementation always returns {@code this}.
129+
* </p>
130+
*
131+
* @return the upgrade buffer metadata, returns this instance if {@link #isUpgradable()} returns {@code false}
132+
* @since 6.0.5
133+
*/
134+
default ParameterBufferMetaData upgradeMetaData() {
135+
return this;
136+
}
137+
111138
}

src/main/org/firebirdsql/gds/impl/ServiceParameterBufferImp.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,16 @@ public ArgumentType getSingleArgumentType(int tag) {
7979
}
8080
return ArgumentType.TraditionalDpb;
8181
}
82+
83+
@Override
84+
public boolean isUpgradable() {
85+
return true;
86+
}
87+
88+
@Override
89+
public ParameterBufferMetaData upgradeMetaData() {
90+
return SPB_VERSION_3_ATTACH;
91+
}
8292
},
8393
// Technically this has nothing to do with SPB version 2/3
8494
SPB_VERSION_2(ISCConstants.isc_spb_current_version) {

src/main/org/firebirdsql/gds/impl/argument/Argument.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
package org.firebirdsql.gds.impl.argument;
2020

2121
import org.firebirdsql.gds.Parameter;
22+
import org.firebirdsql.gds.impl.ParameterBufferMetaData;
2223

2324
import java.io.IOException;
2425
import java.io.OutputStream;
@@ -87,4 +88,17 @@ public long getValueAsLong() {
8788
*/
8889
public abstract int getLength();
8990

91+
/**
92+
* If needed, returns a new argument to transform to a suitable argument type, otherwise returns this instance.
93+
*
94+
* @param parameterBufferMetaData
95+
* parameter buffer metadata (used to determine the needed argument type)
96+
* @return either a new argument if transformation is needed, or this instance
97+
* @throws IllegalArgumentException
98+
* if transformation is needed, but the creation of the new instance fails (e.g. downgrading from
99+
* {@link ArgumentType#Wide} to {@link ArgumentType#TraditionalDpb}, and the value is too long)
100+
* @since 6.0.5
101+
*/
102+
public abstract Argument transformTo(ParameterBufferMetaData parameterBufferMetaData);
103+
90104
}

src/main/org/firebirdsql/gds/impl/argument/BigIntArgument.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
import org.firebirdsql.encodings.Encoding;
2222
import org.firebirdsql.gds.ParameterBuffer;
2323
import org.firebirdsql.gds.VaxEncoding;
24+
import org.firebirdsql.gds.impl.ParameterBufferMetaData;
2425

2526
import java.io.IOException;
2627
import java.io.OutputStream;
@@ -82,6 +83,13 @@ public void copyTo(ParameterBuffer buffer, Encoding encoding) {
8283
buffer.addArgument(getType(), value);
8384
}
8485

86+
@Override
87+
public BigIntArgument transformTo(ParameterBufferMetaData parameterBufferMetaData) {
88+
ArgumentType newArgumentType = parameterBufferMetaData.getIntegerArgumentType(getType());
89+
if (newArgumentType == argumentType) return this;
90+
return new BigIntArgument(getType(), newArgumentType, value);
91+
}
92+
8593
@Override
8694
public boolean equals(Object other) {
8795
if (this == other) return true;

src/main/org/firebirdsql/gds/impl/argument/ByteArgument.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020

2121
import org.firebirdsql.encodings.Encoding;
2222
import org.firebirdsql.gds.ParameterBuffer;
23+
import org.firebirdsql.gds.impl.ParameterBufferMetaData;
2324

2425
import java.io.IOException;
2526
import java.io.OutputStream;
@@ -79,6 +80,13 @@ public void copyTo(ParameterBuffer buffer, Encoding encoding) {
7980
buffer.addArgument(getType(), value);
8081
}
8182

83+
@Override
84+
public ByteArgument transformTo(ParameterBufferMetaData parameterBufferMetaData) {
85+
ArgumentType newArgumentType = parameterBufferMetaData.getByteArgumentType(getType());
86+
if (newArgumentType == argumentType) return this;
87+
return new ByteArgument(getType(), newArgumentType, value);
88+
}
89+
8290
@Override
8391
public boolean equals(Object other) {
8492
if (this == other) return true;

src/main/org/firebirdsql/gds/impl/argument/ByteArrayArgument.java

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020

2121
import org.firebirdsql.encodings.Encoding;
2222
import org.firebirdsql.gds.ParameterBuffer;
23+
import org.firebirdsql.gds.impl.ParameterBufferMetaData;
2324

2425
import java.io.IOException;
2526
import java.io.OutputStream;
@@ -40,12 +41,18 @@ public final class ByteArrayArgument extends TypedArgument {
4041
private final byte[] value;
4142

4243
/**
43-
* Initializes an instance of ByteArrayArgument.
44+
* Initialises an instance of ByteArrayArgument.
4445
*
4546
* @param type
46-
* Parameter type
47+
* parameter type
48+
* @param argumentType
49+
* argument type
4750
* @param value
48-
* Byte array with a maximum length defined by {@code argumentType}.
51+
* byte array
52+
* @throws IllegalArgumentException
53+
* if {@code type} is not valid for byte arrays, or if {@code value} is {@code null}
54+
* @throws LengthOverflowException
55+
* if the length of {@code value} exceeds {@link ArgumentType#getMaxLength()}
4956
*/
5057
public ByteArrayArgument(int type, ArgumentType argumentType, byte[] value) {
5158
super(type, argumentType);
@@ -58,7 +65,7 @@ public ByteArrayArgument(int type, ArgumentType argumentType, byte[] value) {
5865
throw new IllegalArgumentException("byte array value should not be null");
5966
}
6067
if (value.length > argumentType.getMaxLength()) {
61-
throw new IllegalArgumentException(
68+
throw new LengthOverflowException(
6269
String.format("byte array value should not be longer than %d bytes, length was %d",
6370
argumentType.getMaxLength(), value.length));
6471
}
@@ -86,11 +93,23 @@ public int getValueAsInt() {
8693
}
8794
}
8895

96+
// primarily intended for testing purposes
97+
public byte[] getValueAsBytes() {
98+
return value.clone();
99+
}
100+
89101
@Override
90102
public void copyTo(ParameterBuffer buffer, Encoding encoding) {
91103
buffer.addArgument(getType(), value.clone());
92104
}
93105

106+
@Override
107+
public ByteArrayArgument transformTo(ParameterBufferMetaData parameterBufferMetaData) {
108+
ArgumentType newArgumentType = parameterBufferMetaData.getByteArrayArgumentType(getType());
109+
if (newArgumentType == argumentType) return this;
110+
return new ByteArrayArgument(getType(), newArgumentType, value);
111+
}
112+
94113
@Override
95114
public boolean equals(Object other) {
96115
if (this == other) return true;
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
// SPDX-FileCopyrightText: Copyright 2026 Mark Rotteveel
2+
// SPDX-License-Identifier: LGPL-2.1-or-later
3+
package org.firebirdsql.gds.impl.argument;
4+
5+
import java.io.Serial;
6+
7+
/**
8+
* Thrown by {@link StringArgument} and {@link ByteArrayArgument} if a value's length exceeds that of their
9+
* {@link ArgumentType}.
10+
*
11+
* @since 6.0.5
12+
*/
13+
public class LengthOverflowException extends IllegalArgumentException {
14+
15+
@Serial
16+
private static final long serialVersionUID = 5735116134576091931L;
17+
18+
LengthOverflowException(String message) {
19+
super(message);
20+
}
21+
22+
}

0 commit comments

Comments
 (0)