[#4793] Correctly add newlines when encode base64
Motivation: We not correctly added newlines if the src data needed to be padded. This regression was introduced by '63426fc3ed083513c07a58b45381f5c10dd47061' Modifications: - Correctly handling newlines - Add unit test that proves the fix. Result: No more invalid base64 encoded data.
This commit is contained in:
parent
acbf1b9e7e
commit
65b3470456
@ -126,15 +126,12 @@ public final class Base64 {
|
||||
int e = 0;
|
||||
int len2 = len - 2;
|
||||
int lineLength = 0;
|
||||
for (; d < len2; e += 4) {
|
||||
for (; d < len2; d += 3, e += 4) {
|
||||
encode3to4(src, d + off, 3, dest, e, dialect);
|
||||
|
||||
lineLength += 4;
|
||||
d += 3;
|
||||
|
||||
if (breakLines && lineLength == MAX_LINE_LENGTH
|
||||
// Only add NEW_LINE if we not ended directly on the MAX_LINE_LENGTH
|
||||
&& d < len2) {
|
||||
if (breakLines && lineLength == MAX_LINE_LENGTH) {
|
||||
dest.setByte(e + 4, NEW_LINE);
|
||||
e ++;
|
||||
lineLength = 0;
|
||||
@ -146,6 +143,11 @@ public final class Base64 {
|
||||
e += 4;
|
||||
} // end if: some padding needed
|
||||
|
||||
// Remove last byte if it's a newline
|
||||
if (e > 1 && dest.getByte(e - 1) == NEW_LINE) {
|
||||
e--;
|
||||
}
|
||||
|
||||
return dest.slice(0, e);
|
||||
}
|
||||
|
||||
|
@ -16,10 +16,16 @@
|
||||
package io.netty.handler.codec.base64;
|
||||
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.buffer.Unpooled;
|
||||
import io.netty.util.CharsetUtil;
|
||||
import org.junit.Test;
|
||||
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.nio.charset.Charset;
|
||||
import java.security.cert.CertificateFactory;
|
||||
import java.security.cert.X509Certificate;
|
||||
|
||||
import static io.netty.buffer.Unpooled.copiedBuffer;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
@ -45,6 +51,62 @@ public class Base64Test {
|
||||
testEncode(src, expectedEncoded);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEncodeEmpty() {
|
||||
ByteBuf src = Unpooled.EMPTY_BUFFER;
|
||||
ByteBuf expectedEncoded = Unpooled.EMPTY_BUFFER;
|
||||
testEncode(src, expectedEncoded);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPaddingNewline() throws Exception {
|
||||
String cert = "-----BEGIN CERTIFICATE-----\n" +
|
||||
"MIICqjCCAjGgAwIBAgICI1YwCQYHKoZIzj0EATAmMSQwIgYDVQQDDBtUcnVzdGVk\n" +
|
||||
"IFRoaW4gQ2xpZW50IFJvb3QgQ0EwIhcRMTYwMTI0MTU0OTQ1LTA2MDAXDTE2MDQy\n" +
|
||||
"NTIyNDk0NVowYzEwMC4GA1UEAwwnREMgMGRlYzI0MGYtOTI2OS00MDY5LWE2MTYt\n" +
|
||||
"YjJmNTI0ZjA2ZGE0MREwDwYDVQQLDAhEQyBJUFNFQzEcMBoGA1UECgwTVHJ1c3Rl\n" +
|
||||
"ZCBUaGluIENsaWVudDB2MBAGByqGSM49AgEGBSuBBAAiA2IABOB7pZYC24sF5gJm\n" +
|
||||
"OHXhasxmrNYebdtSAiQRgz0M0pIsogsFeTU/W0HTlTOqwDDckphHESAKHVxa6EBL\n" +
|
||||
"d+/8HYZ1AaCmXtG73XpaOyaRr3TipJl2IaJzwuehgDHs0L+qcqOB8TCB7jAwBgYr\n" +
|
||||
"BgEBEAQEJgwkMGRlYzI0MGYtOTI2OS00MDY5LWE2MTYtYjJmNTI0ZjA2ZGE0MCMG\n" +
|
||||
"CisGAQQBjCHbZwEEFQwTNDkwNzUyMjc1NjM3MTE3Mjg5NjAUBgorBgEEAYwh22cC\n" +
|
||||
"BAYMBDIwNTkwCwYDVR0PBAQDAgXgMAkGA1UdEwQCMAAwHQYDVR0OBBYEFGWljaKj\n" +
|
||||
"wiGqW61PgLL/zLxj4iirMB8GA1UdIwQYMBaAFA2FRBtG/dGnl0iXP2uKFwJHmEQI\n" +
|
||||
"MCcGA1UdJQQgMB4GCCsGAQUFBwMCBggrBgEFBQcDAQYIKwYBBQUHAwkwCQYHKoZI\n" +
|
||||
"zj0EAQNoADBlAjAQFP8rMLUxl36u8610LsSCiRG8pP3gjuLaaJMm3tjbVue/TI4C\n" +
|
||||
"z3iL8i96YWK0VxcCMQC7pf6Wk3RhUU2Sg6S9e6CiirFLDyzLkaWxuCnXcOwTvuXT\n" +
|
||||
"HUQSeUCp2Q6ygS5qKyc=\n" +
|
||||
"-----END CERTIFICATE-----";
|
||||
|
||||
String expected = "MIICqjCCAjGgAwIBAgICI1YwCQYHKoZIzj0EATAmMSQwIgYDVQQDDBtUcnVzdGVkIFRoaW4gQ2xp\n" +
|
||||
"ZW50IFJvb3QgQ0EwIhcRMTYwMTI0MTU0OTQ1LTA2MDAXDTE2MDQyNTIyNDk0NVowYzEwMC4GA1UE\n" +
|
||||
"AwwnREMgMGRlYzI0MGYtOTI2OS00MDY5LWE2MTYtYjJmNTI0ZjA2ZGE0MREwDwYDVQQLDAhEQyBJ\n" +
|
||||
"UFNFQzEcMBoGA1UECgwTVHJ1c3RlZCBUaGluIENsaWVudDB2MBAGByqGSM49AgEGBSuBBAAiA2IA\n" +
|
||||
"BOB7pZYC24sF5gJmOHXhasxmrNYebdtSAiQRgz0M0pIsogsFeTU/W0HTlTOqwDDckphHESAKHVxa\n" +
|
||||
"6EBLd+/8HYZ1AaCmXtG73XpaOyaRr3TipJl2IaJzwuehgDHs0L+qcqOB8TCB7jAwBgYrBgEBEAQE\n" +
|
||||
"JgwkMGRlYzI0MGYtOTI2OS00MDY5LWE2MTYtYjJmNTI0ZjA2ZGE0MCMGCisGAQQBjCHbZwEEFQwT\n" +
|
||||
"NDkwNzUyMjc1NjM3MTE3Mjg5NjAUBgorBgEEAYwh22cCBAYMBDIwNTkwCwYDVR0PBAQDAgXgMAkG\n" +
|
||||
"A1UdEwQCMAAwHQYDVR0OBBYEFGWljaKjwiGqW61PgLL/zLxj4iirMB8GA1UdIwQYMBaAFA2FRBtG\n" +
|
||||
"/dGnl0iXP2uKFwJHmEQIMCcGA1UdJQQgMB4GCCsGAQUFBwMCBggrBgEFBQcDAQYIKwYBBQUHAwkw\n" +
|
||||
"CQYHKoZIzj0EAQNoADBlAjAQFP8rMLUxl36u8610LsSCiRG8pP3gjuLaaJMm3tjbVue/TI4Cz3iL\n" +
|
||||
"8i96YWK0VxcCMQC7pf6Wk3RhUU2Sg6S9e6CiirFLDyzLkaWxuCnXcOwTvuXTHUQSeUCp2Q6ygS5q\n" +
|
||||
"Kyc=";
|
||||
|
||||
ByteBuf src = Unpooled.wrappedBuffer(certFromString(cert).getEncoded());
|
||||
ByteBuf expectedEncoded = copiedBuffer(expected, CharsetUtil.US_ASCII);
|
||||
testEncode(src, expectedEncoded);
|
||||
}
|
||||
|
||||
private static X509Certificate certFromString(String string) throws Exception {
|
||||
CertificateFactory factory = CertificateFactory.getInstance("X.509");
|
||||
ByteArrayInputStream bin = new ByteArrayInputStream(string.getBytes(CharsetUtil.US_ASCII));
|
||||
try {
|
||||
return (X509Certificate) factory.generateCertificate(bin);
|
||||
} finally {
|
||||
bin.close();
|
||||
}
|
||||
}
|
||||
|
||||
private static void testEncode(ByteBuf src, ByteBuf expectedEncoded) {
|
||||
ByteBuf encoded = Base64.encode(src, true, Base64Dialect.STANDARD);
|
||||
try {
|
||||
|
Loading…
Reference in New Issue
Block a user