Replace cxjs_eval() with a Safe Implementation#116
Conversation
…s unsafe version).
Greptile SummaryThis PR replaces the unsafe
Confidence Score: 3/5The safe-eval replacement is a meaningful security improvement, but it silently drops the object-scoping arguments that the server-side counterpart supports, which can produce wrong widget-property values with no diagnostic output. When eval() is called with 3 or 4 arguments in the expression language, the generated JS passes all arguments to cxjs_eval, but the function only captures the first two user args — the current-object and parent-object overrides are silently discarded. Expressions that rely on that scoping will evaluate against the wrong object context on the client without any error or warning, producing silent wrong-value regressions. centrallix-os/sys/js/ht_render.js — the new cxjs_eval function needs to handle or explicitly reject the 3rd and 4th user arguments to match exp_fn_eval's object-scoping behaviour.
|
| Filename | Overview |
|---|---|
| centrallix-os/sys/js/ht_render.js | Replaces the old single-arg eval(x) with a structured safe parser; handles booleans, null, numbers, quoted strings, and :obj:prop references — but silently ignores the 3rd/4th user arguments (current/parent object overrides) that the server-side exp_fn_eval supports. |
| centrallix/expression/exp_generator.c | Adds eval alongside substitute in the list of functions that get _context,_this, prepended to their argument list during JS code generation. One-line mechanical change that correctly enables the new client-side function signature. |
Sequence Diagram
sequenceDiagram
participant CX as Centrallix Expression eval(expr, perms, obj)
participant GEN as exp_generator.c
participant JS as Browser JS
participant CXJS as cxjs_eval()
participant WGTR as wgtrGetNode/wgtrGetProperty
CX->>GEN: compile eval() node
GEN->>JS: emit cxjs_eval(_context,_this, expr, perms, obj)
Note over GEN,JS: i2 (obj) becomes 5th arg — ignored by cxjs_eval
JS->>CXJS: call at runtime
Note over CXJS: permflags=undefined → all access allowed
alt literal value (bool/null/int/float/string)
CXJS-->>JS: return parsed value
else :property
CXJS->>CXJS: check _this + permflags C
CXJS-->>JS: return _this[prop] or null
else :object:property
CXJS->>WGTR: wgtrGetNode(_context, objname)
WGTR-->>CXJS: node or null
CXJS->>WGTR: wgtrGetProperty(node, propname)
WGTR-->>CXJS: value or null
CXJS-->>JS: return value
else unrecognised
CXJS-->>JS: console.warn + return null
end
Prompt To Fix All With AI
Fix the following 1 code review issue. Work through them one at a time, proposing concise fixes.
---
### Issue 1 of 1
centrallix-os/sys/js/ht_render.js:314-375
**3rd and 4th user args silently ignored (current/parent object override)**
The server-side `exp_fn_eval` accepts up to four user arguments: `expr`, `permflags`, `currentobj`, and `parentobj`. When a Centrallix expression calls `eval(expr, "CO", "mywidget")`, the C generator emits `cxjs_eval(_context, _this, expr, "CO", "mywidget")`, but the JS function only captures four parameters. The 5th argument (`mywidget`) — which `exp_fn_eval` uses to override `objlist->CurrentID` for the scope of the inner evaluation — is silently discarded. Any expression using `eval()` with 3 or more arguments will silently use the wrong object context on the client, producing incorrect property lookups with no warning.
Reviews (2): Last reviewed commit: "Add support for booleans and null values..." | Re-trigger Greptile
|
This PR is ready for human review. |
gbeeley
left a comment
There was a problem hiding this comment.
Need to address 3rd/4th param consistency with server per Greptile.
cxjs_eval() with a Safe Implementation.cxjs_eval() with a Safe Implementation
gbeeley
left a comment
There was a problem hiding this comment.
A couple of changes needed - thanks!
| const prop = rest.substring(1); | ||
| const par_node = (par_obj_name !== null && par_obj_name !== undefined) | ||
| ? wgtrGetNode(_context, par_obj_name) | ||
| : wgtrGetParent(_context); |
There was a problem hiding this comment.
This defaults to the parent of the context, rather than the parent of the current object (_this).
In server contexts, the parent object has a context-dependent meaning but usually refers to the immediate parent object of the current object. The most common use is in a QueryTree object.
On the client, the most useful meaning here would be to reference the parent of _this rather than the parent of _context which likely steps out of the current scope entirely.
There was a problem hiding this comment.
Ahhh, so like this?
const par_node = (par_obj_name !== null && par_obj_name !== undefined)
? wgtrGetNode(_context, par_obj_name)
: wgtrGetParent(_this);This issue likely arises from me only having a surface-level understanding of what eval(), _context, and _this should do.
There was a problem hiding this comment.
Yes, that looks correct - please test out and verify. Thanks!
There was a problem hiding this comment.
I'll try to test this, although I only barely understand what this function is supposed to do in this case.
|
@gbeeley That should resolve your requested changes. |
gbeeley
left a comment
There was a problem hiding this comment.
Oops - one of my last recommendations was partly wrong.
| } | ||
| else if (_this !== null && _this !== undefined) | ||
| { | ||
| return wgtrGetProperty(_this, rest); |
There was a problem hiding this comment.
I take that back. There are cases where _this is a plain object rather than a widget. So this code should check first whether it is a widget via wgtrIsNode() before calling wgtrGetProperty(), otherwise use the _this[prop] approach.
An example of this is parameters passed from an event (the event params) which can be referenced as the current object as in :property.
There was a problem hiding this comment.
Hmmm, I think I understand. Should be fixed now.
|
@gbeeley I think I've fixed those issues. |
This PR will add a safe client-side implementation of eval, replacing the previous unsafe version.