shashank created CAMEL-25301:
--------------------------------
Summary: camel-cloudevents - the application-cloudevents+json data
type writes invalid JSON when an attribute value or a text body contains a
quote, a backslash or a line break, or when the text starts with '[' or '{'
Key: CAMEL-25301
URL: https://issues.apache.org/jira/browse/CAMEL-25301
Project: Camel
Issue Type: Bug
Reporter: shashank
{{CloudEventJsonDataTypeTransformer}} (data type
{{application-cloudevents+json}}, used by Kamelets and routes to turn a message
into a structured-mode CloudEvent) builds the JSON event by string
concatenation:
{code:java}
builder.append("
").append("\"").append(key).append("\"").append(":").append("\"").append(value).append("\"")
{code}
Nothing is escaped. So:
* a text body with a quote, a backslash or a line break gives an event that is
not valid JSON ({{"data":"He said "hi""}}, a raw line break inside the string).
A JSON reader rejects the event, or, for a backslash, reads other text
({{C:\temp}} becomes {{C:}} TAB {{emp}});
* the same for every attribute value, for example a subject (a file name) or a
source with a quote or a backslash;
* since CAMEL-22339 any text that starts with {{[}} or {{\{}} is copied into
the event as a JSON value, whatever the data content type, so a {{text/plain}}
log line such as {{[INFO] order 42 received}} gives {{"data":[INFO] order 42
received}}.
The CloudEvents JSON format requires the event to be a JSON object, and RFC
8259 (section 7) requires {{"}}, {{\}} and the control characters
U+0000..U+001F to be escaped in a string.
h3. Reproduction
New tests in {{CloudEventJsonDataTypeTransformerTest}}, which parse the
produced event with {{Jsoner}}:
* {{shouldEscapeTextData}}: body {{He said "hi"}} + line break +
{{C:\temp\new}} + tab + {{done}}, {{text/plain}}: on main
{{DeserializationException: The unexpected character (h) was found at position
51}}; expected: {{data}} equals the body;
* {{shouldKeepTextDataThatOnlyLooksLikeJson}}: {{[INFO] order 42 received}},
{{text/plain}}: on main {{DeserializationException}};
* {{shouldEscapeAttributeValues}}: subject {{reports\2026 "Q3".csv}}: on main
{{DeserializationException}};
* control {{shouldNestJsonData}}: a JSON body (with an escaped quote inside) is
still nested as a JSON object; passes on main and with the fix.
The nesting of JSON data is deliberate (CAMEL-22339) and right: the CloudEvents
JSON format (section 3.1.1) says that when {{datacontenttype}} declares JSON
(or is absent) the data "MUST be stored directly as a JSON value, rather than
as an encoded JSON document represented as a string". The fix keeps that for
every body that is a JSON object or array.
h3. Proposed fix
Write every string with an RFC 8259 escaper (quote, backslash, {{\n}}, {{\r}},
{{\t}}, {{\b}}, {{\f}}, other control characters as {{\u00XX}}), and nest the
body as a JSON value only when it is a JSON object or array that parses
({{Jsoner.deserialize}}, from camel-util-json, already on the classpath through
camel-support), else write it as a JSON string. Text that needs no escaping is
written exactly as today, so the output of all existing tests is unchanged.
With the fix the module passes (11 tests). The text test also checks that the
written event has no raw control character ({{Jsoner}} itself accepts raw
control characters inside a string).
Not in scope (unchanged by the fix):
* {{Jsoner}} is lenient: it accepts missing or extra commas and colons ({{[1
2]}}, {{\{"a" 1\}}}, {{[1,]}}), raw control characters inside strings and
unknown escapes. A body that is such malformed JSON is still nested as it is,
as today; only a strict validator would avoid that.
* As since CAMEL-22339, the data content type is not consulted: a JSON object
or array is nested even for {{text/plain}} (the spec asks for a string there),
and a JSON scalar ({{42}}, {{"x"}}) with {{application/json}} is written as a
string. Changing that would change the output of working routes.
Found with a Lean 4 model of the writer and of a JSON string reader: the
property "the JSON string written for a value is read back as exactly that
value, with nothing left over" fails for every value whose first quote is
preceded by plain characters (the string ends at that quote; theorem
{{main_cut_at_quote}}), and holds for the escaped writer for every value
(theorem {{fix_roundtrip}}), which writes plain text exactly as today
({{fix_same_plain}}).
Affected: 4.14.x, 4.18.x and main (no escaping since the transformer was added
in CAMEL-18698; the "starts with [ or \{" rule since CAMEL-22339, 4.14.0).
Duplicate check (2026-10-03): JIRA text "cloudevents" + "json" (CAMEL-22339,
CAMEL-24084, CAMEL-24803, CAMEL-22429: none about escaping),
"CloudEventJsonDataTypeTransformer" (none). GitHub pull requests "cloudevents
json", "CloudEventJsonDataTypeTransformer": only #18876 (CAMEL-22339) and the
CAMEL-24084 knative ones.
_Filed with Claude Code on behalf of allthingssecurity._
--
This message was sent by Atlassian Jira
(v8.20.10#820010)