Skip to content

Commit 189f83a

Browse files
committed
Backport #90 fix in 2.9.9
1 parent 8182fdd commit 189f83a

File tree

4 files changed

+99
-1
lines changed

4 files changed

+99
-1
lines changed

release-notes/VERSION-2.x

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ Modules:
1212

1313
#63: (yaml) `null` Object Id serialized as anchor for YAML
1414
(reported by jflefebvre06@github)
15+
#90: (yaml) Exception when decoding Jackson-encoded `Base64` binary value in YAML
16+
(reported by Tanguy L)
1517
#122: (csv) `readValues(null)` causes infinite loop
1618
(reported by andyeko@github)
1719
#123: (yaml) YAML Anchor, reference fails with simple example

yaml/src/main/java/com/fasterxml/jackson/dataformat/yaml/YAMLGenerator.java

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -833,7 +833,8 @@ private void _writeScalarBinary(Base64Variant b64variant,
833833
if (b64variant == Base64Variants.getDefaultVariant()) {
834834
b64variant = Base64Variants.MIME;
835835
}
836-
String encoded = b64variant.encode(data);
836+
final String lf = _lf();
837+
String encoded = _base64encode(b64variant, data, lf);
837838
_emitter.emit(new ScalarEvent(null, TAG_BINARY, EXPLICIT_TAGS, encoded,
838839
null, null, STYLE_BASE64));
839840
}
@@ -853,4 +854,42 @@ protected ScalarEvent _scalarEvent(String value, Character style)
853854
return new ScalarEvent(anchor, yamlTag, NO_TAGS, value,
854855
null, null, style);
855856
}
857+
858+
// // // 26-Feb-2019, tatu: Copied temporarily (for 2.10) from `Base64Variant` to prevent
859+
// // // hard dependency for same minor version
860+
861+
private String _base64encode(final Base64Variant b64v, final byte[] input, final String linefeed)
862+
{
863+
final int inputEnd = input.length;
864+
final StringBuilder sb = new StringBuilder(inputEnd + (inputEnd >> 2) + (inputEnd >> 3));
865+
866+
int chunksBeforeLF = b64v.getMaxLineLength() >> 2;
867+
868+
int inputPtr = 0;
869+
int safeInputEnd = inputEnd-3;
870+
871+
while (inputPtr <= safeInputEnd) {
872+
int b24 = ((int) input[inputPtr++]) << 8;
873+
b24 |= ((int) input[inputPtr++]) & 0xFF;
874+
b24 = (b24 << 8) | (((int) input[inputPtr++]) & 0xFF);
875+
b64v.encodeBase64Chunk(sb, b24);
876+
if (--chunksBeforeLF <= 0) {
877+
sb.append(linefeed);
878+
chunksBeforeLF = b64v.getMaxLineLength() >> 2;
879+
}
880+
}
881+
int inputLeft = inputEnd - inputPtr;
882+
if (inputLeft > 0) {
883+
int b24 = ((int) input[inputPtr++]) << 16;
884+
if (inputLeft == 2) {
885+
b24 |= (((int) input[inputPtr++]) & 0xFF) << 8;
886+
}
887+
b64v.encodeBase64Partial(sb, b24, inputLeft);
888+
}
889+
return sb.toString();
890+
}
891+
892+
protected String _lf() {
893+
return _outputOptions.getLineBreak().getString();
894+
}
856895
}

yaml/src/test/java/com/fasterxml/jackson/dataformat/yaml/deser/BinaryReadTest.java

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,14 @@
11
package com.fasterxml.jackson.dataformat.yaml.deser;
22

3+
import java.io.ByteArrayOutputStream;
34
import java.io.IOException;
45
import java.util.Arrays;
6+
import java.util.Random;
57

68
import org.junit.Assert;
79

10+
import com.fasterxml.jackson.core.*;
11+
812
import com.fasterxml.jackson.databind.*;
913
import com.fasterxml.jackson.databind.node.JsonNodeType;
1014
import com.fasterxml.jackson.dataformat.yaml.ModuleTestBase;
@@ -41,4 +45,29 @@ public void testBinaryViaTree() throws Exception
4145
final byte[] expectedFileHeader = new byte[]{'G', 'I', 'F', '8', '9', 'a'};
4246
Assert.assertArrayEquals(expectedFileHeader, actualFileHeader);
4347
}
48+
49+
// [dataformats-text#90]
50+
public void testReadLongBinary() throws Exception {
51+
final byte[] data = new byte[1000];
52+
new Random(1234).nextBytes(data);
53+
54+
ByteArrayOutputStream os = new ByteArrayOutputStream();
55+
56+
try (JsonGenerator gen = MAPPER.getFactory().createGenerator(os)) {
57+
gen.writeStartObject();
58+
gen.writeBinaryField("data", data);
59+
gen.writeEndObject();
60+
gen.close();
61+
}
62+
63+
try (JsonParser parser = MAPPER.getFactory().createParser(os.toByteArray())) {
64+
assertEquals(JsonToken.START_OBJECT, parser.nextToken());
65+
assertEquals(JsonToken.FIELD_NAME, parser.nextToken());
66+
assertEquals("data", parser.currentName());
67+
assertEquals(JsonToken.VALUE_EMBEDDED_OBJECT, parser.nextToken());
68+
Assert.assertArrayEquals(data, parser.getBinaryValue());
69+
assertEquals(JsonToken.END_OBJECT, parser.nextToken());
70+
assertNull(parser.nextToken());
71+
}
72+
}
4473
}

yaml/src/test/java/com/fasterxml/jackson/dataformat/yaml/ser/BinaryWriteTest.java

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
11
package com.fasterxml.jackson.dataformat.yaml.ser;
22

3+
import java.io.StringWriter;
4+
import java.util.Arrays;
5+
36
import org.junit.Assert;
47

8+
import com.fasterxml.jackson.core.JsonGenerator;
59
import com.fasterxml.jackson.databind.*;
610
import com.fasterxml.jackson.databind.node.JsonNodeType;
711
import com.fasterxml.jackson.databind.node.ObjectNode;
@@ -26,4 +30,28 @@ public void testBinaryViaTree() throws Exception
2630
final byte[] b = data.binaryValue();
2731
Assert.assertArrayEquals(srcPayload, b);
2832
}
33+
34+
public void testWriteLongBinary() throws Exception {
35+
final int length = 200;
36+
final byte[] data = new byte[length];
37+
Arrays.fill(data, (byte) 1);
38+
39+
StringWriter w = new StringWriter();
40+
41+
try (JsonGenerator gen = MAPPER.getFactory().createGenerator(w)) {
42+
gen.writeStartObject();
43+
gen.writeBinaryField("array", data);
44+
gen.writeEndObject();
45+
gen.close();
46+
}
47+
48+
String yaml = w.toString();
49+
Assert.assertEquals("---\n" +
50+
"array: !!binary |-\n" +
51+
" AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEB\n" +
52+
" AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEB\n" +
53+
" AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEB\n" +
54+
" AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQE=\n", yaml);
55+
56+
}
2957
}

0 commit comments

Comments
 (0)