Skip to content

Commit effccf3

Browse files
committed
bitWorkArea needs to be in implementation class
Allow static access to default pad Fix bug in Base32 chunking and add some tests git-svn-id: https://svn.apache.org/repos/asf/commons/proper/codec/trunk@1064407 13f79535-47bb-0310-9956-ffa450edef68
1 parent cffa33e commit effccf3

3 files changed

Lines changed: 33 additions & 11 deletions

File tree

src/java/org/apache/commons/codec/binary/Base32.java

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,12 @@ public class Base32 extends BaseNCodec {
142142
*/
143143
private final int encodeSize;
144144

145+
/**
146+
* Place holder for the bytes we're dealing with for our based logic.
147+
* Bitwise operations store and extract the encoding or decoding from this variable.
148+
*/
149+
private long bitWorkArea;
150+
145151
/**
146152
* Creates a Base32 codec used for decoding and encoding.
147153
* <p>
@@ -281,10 +287,11 @@ void encode(byte[] in, int inPos, int inAvail) { // package protected for access
281287
// encoding.
282288
if (inAvail < 0) {
283289
eof = true;
284-
if (0 == modulus) {
285-
return; // no leftovers to process
290+
if (0 == modulus && lineLength == 0) {
291+
return; // no leftovers to process and not using chunking
286292
}
287293
ensureBufferSize(encodeSize);
294+
int savedPos = pos;
288295
switch (modulus) { // % 5
289296
case 1 : // Only 1 octet; take top 5 bits then remainder
290297
buffer[pos++] = encodeTable[(int)(bitWorkArea >> 3) & MASK_5BITS]; // 8-1*5 = 3
@@ -328,14 +335,16 @@ void encode(byte[] in, int inPos, int inAvail) { // package protected for access
328335
buffer[pos++] = PAD;
329336
break;
330337
}
331-
if (lineLength > 0){ // add chunk separator if required
338+
currentLinePos += pos - savedPos; // keep track of current line position
339+
// if currentPos == 0 we are at the start of a line, so don't add CRLF
340+
if (lineLength > 0 && currentLinePos > 0){ // add chunk separator if required
332341
System.arraycopy(lineSeparator, 0, buffer, pos, lineSeparator.length);
333342
pos += lineSeparator.length;
334343
}
335344
} else {
336345
for (int i = 0; i < inAvail; i++) {
337346
ensureBufferSize(encodeSize);
338-
modulus = (++modulus) % BITS_PER_ENCODED_BYTE;
347+
modulus = (++modulus) % BYTES_PER_UNENCODED_BLOCK;
339348
int b = in[inPos++];
340349
if (b < 0) {
341350
b += 256;

src/java/org/apache/commons/codec/binary/BaseNCodec.java

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,9 @@ public abstract class BaseNCodec implements BinaryEncoder, BinaryDecoder {
6969
/**
7070
* Byte used to pad output.
7171
*/
72-
protected final byte PAD = '='; // instance variable just in case it needs to vary later
72+
protected static final byte PAD_DEFAULT = '='; // Allow static access to default
73+
74+
protected final byte PAD = PAD_DEFAULT; // instance variable just in case it needs to vary later
7375

7476
/** Number of bytes in each full block of unencoded data, e.g. 4 for Base64 and 5 for Base32 */
7577
private final int unencodedBlockSize;
@@ -110,12 +112,6 @@ public abstract class BaseNCodec implements BinaryEncoder, BinaryDecoder {
110112
*/
111113
protected boolean eof;
112114

113-
/**
114-
* Place holder for the bytes we're dealing with for our based logic.
115-
* Bitwise operations store and extract the encoding or decoding from this variable.
116-
*/
117-
protected long bitWorkArea;
118-
119115
/**
120116
* Variable tracks how many characters have been written to the current line. Only used when encoding. We use it to
121117
* make sure each encoded line never goes beyond lineLength (if lineLength > 0).

src/test/org/apache/commons/codec/binary/Base32Test.java

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,16 @@ public class Base32Test extends TestCase {
4545
};
4646

4747

48+
private static final String [][] BASE32_TEST_CASES_CHUNKED = { //Chunked
49+
{"" ,""},
50+
{"f" ,"MY======\r\n"},
51+
{"fo" ,"MZXQ====\r\n"},
52+
{"foo" ,"MZXW6===\r\n"},
53+
{"foob" ,"MZXW6YQ=\r\n"},
54+
{"fooba" ,"MZXW6YTB\r\n"},
55+
{"foobar" ,"MZXW6YTBOI======\r\n"},
56+
};
57+
4858
public void testBase32Samples() throws Exception {
4959
Base32 codec = new Base32();
5060
for (int i = 0; i < BASE32_TEST_CASES.length; i++) {
@@ -59,6 +69,13 @@ public void testBase32HexSamples() throws Exception {
5969
}
6070
}
6171

72+
public void testBase32Chunked () throws Exception {
73+
Base32 codec = new Base32(20);
74+
for (int i = 0; i < BASE32_TEST_CASES_CHUNKED.length; i++) {
75+
assertEquals(BASE32_TEST_CASES_CHUNKED[i][1], codec.encodeAsString(BASE32_TEST_CASES_CHUNKED[i][0].getBytes("UTF-8")));
76+
}
77+
}
78+
6279
public void testSingleCharEncoding() {
6380
for (int i = 0; i < 20; i++) {
6481
Base32 codec = new Base32();

0 commit comments

Comments
 (0)