Skip to content

Commit 96440b5

Browse files
committed
JAVA-2507: Replace use of javax.xml.bind.DatatypeConverter for Base64 encoding and decoding with org.bson.internal.Base64
1 parent 32c80cb commit 96440b5

File tree

9 files changed

+58
-45
lines changed

9 files changed

+58
-45
lines changed

driver-core/src/main/com/mongodb/connection/Base64Codec.java renamed to bson/src/main/org/bson/internal/Base64.java

Lines changed: 35 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2008-2014 MongoDB, Inc.
2+
* Copyright 2014-2017 MongoDB, Inc.
33
* Copyright 1999,2005 The Apache Software Foundation.
44
*
55
* Licensed under the Apache License, Version 2.0 (the "License");
@@ -8,27 +8,26 @@
88
*
99
* http://www.apache.org/licenses/LICENSE-2.0
1010
*
11-
* Unless required by applicable law or agreed to in writing, software
12-
* distributed under the License is distributed on an "AS IS" BASIS,
13-
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14-
* See the License for the specific language governing permissions and
15-
* limitations under the License.
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*
1617
*/
1718

18-
package com.mongodb.connection;
19-
20-
import com.mongodb.MongoException;
21-
22-
import java.io.UnsupportedEncodingException;
19+
package org.bson.internal;
2320

2421
/**
2522
* <p>Provides Base64 encoding and decoding.</p>
2623
* <p>This class implements Base64 encoding</p>
2724
* <p>Thanks to Apache Commons project. This class refactored from org.apache.commons.codec.binary</p>
2825
* <p>Original Thanks to <a href="http://svn.apache.org/repos/asf/webservices/commons/trunk/modules/util/">commons</a> project in
2926
* ws.apache.org for this code. </p>
27+
*
28+
* @since 3.5
3029
*/
31-
class Base64Codec {
30+
public final class Base64 {
3231
private static final int BYTES_PER_UNENCODED_BLOCK = 3;
3332
private static final int BYTES_PER_ENCODED_BLOCK = 4;
3433

@@ -61,7 +60,13 @@ class Base64Codec {
6160
}
6261
}
6362

64-
public byte[] decode(final String s) {
63+
/**
64+
* Decodes the given Base64-encoded string.
65+
*
66+
* @param s the Base64-encoded string
67+
* @return the decoded byte array
68+
*/
69+
public static byte[] decode(final String s) {
6570
int delta = s.endsWith("==") ? 2 : s.endsWith("=") ? 1 : 0;
6671
byte[] buffer = new byte[s.length() * BYTES_PER_UNENCODED_BLOCK / BYTES_PER_ENCODED_BLOCK - delta];
6772
int mask = 0xFF;
@@ -84,7 +89,14 @@ public byte[] decode(final String s) {
8489
return buffer;
8590
}
8691

87-
public String encode(final byte[] in) {
92+
/**
93+
* Encodes the given byte array into a Base64-encoded string.
94+
*
95+
*
96+
* @param in the byte array
97+
* @return the Base64-encoded string
98+
*/
99+
public static String encode(final byte[] in) {
88100

89101
int modulus = 0;
90102
int bitWorkArea = 0;
@@ -128,10 +140,14 @@ public String encode(final byte[] in) {
128140
break;
129141
}
130142

131-
try {
132-
return new String(buffer, "UTF-8");
133-
} catch (UnsupportedEncodingException e) {
134-
throw new MongoException("UTF-8 Charset is not available");
135-
}
143+
return byteArrayToString(buffer);
144+
}
145+
146+
@SuppressWarnings("deprecation")
147+
private static String byteArrayToString(final byte[] buffer) {
148+
return new String(buffer, 0, 0, buffer.length);
149+
}
150+
151+
private Base64() {
136152
}
137153
}

bson/src/main/org/bson/json/ExtendedJsonBinaryConverter.java

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,15 +18,14 @@
1818
package org.bson.json;
1919

2020
import org.bson.BsonBinary;
21-
22-
import static javax.xml.bind.DatatypeConverter.printBase64Binary;
21+
import org.bson.internal.Base64;
2322

2423
class ExtendedJsonBinaryConverter implements Converter<BsonBinary> {
2524

2625
@Override
2726
public void convert(final BsonBinary value, final StrictJsonWriter writer) {
2827
writer.writeStartObject();
29-
writer.writeString("$binary", printBase64Binary(value.getData()));
28+
writer.writeString("$binary", Base64.encode(value.getData()));
3029
writer.writeString("$type", String.format("%02X", value.getType()));
3130
writer.writeEndObject();
3231
}

bson/src/main/org/bson/json/JsonReader.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
import org.bson.BsonTimestamp;
2929
import org.bson.BsonType;
3030
import org.bson.BsonUndefined;
31+
import org.bson.internal.Base64;
3132
import org.bson.BsonReaderMark;
3233
import org.bson.internal.UnsignedLongs;
3334
import org.bson.types.Decimal128;
@@ -666,7 +667,7 @@ private BsonBinary visitBinDataConstructor() {
666667
}
667668
verifyToken(JsonTokenType.RIGHT_PAREN);
668669

669-
byte[] bytes = DatatypeConverter.parseBase64Binary(bytesToken.getValue(String.class));
670+
byte[] bytes = Base64.decode(bytesToken.getValue(String.class));
670671
return new BsonBinary(subTypeToken.getValue(Integer.class).byteValue(), bytes);
671672
}
672673

@@ -963,11 +964,11 @@ private BsonBinary visitBinDataExtendedJson() {
963964

964965
for (final BsonBinarySubType st : BsonBinarySubType.values()) {
965966
if (st.getValue() == subType) {
966-
return new BsonBinary(st, DatatypeConverter.parseBase64Binary(bytesToken.getValue(String.class)));
967+
return new BsonBinary(st, Base64.decode(bytesToken.getValue(String.class)));
967968
}
968969
}
969970

970-
return new BsonBinary(DatatypeConverter.parseBase64Binary(bytesToken.getValue(String.class)));
971+
return new BsonBinary(Base64.decode(bytesToken.getValue(String.class)));
971972
}
972973

973974
private long visitDateTimeExtendedJson() {

bson/src/main/org/bson/json/ShellBinaryConverter.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,14 +18,14 @@
1818
package org.bson.json;
1919

2020
import org.bson.BsonBinary;
21+
import org.bson.internal.Base64;
2122

2223
import static java.lang.String.format;
23-
import static javax.xml.bind.DatatypeConverter.printBase64Binary;
2424

2525
class ShellBinaryConverter implements Converter<BsonBinary> {
2626
@Override
2727
public void convert(final BsonBinary value, final StrictJsonWriter writer) {
2828
writer.writeRaw(format("new BinData(%s, \"%s\")", Integer.toString(value.getType() & 0xFF),
29-
printBase64Binary(value.getData())));
29+
Base64.encode(value.getData())));
3030
}
3131
}
Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2008-2014 MongoDB, Inc.
2+
* Copyright 2014-2017 MongoDB, Inc.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -14,21 +14,19 @@
1414
* limitations under the License.
1515
*/
1616

17-
package com.mongodb.connection
17+
package org.bson.json
1818

19+
import org.bson.internal.Base64
1920
import spock.lang.Specification
2021
import spock.lang.Unroll
2122

22-
class Base64CodecSpecification extends Specification {
23+
class Base64Specification extends Specification {
2324

2425
@Unroll
2526
def 'encodes #encoded into #decoded'() {
26-
given:
27-
def subject = new Base64Codec();
28-
2927
expect:
30-
subject.encode(encoded.getBytes()) == decoded
31-
subject.decode(decoded) == encoded.getBytes()
28+
Base64.encode(encoded.getBytes()) == decoded
29+
Base64.decode(decoded) == encoded.getBytes()
3230

3331
where:
3432
encoded | decoded

driver-core/src/main/com/mongodb/connection/ScramSha1Authenticator.java

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import com.mongodb.MongoCredential;
2020
import com.mongodb.ServerAddress;
2121
import com.mongodb.internal.authentication.NativeAuthenticationHelper;
22+
import org.bson.internal.Base64;
2223

2324
import javax.crypto.Mac;
2425
import javax.crypto.SecretKeyFactory;
@@ -66,7 +67,6 @@ private static class ScramSha1SaslClient implements SaslClient {
6667
private static final String GS2_HEADER = "n,,";
6768
private static final int RANDOM_LENGTH = 24;
6869

69-
private final Base64Codec base64Codec;
7070
private final MongoCredential credential;
7171
private String clientFirstMessageBare;
7272
private final RandomStringGenerator randomStringGenerator;
@@ -76,7 +76,6 @@ private static class ScramSha1SaslClient implements SaslClient {
7676

7777
ScramSha1SaslClient(final MongoCredential credential, final RandomStringGenerator randomStringGenerator) {
7878
this.credential = credential;
79-
this.base64Codec = new Base64Codec();
8079
this.randomStringGenerator = randomStringGenerator;
8180
}
8281

@@ -185,7 +184,7 @@ private byte[] computeClientFinalMessage(final byte[] challenge) throws SaslExce
185184
}
186185

187186
private byte[] decodeBase64(final String str) {
188-
return this.base64Codec.decode(str);
187+
return Base64.decode(str);
189188
}
190189

191190
private byte[] decodeUTF8(final String str) throws SaslException {
@@ -198,7 +197,7 @@ private byte[] decodeUTF8(final String str) throws SaslException {
198197
}
199198

200199
private String encodeBase64(final byte[] bytes) {
201-
return this.base64Codec.encode(bytes);
200+
return Base64.encode(bytes);
202201
}
203202

204203
private String encodeUTF8(final byte[] bytes) throws SaslException {

driver/src/main/com/mongodb/util/JSONCallback.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
import org.bson.BSONObject;
2727
import org.bson.BasicBSONCallback;
2828
import org.bson.BsonUndefined;
29+
import org.bson.internal.Base64;
2930
import org.bson.types.BSONTimestamp;
3031
import org.bson.types.Binary;
3132
import org.bson.types.Code;
@@ -35,7 +36,6 @@
3536
import org.bson.types.MinKey;
3637
import org.bson.types.ObjectId;
3738

38-
import javax.xml.bind.DatatypeConverter;
3939
import java.text.ParsePosition;
4040
import java.text.SimpleDateFormat;
4141
import java.util.Date;
@@ -129,7 +129,7 @@ public Object objectDone() {
129129
o = UUID.fromString((String) b.get("$uuid"));
130130
} else if (b.containsField("$binary")) {
131131
int type = (b.get("$type") instanceof String) ? Integer.valueOf((String) b.get("$type"), 16) : (Integer) b.get("$type");
132-
byte[] bytes = DatatypeConverter.parseBase64Binary((String) b.get("$binary"));
132+
byte[] bytes = Base64.decode((String) b.get("$binary"));
133133
o = new Binary((byte) type, bytes);
134134
} else if (b.containsField("$undefined") && b.get("$undefined").equals(true)) {
135135
o = new BsonUndefined();

driver/src/main/com/mongodb/util/JSONSerializers.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
import com.mongodb.DBObject;
2222
import com.mongodb.DBRef;
2323
import org.bson.BsonUndefined;
24+
import org.bson.internal.Base64;
2425
import org.bson.types.BSONTimestamp;
2526
import org.bson.types.Binary;
2627
import org.bson.types.Code;
@@ -31,7 +32,6 @@
3132
import org.bson.types.ObjectId;
3233
import org.bson.types.Symbol;
3334

34-
import javax.xml.bind.DatatypeConverter;
3535
import java.lang.reflect.Array;
3636
import java.text.SimpleDateFormat;
3737
import java.util.Date;
@@ -474,7 +474,7 @@ private abstract static class BinarySerializerBase extends CompoundObjectSeriali
474474

475475
protected void serialize(final byte[] bytes, final byte type, final StringBuilder buf) {
476476
DBObject temp = new BasicDBObject();
477-
temp.put("$binary", DatatypeConverter.printBase64Binary(bytes));
477+
temp.put("$binary", Base64.encode(bytes));
478478
temp.put("$type", type);
479479
serializer.serialize(temp, buf);
480480
}

driver/src/test/unit/com/mongodb/util/JSONSerializersTest.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import com.mongodb.BasicDBObject;
2020
import com.mongodb.DBRef;
2121
import org.bson.BsonUndefined;
22+
import org.bson.internal.Base64;
2223
import org.bson.types.BSONTimestamp;
2324
import org.bson.types.BasicBSONList;
2425
import org.bson.types.Binary;
@@ -31,7 +32,6 @@
3132
import org.bson.types.Symbol;
3233
import org.junit.Test;
3334

34-
import javax.xml.bind.DatatypeConverter;
3535
import java.text.SimpleDateFormat;
3636
import java.util.ArrayList;
3737
import java.util.Date;
@@ -203,7 +203,7 @@ public void testStrictSerialization() {
203203

204204
// test BINARY
205205
byte[] b = {1, 2, 3, 4};
206-
String base64 = DatatypeConverter.printBase64Binary(b);
206+
String base64 = Base64.encode(b);
207207
StringBuilder buf = new StringBuilder();
208208
serializer.serialize(new Binary(b), buf);
209209
assertEquals("{ \"$binary\" : \"" + base64 + "\" , \"$type\" : 0}", buf.toString());

0 commit comments

Comments
 (0)