davsclaus commented on code in PR #27721:
URL: https://github.com/apache/camel/pull/27721#discussion_r4268691321


##########
components/camel-chunk/src/main/java/org/apache/camel/component/chunk/ChunkEndpoint.java:
##########
@@ -134,6 +142,37 @@ protected void onExchange(Exchange exchange) throws 
Exception {
         }
     }
 
+    /**
+     * Neutralizes message data so the Chunk engine does not parse and expand 
template tags present inside the data
+     * itself. A String value is wrapped as a literal Chunk snippet only when 
it actually contains Chunk tags (as
+     * reported by Chunk's own parser via {@link Snippet#isSimple()}); 
tag-free values are left as-is so Chunk's string
+     * filters (for example {@code slice}, {@code get}, {@code join}) keep 
their existing behaviour. Nested {@link Map}
+     * values (such as the message headers or variables) are copied and 
processed recursively, preserving a
+     * case-insensitive headers map. Other value types are left unchanged.
+     */
+    @SuppressWarnings("unchecked")
+    private static Object toLiteralValue(Object value, HeadersMapFactory 
factory) {
+        if (value instanceof String) {
+            String str = (String) value;
+            // Only neutralize values that would otherwise be re-parsed as 
template code (i.e. that contain tags);
+            // leaving tag-free data as a plain String keeps Chunk's string 
filters working as before.
+            if (!Snippet.getSnippet(str).isSimple()) {
+                return Snippet.makeLiteralSnippet(str);
+            }
+            return str;
+        }
+        if (value instanceof Map) {
+            Map<?, ?> map = (Map<?, ?>) value;
+            Map<String, Object> copy = factory.isInstanceOf((Map<String, 
Object>) value)
+                    ? factory.newMap() : new LinkedHashMap<>();
+            for (Map.Entry<?, ?> entry : map.entrySet()) {
+                copy.put(String.valueOf(entry.getKey()), 
toLiteralValue(entry.getValue(), factory));
+            }
+            return copy;
+        }
+        return value;

Review Comment:
   Values other than `String` and `Map` pass through here unchanged, and Chunk 
turns them back into template source when it prints them:
   
   - a `List` header (repeated query parameters) or a `Map` body with a `List` 
of `Map`s (unmarshalled JSON): `{% loop in $body.rows as $r %}{$r.n}{% endloop 
%}` expands tags in `n`
   - a non-`String` `CharSequence` body such as `StringBuilder`: Chunk prints 
its `toString()`, and that string is parsed
   
   Recursing into `Collection`s and arrays (building a new `List` from 
`toLiteralValue()` of each item) and returning `toLiteralValue(cs.toString(), 
factory)` for a non-`String` `CharSequence` fixed the list-of-maps, `|join` and 
`StringBuilder` cases in my test against chunk-templates 3.6.2. A `String` item 
printed inside `{% loop %}` and POJO properties (`{$body.name}`, 
`{$exception.message}`) are still parsed, because Chunk handles those itself. 
Those need to be documented.



##########
docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_24.adoc:
##########
@@ -366,6 +366,17 @@ Previously it returned only the first chunk of the event 
log (at most 500 events
 any sign. A wide `after`/`before` window now returns every event in one list: 
that is one request per 500 events plus
 one that finds the end of the log, and more memory. Narrow the window when the 
event log is large.
 
+=== camel-chunk - message data containing Chunk tags is rendered literally
+
+Previously the `chunk` component bound the message body, headers and variables 
into the Chunk engine in a
+way that caused Chunk to re-parse those values as template source: a value 
that itself contained Chunk tags
+(such as a body of `{$headers.name}`) had those tags expanded instead of being 
printed verbatim.
+
+Message values that contain Chunk tags are now rendered literally, so only the 
route author's template file

Review Comment:
   This reads as if every message value is now printed literally. Only a value 
printed directly with `{$tag}` is protected. Chunk still parses the result of 
any filter (`{$body|trim}`, `{$body|urldecode}`), a `String` item in a `{% loop 
%}`, and `String` properties of other objects (a POJO body, 
`{$exception.message}`). Please list these cases here and in 
`chunk-component.adoc`, so users know not to pass untrusted values through 
filters in a Chunk template.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to