shashank created CAMEL-25699:
--------------------------------
Summary: camel-protobuf - converting a message to a Map replaces
the value of every bytes field with the text of ByteString.toString() (size and
a shortened, escaped preview), so the data of the field is lost
Key: CAMEL-25699
URL: https://issues.apache.org/jira/browse/CAMEL-25699
Project: Camel
Issue Type: Bug
Reporter: shashank
Assignee: shashank
The protobuf data format documents that the result of an unmarshal can be read
as a {{Map}} ({{exchange.getMessage().getBody(Map.class)}}, the type converter
{{ProtobufTypeConverter.toMap}} added by CAMEL-14192), and that a {{Map}} can
be marshalled.
{{ProtobufConverter.convertValueToSuitableFieldType}} (main d46d51c24550, lines
159-162) handles a {{bytes}} field together with an enum field: {{result =
value.toString()}}. For an enum that is the name of the constant. For a
{{bytes}} field the value is a {{com.google.protobuf.ByteString}}, and
{{ByteString.toString()}} does not return the content; it returns a description
for logging, for example
{noformat}
<ByteString@3a03464 size=4 contents="\001\002\003\377">
{noformat}
with the identity hash code, the size and an escaped preview that protobuf-java
shortens for long values. So every {{bytes}} field of the message (also in
nested messages and repeated fields) reaches the route as such a {{String}};
the data of the field cannot be recovered from it, and nothing fails or is
logged.
The other direction fails loudly: {{ProtobufConverter.toProto}} passes a
{{byte[]}} value for a {{bytes}} field to {{Builder.setField}} unchanged, and
protobuf rejects it ({{IllegalArgumentException}}), so there is no {{Map}} form
of a {{bytes}} field that can be marshalled.
Trigger: any message type with a {{bytes}} field (a common type for binary
payloads, hashes, ids, encrypted data) and the documented {{Map}} output:
{{unmarshal().protobuf(...)}} with {{contentTypeFormat=native}} (default)
followed by {{getBody(Map.class)}} or {{convertBodyTo(Map.class)}}, or any
other use of the {{Message}} to {{Map}} type converter.
h3. Reproduction
New {{ProtobufBytesFieldMapTest}} with the well-known type
{{com.google.protobuf.BytesValue}} (one {{bytes}} field named {{value}}, part
of protobuf-java, so the test protos are not changed), a value of 61 bytes:
* {{ProtobufConverter.toMap}}: on main the value is a {{String}}, not the bytes
({{ClassCastException: class java.lang.String cannot be cast to class [B}});
* a route {{from("direct:unmarshal").unmarshal(new
ProtobufDataFormat(BytesValue.getDefaultInstance()))}}, then
{{getBody(Map.class)}}: the same;
* {{toProto(toMap(message))}}: fails on main ({{IllegalArgumentException:
argument type mismatch}} from {{setField}}).
With the fix the three tests pass, and the camel-protobuf tests: 19 run, 0
failures, 0 errors, 0 skipped.
h3. Proposed fix
* {{convertValueToSuitableFieldType}}: a {{bytes}} field becomes
{{ByteString.toByteArray()}} ({{byte[]}}); enums are unchanged.
* {{getSuitableFieldValue}}: a {{byte[]}} value for a {{bytes}} field is
wrapped with {{ByteString.copyFrom}}; a {{ByteString}} is passed as before,
other types fail as before.
Users can notice that the {{Map}} now holds a {{byte[]}} for a {{bytes}} field
instead of a {{String}}; a short note goes into the 4.24 upgrade guide.
How it was found: reading the data format converters while sweeping byte and
size handling in data formats (round r29, track H, whose other tools were Z3
models of retry and back-off arithmetic); the conversion has no arithmetic, so
there is no model, the tests are the evidence. A small Java probe with
protobuf-java 4.35.1 (the version of the parent pom) printed {{value
BYTE_STRING -> <ByteString@3a03464 size=4 contents="\001\002\003\377">}}.
Not changed: an {{int64}} field given an {{Integer}} in the {{Map}} (or a
{{float}} field given a {{Double}}) is still rejected by protobuf with an
exception (loud, separate question); map fields stay a list of
{{key}}/{{value}} maps.
Affected: main (d46d51c24550; tested). camel-4.23.x, camel-4.22.x, camel-4.18.x
and camel-4.14.x have the same lines 160-162 (read, not run).
Duplicate check (2026-10-16): JIRA text "protobuf" with "ByteString", "bytes"
or "toMap" (CAMEL-14192, the feature; CAMEL-24170, the July 2026 data format
review umbrella, whose protobuf items are the JSON charset, the Jackson
timezone and the class resolver, not this); GitHub pull requests "protobuf
ByteString", "camel-protobuf map" (nothing related).
_Filed with Claude Code on behalf of allthingssecurity._
--
This message was sent by Atlassian Jira
(v8.20.10#820010)