[#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 e = 0;
|
||||||
int len2 = len - 2;
|
int len2 = len - 2;
|
||||||
int lineLength = 0;
|
int lineLength = 0;
|
||||||
for (; d < len2; e += 4) {
|
for (; d < len2; d += 3, e += 4) {
|
||||||
encode3to4(src, d + off, 3, dest, e, dialect);
|
encode3to4(src, d + off, 3, dest, e, dialect);
|
||||||
|
|
||||||
lineLength += 4;
|
lineLength += 4;
|
||||||
d += 3;
|
|
||||||
|
|
||||||
if (breakLines && lineLength == MAX_LINE_LENGTH
|
if (breakLines && lineLength == MAX_LINE_LENGTH) {
|
||||||
// Only add NEW_LINE if we not ended directly on the MAX_LINE_LENGTH
|
|
||||||
&& d < len2) {
|
|
||||||
dest.setByte(e + 4, NEW_LINE);
|
dest.setByte(e + 4, NEW_LINE);
|
||||||
e ++;
|
e ++;
|
||||||
lineLength = 0;
|
lineLength = 0;
|
||||||
@ -146,6 +143,11 @@ public final class Base64 {
|
|||||||
e += 4;
|
e += 4;
|
||||||
} // end if: some padding needed
|
} // 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);
|
return dest.slice(0, e);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -16,10 +16,16 @@
|
|||||||
package io.netty.handler.codec.base64;
|
package io.netty.handler.codec.base64;
|
||||||
|
|
||||||
import io.netty.buffer.ByteBuf;
|
import io.netty.buffer.ByteBuf;
|
||||||
|
import io.netty.buffer.Unpooled;
|
||||||
import io.netty.util.CharsetUtil;
|
import io.netty.util.CharsetUtil;
|
||||||
import org.junit.Test;
|
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 io.netty.buffer.Unpooled.copiedBuffer;
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
|
|
||||||
@ -45,6 +51,62 @@ public class Base64Test {
|
|||||||
testEncode(src, expectedEncoded);
|
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) {
|
private static void testEncode(ByteBuf src, ByteBuf expectedEncoded) {
|
||||||
ByteBuf encoded = Base64.encode(src, true, Base64Dialect.STANDARD);
|
ByteBuf encoded = Base64.encode(src, true, Base64Dialect.STANDARD);
|
||||||
try {
|
try {
|
||||||
|
Loading…
Reference in New Issue
Block a user