davsclaus commented on code in PR #28391:
URL: https://github.com/apache/camel/pull/28391#discussion_r4367558681
##########
components/camel-quickjs/src/main/java/org/apache/camel/language/quickjs/QuickjsHelper.java:
##########
@@ -152,6 +152,78 @@ final class QuickjsHelper {
*/
static final String CAMEL_FACADE = camelFacade();
+ /**
+ * JavaScript that prepares the script result for the JSON hand-over to
Java, where a {@code Set} or a {@code Map}
+ * would become an empty object and a typed array an object of index to
value: a {@code Set} becomes an array, a
+ * {@code Map} an object (its keys as strings), and a typed array or an
{@code ArrayBuffer} an array of numbers,
+ * also when nested in objects and arrays. A primitive is returned after
one type check, and an object or array is
+ * only copied when something in it is converted. A value with {@code
toJSON} (such as a {@code Date}) and a cyclic
+ * reference are left to JSON as before. The built-ins are captured once
so a script cannot replace them.
+ */
+ private static final String RESULT_CONVERTER = """
+ const __camelResult = (() => {
+ const SetType = Set;
+ const MapType = Map;
+ const ArrayBufferType = ArrayBuffer;
+ const DataViewType = DataView;
+ const Uint8ArrayType = Uint8Array;
+ const isView = ArrayBuffer.isView;
+ const isArray = Array.isArray;
+ const from = Array.from;
+ const keys = Object.keys;
+ const fromEntries = Object.fromEntries;
+ const define = Object.defineProperty;
+ const isObject = v => typeof v === "object" && v !== null;
+ const put = (o, k, v) => define(o, k, { value: v, writable:
true, enumerable: true, configurable: true });
+ const convert = (v, path) => {
+ if (typeof v.toJSON === "function" || path.includes(v)) {
+ return v;
+ }
+ if (v instanceof ArrayBufferType) {
+ return from(new Uint8ArrayType(v));
+ }
+ if (isView(v)) {
+ return v instanceof DataViewType ? v : from(v);
Review Comment:
Good catch, thanks. d0869c31fc6b converts a `DataView` to the bytes it views
(`new Uint8Array(v.buffer, v.byteOffset, v.byteLength)`), as you suggested. A
new test checks that a view over part of a buffer gives only those bytes, and
the doc page and the PR description now name `DataView`.
_Claude Code on behalf of davsclaus_
##########
components/camel-javascript/src/main/java/org/apache/camel/language/js/JavaScriptLanguage.java:
##########
@@ -149,6 +168,11 @@ private static Object materialize(Value value, Map<Value,
Object> seen) {
if (value.isInstant()) {
return value.asInstant();
}
+ if (value.hasBufferElements()) {
+ byte[] bytes = new byte[Math.toIntExact(value.getBufferSize())];
Review Comment:
Leaving this one as it is. The script is route code, which the security
model trusts: the route author decides what it returns, and a large result is
the same as a processor building a large body. By the time this line runs, the
script has already allocated the buffer, so the copy only doubles memory that
is already used. Before this PR, the same result became a `List` with one boxed
number per byte, which took far more memory. A fixed cap such as 100 MB would
also fail routes that legitimately move large binary bodies. Limiting the size
of messages belongs to the route (throttle, JVM limits).
_Claude Code on behalf of davsclaus_
##########
components/camel-python3/src/main/java/org/apache/camel/language/python3/Python3Language.java:
##########
@@ -326,6 +341,11 @@ private static Object materialize(Value value, Map<Value,
Object> seen) {
if (isMainModule(value)) {
return null;
}
+ if (value.hasBufferElements()) {
+ byte[] bytes = new byte[Math.toIntExact(value.getBufferSize())];
Review Comment:
Same as for `JavaScriptLanguage`: the bytes come from a script the route
author wrote, and the Python object already holds them. The `byte[]` copy
replaces the much larger `List` of numbers it gave before. No cap here, for the
same reasons.
_Claude Code on behalf of davsclaus_
--
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]