From a135e6b2a3b4ecb32882b165855a74ef028335e6 Mon Sep 17 00:00:00 2001 From: Aaron Barany Date: Mon, 12 Dec 2022 13:38:12 -0800 Subject: [PATCH] Remove tag copying for CBOR event copies. Copying tags can be dangerous in two main cases: 1. Jackson creates its own tags, such as for BigNum or the self describe tag. 2. The semantic meaning of an element changes. For example, converting between stringrefs and no stringrefs. In some cases it would result in duplicate tags, while in others it may cause completely incorrect tags, such as a stringref tag applying to a string rather than an integer. Before nested tag support was added this could generate files that Jackson could not parse, though even with nested tag support it may cause undefined behavior. --- .../dataformat/cbor/CBORGenerator.java | 36 --------------- .../dataformat/cbor/StringrefTest.java | 44 ++++++++++++++++--- 2 files changed, 37 insertions(+), 43 deletions(-) diff --git a/cbor/src/main/java/com/fasterxml/jackson/dataformat/cbor/CBORGenerator.java b/cbor/src/main/java/com/fasterxml/jackson/dataformat/cbor/CBORGenerator.java index 8b6088b6b..022ac0c19 100644 --- a/cbor/src/main/java/com/fasterxml/jackson/dataformat/cbor/CBORGenerator.java +++ b/cbor/src/main/java/com/fasterxml/jackson/dataformat/cbor/CBORGenerator.java @@ -537,42 +537,6 @@ public final void writeFieldId(long id) throws IOException { _writeLongNoCheck(id); } - /* - /********************************************************** - /* Overridden methods, copying with tag-awareness - /********************************************************** - */ - - /** - * Specialize {@link JsonGenerator#copyCurrentEvent} to handle tags. - */ - @Override - public void copyCurrentEvent(JsonParser p) throws IOException { - maybeCopyTag(p); - super.copyCurrentEvent(p); - } - - /** - * Specialize {@link JsonGenerator#copyCurrentStructure} to handle tags. - */ - @Override - public void copyCurrentStructure(JsonParser p) throws IOException { - maybeCopyTag(p); - super.copyCurrentStructure(p); - } - - protected void maybeCopyTag(JsonParser p) throws IOException { - if (p instanceof CBORParser) { - if (p.hasCurrentToken()) { - final int currentTag = ((CBORParser) p).getCurrentTag(); - - if (currentTag != -1) { - writeTag(currentTag); - } - } - } - } - /* /********************************************************** /* Output method implementations, structural diff --git a/cbor/src/test/java/com/fasterxml/jackson/dataformat/cbor/StringrefTest.java b/cbor/src/test/java/com/fasterxml/jackson/dataformat/cbor/StringrefTest.java index 829c0fcef..5a305d8e2 100644 --- a/cbor/src/test/java/com/fasterxml/jackson/dataformat/cbor/StringrefTest.java +++ b/cbor/src/test/java/com/fasterxml/jackson/dataformat/cbor/StringrefTest.java @@ -610,14 +610,8 @@ public void testNestedTags() throws Exception { gen.close(); byte[] encoded = bytes.toByteArray(); - byte[] nestedTagBytes = new byte[]{ - (byte) 0xD9, (byte) 0xD9, (byte) 0xF7, (byte) 0xD9, 0x01, 0x00, (byte) 0x9F, - (byte) 0xC2, 0x45, 0x12, 0x34, 0x56, 0x78, (byte) 0x90, (byte) 0xC2, 0x46, 0x00, - (byte) 0x98, 0x76, 0x54, 0x32, 0x10, (byte) 0xC2, (byte) 0xD8, 0x19, 0x00, - (byte) 0xFF - }; - assertArrayEquals(nestedTagBytes, encoded); + assertArrayEquals(_nestedTagBytes, encoded); CBORParser parser = cborParser(encoded); assertToken(JsonToken.START_ARRAY, parser.nextToken()); @@ -633,6 +627,35 @@ public void testNestedTags() throws Exception { assertToken(JsonToken.END_ARRAY, parser.nextToken()); } + public void testNestedTagsRounddTrip() throws Exception { + CBORParser parser = cborParser(_nestedTagBytes); + ByteArrayOutputStream bytes = new ByteArrayOutputStream(); + CBORGenerator gen = cborGenerator(bytes); + parser.nextToken(); + gen.copyCurrentStructure(parser); + gen.close(); + + byte[] expectedExpandedBytes = new byte[]{ + (byte) 0x9F, (byte) 0xC2, 0x45, 0x12, 0x34, 0x56, 0x78, (byte) 0x90, (byte) 0xC2, + 0x46, 0x00, (byte) 0x98, 0x76, 0x54, 0x32, 0x10, (byte) 0xC2, 0x45, 0x12, 0x34, + 0x56, 0x78, (byte) 0x90, (byte) 0xFF + }; + byte[] encoded = bytes.toByteArray(); + assertArrayEquals(expectedExpandedBytes, encoded); + + bytes.reset(); + parser = cborParser(encoded); + gen = new CBORFactory() + .enable(CBORGenerator.Feature.WRITE_TYPE_HEADER) + .enable(CBORGenerator.Feature.STRINGREF) + .createGenerator(bytes); + parser.nextToken(); + gen.copyCurrentStructure(parser); + gen.close(); + + assertArrayEquals(_nestedTagBytes, bytes.toByteArray()); + } + private void verifyStringArray(byte[] encoded) throws IOException { assertArrayEquals(_stringArrayBytes, encoded); @@ -783,4 +806,11 @@ private void verifyNextTokenBinaryStream(String expected, CBORParser parser) thr 0x19, 0x01, 0x44, 0x73, 0x73, 0x73, 0x73, (byte) 0xD8, 0x19, 0x17, 0x43, 0x72, 0x72, 0x72, (byte) 0xD8, 0x19, 0x18, 0x18, (byte) 0xFF }; + + private static final byte[] _nestedTagBytes = new byte[]{ + (byte) 0xD9, (byte) 0xD9, (byte) 0xF7, (byte) 0xD9, 0x01, 0x00, (byte) 0x9F, + (byte) 0xC2, 0x45, 0x12, 0x34, 0x56, 0x78, (byte) 0x90, (byte) 0xC2, 0x46, 0x00, + (byte) 0x98, 0x76, 0x54, 0x32, 0x10, (byte) 0xC2, (byte) 0xD8, 0x19, 0x00, + (byte) 0xFF + }; } \ No newline at end of file