Repository navigation
Add system(command; args) operator (disabled by default) - #2640
Conversation
Agent-Logs-Url: https://github.com/mikefarah/yq/sessions/8a11e9a0-10d2-4f2a-ae29-4e9d0bfc266f Co-authored-by: mikefarah <1151925+mikefarah@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
Adds a new system(...) operator to yqlib that can execute external commands (disabled by default) and wires it through parsing, CLI configuration, tests, and operator documentation.
Changes:
- Introduces
SecurityPreferences.EnableSystemOps(defaultfalse) and a--enable-system-operatorCLI flag to opt in. - Implements
systemoperator parsing/registration and execution logic (stdin = current node YAML, stdout -> string). - Adds operator scenarios + generated documentation pages/headers.
Reviewed changes
Copilot reviewed 8 out of 8 changed files in this pull request and generated 7 comments.
Show a summary per file
| File | Description |
|---|---|
| pkg/yqlib/security_prefs.go | Adds security preference toggle for system operator. |
| pkg/yqlib/operator_system.go | Implements system operator execution and result mapping. |
| pkg/yqlib/operation.go | Registers SYSTEM operation type. |
| pkg/yqlib/lexer_participle.go | Adds system to the lexer/operator table. |
| cmd/root.go | Adds --enable-system-operator persistent flag. |
| pkg/yqlib/operator_system_test.go | Adds scenarios for disabled/enabled behavior and failures. |
| pkg/yqlib/doc/operators/system-operators.md | Adds generated operator docs with examples/output. |
| pkg/yqlib/doc/operators/headers/system-operators.md | Adds doc header snippet included by generator. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| var command string | ||
| var argsExpression *ExpressionNode | ||
|
|
||
| // check if it's a block operator (command; args) or just (command) | ||
| if expressionNode.RHS.Operation.OperationType == blockOpType { |
There was a problem hiding this comment.
command/argsExpression are resolved once using context.ReadOnlyClone() before iterating over context.MatchingNodes, and only the first match is used. This means system(<expr>) and system(<expr>; <expr>) cannot vary per matched node (e.g. system(.cmd; .args)), and may pick an unrelated first result when multiple nodes are matched. Consider evaluating the command/args expressions inside the per-candidate loop using context.SingleReadonlyChildContext(candidate) (and failing if they don't yield a single scalar/sequence) so parameter expressions behave consistently with other operators like load.
There was a problem hiding this comment.
Done in da611f7. Command and args expressions are now evaluated inside the per-candidate loop using context.SingleReadonlyChildContext(candidate), matching the pattern used by loadOperator. This allows expressions like system(.cmd; .arg) to resolve .cmd and .arg against each matched node individually. Also added a test case for per-node evaluation, used exec.LookPath for portability, and fixed CRLF-aware newline trimming.
| subdescription: "Use `--enable-system-operator` to enable the system operator.", | ||
| document: "country: Australia", | ||
| expression: `.country = system("/usr/bin/echo"; "test")`, | ||
| expected: []string{ | ||
| "D0, P[], (!!map)::country: null\n", | ||
| }, | ||
| }, | ||
| } | ||
|
|
||
| var systemOperatorEnabledScenarios = []expressionScenario{ | ||
| { | ||
| description: "Run a command with an argument", | ||
| subdescription: "Use `--enable-system-operator` to enable the system operator.", | ||
| document: "country: Australia", | ||
| expression: `.country = system("/usr/bin/echo"; "test")`, | ||
| expected: []string{ |
There was a problem hiding this comment.
These tests depend on hard-coded absolute paths like /usr/bin/echo and /bin/echo, which can fail on some Linux distros/containers and all non-POSIX platforms. Consider resolving the executable at runtime (e.g. via exec.LookPath) or skipping these scenarios when the required commands aren't available, to keep the test suite portable and reliable.
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
…ldContext Agent-Logs-Url: https://github.com/mikefarah/yq/sessions/dca841eb-3f63-4f23-adeb-556431560420 Co-authored-by: mikefarah <1151925+mikefarah@users.noreply.github.com>
…m op docs Agent-Logs-Url: https://github.com/mikefarah/yq/sessions/3f8a5375-25fd-4428-a8e6-b630194c36b2 Co-authored-by: mikefarah <1151925+mikefarah@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 9 out of 9 changed files in this pull request and generated 4 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| if commandNodes.MatchingNodes.Front() == nil { | ||
| return Context{}, fmt.Errorf("system operator: command expression returned no results") | ||
| } | ||
| command = commandNodes.MatchingNodes.Front().Value.(*CandidateNode).Value | ||
|
|
||
| argsNodes, err := d.GetMatchingNodes(nodeContext, block.RHS) | ||
| if err != nil { | ||
| return Context{}, err | ||
| } | ||
| if argsNodes.MatchingNodes.Front() != nil { | ||
| args = resolveSystemArgs(argsNodes.MatchingNodes.Front().Value.(*CandidateNode)) | ||
| } | ||
| } else { | ||
| commandNodes, err := d.GetMatchingNodes(nodeContext, expressionNode.RHS) | ||
| if err != nil { | ||
| return Context{}, err | ||
| } | ||
| if commandNodes.MatchingNodes.Front() == nil { | ||
| return Context{}, fmt.Errorf("system operator: command expression returned no results") | ||
| } | ||
| command = commandNodes.MatchingNodes.Front().Value.(*CandidateNode).Value | ||
| } |
There was a problem hiding this comment.
command is taken from the first matched node’s .Value without validating type/tag. If the command expression yields !!null or a non-scalar node, exec.Command will be invoked with an empty/invalid command (leading to confusing errors like “exec: no command”). Consider validating that the command node is a non-null scalar (and possibly erroring if multiple results are returned) and returning a clearer system operator: command must be a string scalar error.
There was a problem hiding this comment.
@copilot apply changes based on this feedback If there are multiple results, just use the first (and log a debug, not a warning, of all the matches).
There was a problem hiding this comment.
Done in 53abbba. Extracted a resolveCommandNode helper that validates the command is a non-null scalar (returning "system operator: command must be a string scalar" if not) and logs a Debugf when multiple results are returned before using the first.
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Agent-Logs-Url: https://github.com/mikefarah/yq/sessions/928aabc5-ad71-41d8-94ab-403942e3f92d Co-authored-by: mikefarah <1151925+mikefarah@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 9 out of 9 changed files in this pull request and generated 5 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
| rootCmd.PersistentFlags().BoolVarP(&yqlib.ConfiguredSecurityPreferences.DisableEnvOps, "security-disable-env-ops", "", false, "Disable env related operations.") | ||
| rootCmd.PersistentFlags().BoolVarP(&yqlib.ConfiguredSecurityPreferences.DisableFileOps, "security-disable-file-ops", "", false, "Disable file related operations (e.g. load)") | ||
| rootCmd.PersistentFlags().BoolVarP(&yqlib.ConfiguredSecurityPreferences.EnableSystemOps, "security-enable-system-operator", "", false, "Enable system operator to allow execution of external commands.") | ||
| rootCmd.PersistentFlags().BoolVarP(&yqlib.ConfiguredSecurityPreferences.EnableSystemOps, "enable-system-operator", "", false, "DEPRECATED: use --security-enable-system-operator instead. Enable system operator to allow execution of external commands.") |
There was a problem hiding this comment.
@copilot no need to add enable-system-operator in this PR only to deprecate it. Also MarkPersistentFlagDeprecated doesn't exist anyway
There was a problem hiding this comment.
Done in b3b4478. Removed the deprecated --enable-system-operator alias and the MarkPersistentFlagDeprecated call entirely. The flag is now only --security-enable-system-operator, consistent with --security-disable-env-ops and --security-disable-file-ops. All references in the operator warning message, test yqFlags, and docs are updated accordingly.
…le-system-operator consistently Agent-Logs-Url: https://github.com/mikefarah/yq/sessions/286b95e9-b6d7-4ab8-b401-2d7a03853922 Co-authored-by: mikefarah <1151925+mikefarah@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
|
@jandubois - I don't suppose you could run your deep review tool against this PR as well? That report was really neat..what are you using? Is this something you made? |
I did run it: https://jandubois.github.io/yq/20260406-103045-pr-2640.html There is also a Markdown version at https://jandubois.github.io/yq/20260406-103045-pr-2640.md if you want to copy some of it into a comment here, to feed back to Copilot. Be aware that the Markdown version includes the individual agent responses, so is quite verbose; you don't want to copy all of it. The HTML version is post-processed and has added code blocks and some other minor things. Since this was another multi-pass review I now ran out of quota for Gemini for today. Unfortunately I only have a limited subscription for it and it looks like running 2 multi-pass reviews use up all of it. 😢 I can still run the tool, but have to run it with just Claude and Codex until 11pm...
Yes, it is my own tool running on "Zilicon Island", my off-leash sandbox (like Jurassic Park, except there are roaming AI agents instead of dinosaurs). It has a lead agent preparing prompts for review agents using the top reasoning models, and then combining their findings. In a It takes a bit of time (you can see this latest review ran for 90 minutes wall time). It also generates metrics and feedback that I use to continuously improve it. You can see all reviews I ran against the You can see that I ran the tool (single-pass only) against my oss-fuzz branches. It found issues in each of them, that I fixed before creating the PRs. Those PRs were also all made with AI, but of course with some steering. PS: Just realized that some of the code blocks have off-by-one errors in the line numbers and highlighted lines. So added a script to the tool to verify the code blocks, so the agent can check and fix it by themselves for future reviews. This is perpetual work-in-progress... |
|
Regarding I6. system operator subsumes env/file security restrictions I think it would be best not just to add the section to the docs, but to actually make |
|
@copilot please fix according to the following feedback: I1. Disabled mode silently injects nulls instead of erroring — if !ConfiguredSecurityPreferences.EnableSystemOps {
log.Warning("system operator is disabled, use --security-enable-system-operator flag to enable")
results := list.New()
for el := context.MatchingNodes.Front(); el != nil; el = el.Next() {
candidate := el.Value.(*CandidateNode)
results.PushBack(candidate.CreateReplacement(ScalarNode, "!!null", "null"))
}
return context.ChildContext(results), nil
}When the system operator is disabled (the default), it returns Fix: Return an error, matching the codebase convention: if !ConfiguredSecurityPreferences.EnableSystemOps {
- log.Warning("system operator is disabled, use --security-enable-system-operator flag to enable")
- results := list.New()
- for el := context.MatchingNodes.Front(); el != nil; el = el.Next() {
- candidate := el.Value.(*CandidateNode)
- results.PushBack(candidate.CreateReplacement(ScalarNode, "!!null", "null"))
- }
- return context.ChildContext(results), nil
+ return Context{}, fmt.Errorf("system operations are disabled, use --security-enable-system-operator to enable")
}If the null-return behaviour is intentional, document the divergence from the env/file pattern in a code comment. I2. Multi-result arg expressions silently truncated to first match — if argsNodes.MatchingNodes.Front() != nil {
args = resolveSystemArgs(argsNodes.MatchingNodes.Front().Value.(*CandidateNode))
}When the args expression produces multiple results (e.g. Fix: Add a debug log matching the command-resolution pattern, or flatten all matching arg nodes into argv: +if argsNodes.MatchingNodes.Len() > 1 {
+ log.Debugf("system operator: args expression returned %d results, using first", argsNodes.MatchingNodes.Len())
+}
if argsNodes.MatchingNodes.Front() != nil {
args = resolveSystemArgs(argsNodes.MatchingNodes.Front().Value.(*CandidateNode))
}I3. Command validation accepts non-string scalars — cmdNode := commandNodes.MatchingNodes.Front().Value.(*CandidateNode)
if cmdNode.Kind != ScalarNode || cmdNode.Tag == "!!null" {
return "", fmt.Errorf("system operator: command must be a string scalar")
}The check rejects !!null and non-scalars but allows !!int, !!bool, and other scalar tags through. Fix: Check the tag explicitly: -if cmdNode.Kind != ScalarNode || cmdNode.Tag == "!!null" {
+if cmdNode.Kind != ScalarNode || cmdNode.guessTagFromCustomType() != "!!str" {
return "", fmt.Errorf("system operator: command must be a string scalar")
}I4. Misleading documentation about semicolons for multiple args — - An argument or array of arguments separated by `;` (optional)This suggests multiple arguments can be semicolon-separated: Fix: -- An argument or array of arguments separated by `;` (optional)
+- An argument (or an array of arguments), separated from the command by `;` (optional)I5. Argument resolution silently ignores invalid node types — if child.Kind != ScalarNode || child.Tag == "!!null" {
log.Warningf("system operator: argument must be a non-null scalar; got kind=%v tag=%v - ignoring", child.Kind, child.Tag)
continue
}When a sequence argument contains a non-scalar or null element, Fix: Return an error instead of continuing: if child.Kind != ScalarNode || child.Tag == "!!null" {
- log.Warningf("system operator: argument must be a non-null scalar; got kind=%v tag=%v - ignoring", child.Kind, child.Tag)
- continue
+ return nil, fmt.Errorf("system operator: argument must be a non-null scalar; got kind=%v tag=%v", child.Kind, child.Tag)
}This requires changing I6. system operator subsumes env/file security restrictions — undocumented — When Fix: Add a note to **Security warning**: The system operator is disabled by default. You must explicitly pass `--security-enable-system-operator` to use it.
+
+**Note:** When enabled, the system operator can replicate the functionality of `env` and `load`
+operators via external commands. Enabling it effectively overrides `--security-disable-env-ops`
+and `--security-disable-file-ops`.I7. Multi-node execution path untested — All 7 test scenarios exercise the per-node loop ( Fix: Add a multi-document or multi-element test: {
description: "System operator processes multiple documents",
skipDoc: true,
document: "a: first",
document2: "a: second",
expression: `.a = system("` + echoPath + `"; "replaced")`,
expected: []string{
"D0, P[], (!!map)::a: replaced\n",
"D1, P[], (!!map)::a: replaced\n",
},
}, |
|
@jandubois it found some really good important issues! Thanks :) |
…ation, debug logs, docs Agent-Logs-Url: https://github.com/mikefarah/yq/sessions/fbfba2db-60ea-4c20-a4c2-0fd396b80c81 Co-authored-by: mikefarah <1151925+mikefarah@users.noreply.github.com>
Done in 62d28d5. All seven issues addressed:
|
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 9 out of 9 changed files in this pull request and generated 2 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
This MR contains the following updates: | Package | Update | Change | |---|---|---| | [mikefarah/yq](https://github.com/mikefarah/yq) | minor | `v4.52.5` → `v4.53.2` | MR created with the help of [el-capitano/tools/renovate-bot](https://gitlab.com/el-capitano/tools/renovate-bot). **Proposed changes to behavior should be submitted there as MRs.** --- ### Release Notes <details> <summary>mikefarah/yq (mikefarah/yq)</summary> ### [`v4.53.2`](https://github.com/mikefarah/yq/releases/tag/v4.53.2) [Compare Source](mikefarah/yq@v4.52.5...v4.53.2) - Releases and tags now signed and immutable! - Add system(command; args) operator (disabled by default) ([#​2640](mikefarah/yq#2640)) - TOML encoder: prefer readable table sections over inline tables ([#​2649](mikefarah/yq#2649)) - Fix TOML encoder to quote keys containing special characters ([#​2648](mikefarah/yq#2648)) - Add string slicing support ([#​2639](mikefarah/yq#2639)) - Fix findInArray misuse on MappingNodes in equality and contains ([#​2645](mikefarah/yq#2645)) Thanks [@​jandubois](https://github.com/jandubois)! - Fix panic on negative slice indices that underflow after adjustment ([#​2646](mikefarah/yq#2646)) Thanks [@​jandubois](https://github.com/jandubois)! - Fix stack overflow from circular alias in traverse ([#​2647](mikefarah/yq#2647)) Thanks [@​jandubois](https://github.com/jandubois)! - Fix panic and OOM in repeatString for large repeat counts ([#​2644](mikefarah/yq#2644)) Thanks [@​jandubois](https://github.com/jandubois)! - Bumped dependencies </details> --- ### Configuration 📅 **Schedule**: (UTC) - Branch creation - At any time (no schedule defined) - Automerge - At any time (no schedule defined) 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. ♻ **Rebasing**: Whenever MR becomes conflicted, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this MR and you won't be reminded about this update again. --- - [ ] <!-- rebase-check -->If you want to rebase/retry this MR, check this box --- This MR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate). <!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My4xMjcuMSIsInVwZGF0ZWRJblZlciI6IjQzLjEyNy4xIiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6WyJSZW5vdmF0ZSBCb3QiLCJhdXRvbWF0aW9uOmJvdC1hdXRob3JlZCIsImRlcGVuZGVuY3ktdHlwZTo6bWlub3IiXX0=-->
This PR contains the following updates: | Package | Update | Change | |---|---|---| | [forgejo-runner-service-yq](https://github.com/mikefarah/yq) | minor | `v4.52.4` → `v4.53.2` | --- ### Release Notes <details> <summary>mikefarah/yq (forgejo-runner-service-yq)</summary> ### [`v4.53.2`](https://github.com/mikefarah/yq/releases/tag/v4.53.2) [Compare Source](mikefarah/yq@v4.52.5...v4.53.2) - Releases and tags now signed and immutable! - Add system(command; args) operator (disabled by default) ([#​2640](mikefarah/yq#2640)) - TOML encoder: prefer readable table sections over inline tables ([#​2649](mikefarah/yq#2649)) - Fix TOML encoder to quote keys containing special characters ([#​2648](mikefarah/yq#2648)) - Add string slicing support ([#​2639](mikefarah/yq#2639)) - Fix findInArray misuse on MappingNodes in equality and contains ([#​2645](mikefarah/yq#2645)) Thanks [@​jandubois](https://github.com/jandubois)! - Fix panic on negative slice indices that underflow after adjustment ([#​2646](mikefarah/yq#2646)) Thanks [@​jandubois](https://github.com/jandubois)! - Fix stack overflow from circular alias in traverse ([#​2647](mikefarah/yq#2647)) Thanks [@​jandubois](https://github.com/jandubois)! - Fix panic and OOM in repeatString for large repeat counts ([#​2644](mikefarah/yq#2644)) Thanks [@​jandubois](https://github.com/jandubois)! - Bumped dependencies ### [`v4.52.5`](https://github.com/mikefarah/yq/releases/tag/v4.52.5) [Compare Source](mikefarah/yq@v4.52.4...v4.52.5) - Fix: reset TOML decoder state between files ([#​2634](mikefarah/yq#2634)) thanks [@​terminalchai](https://github.com/terminalchai) - Fix: preserve original filename when using --front-matter ([#​2613](mikefarah/yq#2613)) thanks [@​cobyfrombrooklyn-bot](https://github.com/cobyfrombrooklyn-bot) - Fix typo in filename ([#​2611](mikefarah/yq#2611)) thanks [@​alexandear](https://github.com/alexandear) - Bumped dependencies </details> --- ### Configuration 📅 **Schedule**: (UTC) - Branch creation - Between 12:00 AM and 03:59 AM (`* 0-3 * * *`) - Automerge - Between 12:00 AM and 03:59 AM (`* 0-3 * * *`) 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. ♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box --- This PR has been generated by [Mend Renovate](https://github.com/renovatebot/renovate). <!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My4xOTUuMSIsInVwZGF0ZWRJblZlciI6IjQzLjE5NS4xIiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6WyJLaW5kL0RlcGVuZGVuY3lVcGRhdGUiLCJydW4tZW5kLXRvLWVuZC10ZXN0cyJdfQ==--> Reviewed-on: https://code.forgejo.org/forgejo/runner/pulls/1536
|
Thank you for adding this! It took me a bit of experimenting to understand how to get it to work as a filter with both stdin and multiple args, maybe this example will be helpful for others: |
This PR contains the following updates: | Package | Update | Change | |---|---|---| | [yq](https://github.com/mikefarah/yq) | minor | `4.52.4` → `4.53.6` | --- >⚠️ **Warning** > > Some dependencies could not be looked up. Check the [Dependency Dashboard](issues/141) for more information. --- ### Release Notes <details> <summary>mikefarah/yq (yq)</summary> ### [`v4.53.6`](https://github.com/mikefarah/yq/releases/tag/v4.53.6) [Compare Source](mikefarah/yq@v4.53.4...v4.53.6) - Fixing release build issue - Fixed line wrapping bug ([#​2824](mikefarah/yq#2824), [#​2823](mikefarah/yq#2823)) Thanks [@​mxey](https://github.com/mxey) - Bumped dependencies ### [`v4.53.4`](https://github.com/mikefarah/yq/releases/tag/v4.53.4) [Compare Source](mikefarah/yq@v4.53.3...v4.53.4) - Close input files after processing each one ([#​2796](mikefarah/yq#2796)) ([#​2808](mikefarah/yq#2808)) Thanks [@​MsfPablo](https://github.com/MsfPablo) - Fixed non string HCL string keys ([#​2795](mikefarah/yq#2795)) - Fixed heap allocation bug ([#​2809](mikefarah/yq#2809)) Thanks [@​MsfPablo](https://github.com/MsfPablo) - Fix deleting commented empty list YAML output ([#​2765](mikefarah/yq#2765)) Thanks [@​dpersek](https://github.com/dpersek) - Fix (has) return false for negative array indices ([#​2769](mikefarah/yq#2769)) Thanks [@​maximilize](https://github.com/maximilize) - Fix (sort): avoid int64 overflow comparing large integers ([#​2771](mikefarah/yq#2771)) Thanks [@​maximilize](https://github.com/maximilize) - Fix: preserve correct parent references in explode merge anchor reconstruction ([#​2730](mikefarah/yq#2730)) Thanks [@​vomba](https://github.com/vomba) - Improve Guard ExpressionParser initialization with sync.Once ([#​2789](mikefarah/yq#2789)) Thanks [@​arcaven](https://github.com/arcaven) - Fix: reject negative indent instead of panicking ([#​2746](mikefarah/yq#2746)) Thanks [@​StressTestor](https://github.com/StressTestor) - Fix: parse signed hex and octal integers ([#​2749](mikefarah/yq#2749)) Thanks [@​StressTestor](https://github.com/StressTestor) - Fix: skip UTF-8 BOM when processing front matter ([#​2751](mikefarah/yq#2751)) Thanks [@​StressTestor](https://github.com/StressTestor) - Fix !!merge tag regression for yq ([#​2705](mikefarah/yq#2705)) Thanks [@​W-Floyd](https://github.com/W-Floyd) - Default to yaml when a file's extension is not a recognised format ([#​2785](mikefarah/yq#2785)) Thanks [@​devthedevil](https://github.com/devthedevil) - Bumped dependencies ### [`v4.53.3`](https://github.com/mikefarah/yq/releases/tag/v4.53.3) [Compare Source](mikefarah/yq@v4.53.2...v4.53.3) - Add `--ini-preserve-quotes` flag for INI round-trip quote preservation ([#​2728](mikefarah/yq#2728)) Thanks [@​toller892](https://github.com/toller892)! - Fix: reset INI decoder state on init ([#​2719](mikefarah/yq#2719)) Thanks [@​xieby1](https://github.com/xieby1)! - Fix: decode properties array bracket paths ([#​2693](mikefarah/yq#2693)) Thanks [@​cyphercodes](https://github.com/cyphercodes)! - Fix: preserve floats with trailing zero when encoding YAML to JSON ([#​2701](mikefarah/yq#2701)) Thanks [@​ChrisJr404](https://github.com/ChrisJr404)! - Fix: JSON to TOML root scope and null handling ([#​2689](mikefarah/yq#2689)) Thanks [@​LovesAsuna](https://github.com/LovesAsuna)! - Fix: reset TOML decoder finished flag on Init for multi-doc evaluation ([#​2704](mikefarah/yq#2704)) Thanks [@​terminalchai](https://github.com/terminalchai)! - Fix: reset TOML decoder between files when evaluating all at once ([#​2685](mikefarah/yq#2685)) Thanks [@​terminalchai](https://github.com/terminalchai)! - Fix: preserve TOML inline table array scope ([#​2694](mikefarah/yq#2694)) Thanks [@​cyphercodes](https://github.com/cyphercodes)! - Fix: preserve empty TOML arrays in tables ([#​2686](mikefarah/yq#2686)) Thanks [@​cyphercodes](https://github.com/cyphercodes)! - Fix: TOML encoder uses inline tables for YAML FlowStyle mappings ([#​2687](mikefarah/yq#2687)) - Fix nested inline YAML merge explode ([#​2699](mikefarah/yq#2699)) Thanks [@​cyphercodes](https://github.com/cyphercodes)! - Fix repeatString overflow test on 32-bit platforms ([#​2680](mikefarah/yq#2680)) Thanks [@​jandubois](https://github.com/jandubois)! - Bumped dependencies ### [`v4.53.2`](https://github.com/mikefarah/yq/releases/tag/v4.53.2) [Compare Source](mikefarah/yq@v4.52.5...v4.53.2) - Releases and tags now signed and immutable! - Add system(command; args) operator (disabled by default) ([#​2640](mikefarah/yq#2640)) - TOML encoder: prefer readable table sections over inline tables ([#​2649](mikefarah/yq#2649)) - Fix TOML encoder to quote keys containing special characters ([#​2648](mikefarah/yq#2648)) - Add string slicing support ([#​2639](mikefarah/yq#2639)) - Fix findInArray misuse on MappingNodes in equality and contains ([#​2645](mikefarah/yq#2645)) Thanks [@​jandubois](https://github.com/jandubois)! - Fix panic on negative slice indices that underflow after adjustment ([#​2646](mikefarah/yq#2646)) Thanks [@​jandubois](https://github.com/jandubois)! - Fix stack overflow from circular alias in traverse ([#​2647](mikefarah/yq#2647)) Thanks [@​jandubois](https://github.com/jandubois)! - Fix panic and OOM in repeatString for large repeat counts ([#​2644](mikefarah/yq#2644)) Thanks [@​jandubois](https://github.com/jandubois)! - Bumped dependencies ### [`v4.52.5`](https://github.com/mikefarah/yq/releases/tag/v4.52.5) [Compare Source](mikefarah/yq@v4.52.4...v4.52.5) - Fix: reset TOML decoder state between files ([#​2634](mikefarah/yq#2634)) thanks [@​terminalchai](https://github.com/terminalchai) - Fix: preserve original filename when using --front-matter ([#​2613](mikefarah/yq#2613)) thanks [@​cobyfrombrooklyn-bot](https://github.com/cobyfrombrooklyn-bot) - Fix typo in filename ([#​2611](mikefarah/yq#2611)) thanks [@​alexandear](https://github.com/alexandear) - Bumped dependencies </details> --- ### Configuration 📅 **Schedule**: (in timezone Europe/London) - Branch creation - At any time (no schedule defined) - Automerge - At any time (no schedule defined) 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. ♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box --- This PR has been generated by [Mend Renovate](https://github.com/renovatebot/renovate). <!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My4yNjAuMiIsInVwZGF0ZWRJblZlciI6IjQzLjI2MC4yIiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6WyJyZW5vdmF0ZS9naXRodWItcmVsZWFzZSIsInR5cGUvbWlub3IiXX0=--> Reviewed-on: https://forgejo.hayden.moe/hayden/phoebe/pulls/363
Adds a
systemoperator that executes an external command and returns its stdout as a string value. Disabled by default for security — requires explicit opt-in via--security-enable-system-operator.Behaviour
"system operations are disabled, use --security-enable-system-operator to enable"), consistent with--security-disable-env-opsand--security-disable-file-ops!!strNote: When enabled, the system operator can replicate the functionality of
envandloadoperators via external commands. Enabling it effectively overrides--security-disable-env-opsand--security-disable-file-ops.Changes
security_prefs.go— addsEnableSystemOps bool(defaultfalse)operator_system.go— operator implementation; supportssystem("cmd"),system("cmd"; "arg"), andsystem("cmd"; ["arg1", "arg2"]); captures stderr in error messages; validates command is a non-empty!!strscalar (rejects!!null,!!int,!!bool, etc.); evaluates command/args per matched node usingSingleReadonlyChildContext; returns error when disabled (consistent with env/file operators);resolveSystemArgsreturns([]string, error)— errors on invalid arg types; logs debug when args expression returns multiple resultsoperation.go— registerssystemOpTypelexer_participle.go— registerssimpleOp("system", systemOpType)cmd/root.go— adds--security-enable-system-operatorpersistent flag (consistent with--security-disable-env-ops/--security-disable-file-ops)operator_system_test.go— covers disabled (error) state, enabled state, array args, per-node expression evaluation, null/integer command errors, command failure, and multi-document iteration; usesexec.LookPathfor portabilitydoc/operators/headers/system-operators.md— documentation header with security note about overriding env/file restrictions and corrected description of the;separator📱 Kick off Copilot coding agent tasks wherever you are with GitHub Mobile, available on iOS and Android.