Skip to content

Commit

Permalink
Remove tag copying for CBOR event copies.
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
here-abarany committed Dec 12, 2022
1 parent 00d5d3e commit fe4283c
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 43 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -536,42 +536,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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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());
Expand All @@ -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);

Expand Down Expand Up @@ -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
};
}

0 comments on commit fe4283c

Please sign in to comment.