Skip to content

Commit 3c54b6e

Browse files
committed
Merge branch '2.10'
2 parents 7a64f9d + 748861e commit 3c54b6e

File tree

6 files changed

+105
-43
lines changed

6 files changed

+105
-43
lines changed

release-notes/CREDITS-2.x

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,3 +37,7 @@ Andrey Somov (asomov@github)
3737
* Contributed #101: Use latest SnakeYAML version 1.23 and get rid of deprecated methods
3838
(2.10.0)
3939

40+
Tanguy Leroux (tlrx@github)
41+
42+
* Reported #90: Exception when decoding Jackson-encoded `Base64` binary value in YAML
43+
(2.10.0)

release-notes/VERSION-2.x

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,15 +10,17 @@ Modules:
1010

1111
2.10.0 (not yet released)
1212

13-
#101: Use latest SnakeYAML version 1.23 and get rid of deprecated methods
13+
#101: (yaml) Use latest SnakeYAML version 1.23 and get rid of deprecated methods
1414
(contributed by Andrey S)
15-
#108: Add new `CsvParser.Feature.ALLOW_COMMENTS` to replace deprecated
15+
#108: (yaml) Add new `CsvParser.Feature.ALLOW_COMMENTS` to replace deprecated
1616
`JsonParser.Feature.ALLOW_YAML_COMMENTS`
1717

1818
2.9.9 (not yet released)
1919

2020
#63: (yaml) `null` Object Id serialized as anchor for YAML
2121
(reported by jflefebvre06@github)
22+
#90: (yaml) Exception when decoding Jackson-encoded `Base64` binary value in YAML
23+
(reported by Tanguy L)
2224
#122: (csv) `readValues(null)` causes infinite loop
2325
(reported by andyeko@github)
2426
#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
@@ -810,7 +810,8 @@ private void _writeScalarBinary(Base64Variant b64variant,
810810
if (b64variant == Base64Variants.getDefaultVariant()) {
811811
b64variant = Base64Variants.MIME;
812812
}
813-
String encoded = b64variant.encode(data);
813+
final String lf = _lf();
814+
String encoded = _base64encode(b64variant, data, lf);
814815
_emitter.emit(new ScalarEvent(null, TAG_BINARY, EXPLICIT_TAGS, encoded,
815816
null, null, STYLE_BASE64));
816817
}
@@ -830,4 +831,42 @@ protected ScalarEvent _scalarEvent(String value, DumperOptions.ScalarStyle style
830831
return new ScalarEvent(anchor, yamlTag, NO_TAGS, value,
831832
null, null, style);
832833
}
834+
835+
// // // 26-Feb-2019, tatu: Copied temporarily (for 2.10) from `Base64Variant` to prevent
836+
// // // hard dependency for same minor version
837+
838+
private String _base64encode(final Base64Variant b64v, final byte[] input, final String linefeed)
839+
{
840+
final int inputEnd = input.length;
841+
final StringBuilder sb = new StringBuilder(inputEnd + (inputEnd >> 2) + (inputEnd >> 3));
842+
843+
int chunksBeforeLF = b64v.getMaxLineLength() >> 2;
844+
845+
int inputPtr = 0;
846+
int safeInputEnd = inputEnd-3;
847+
848+
while (inputPtr <= safeInputEnd) {
849+
int b24 = ((int) input[inputPtr++]) << 8;
850+
b24 |= ((int) input[inputPtr++]) & 0xFF;
851+
b24 = (b24 << 8) | (((int) input[inputPtr++]) & 0xFF);
852+
b64v.encodeBase64Chunk(sb, b24);
853+
if (--chunksBeforeLF <= 0) {
854+
sb.append(linefeed);
855+
chunksBeforeLF = b64v.getMaxLineLength() >> 2;
856+
}
857+
}
858+
int inputLeft = inputEnd - inputPtr;
859+
if (inputLeft > 0) {
860+
int b24 = ((int) input[inputPtr++]) << 16;
861+
if (inputLeft == 2) {
862+
b24 |= (((int) input[inputPtr++]) & 0xFF) << 8;
863+
}
864+
b64v.encodeBase64Partial(sb, b24, inputLeft);
865+
}
866+
return sb.toString();
867+
}
868+
869+
protected String _lf() {
870+
return _outputOptions.getLineBreak().getString();
871+
}
833872
}

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/failing/ObjectId123Test.java

Lines changed: 0 additions & 40 deletions
This file was deleted.

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)