Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 17 additions & 9 deletions docs/netsuke-design.md
Original file line number Diff line number Diff line change
Expand Up @@ -170,11 +170,16 @@ Each entry in the `rules` list is a mapping that defines a reusable action.

- `command`: A single command string to be executed. This string uses
placeholders like `{{ ins }}` and `{{ outs }}` for input and output files.
Netsuke's IR-to-Ninja generator will translate these into Ninja's native `$in`
and `$out` variables.
Netsuke's IR-to-Ninja generator will translate these into Ninja's native $in
and $out variables. After interpolation, the value must be parsable by the
[`shlex`](https://docs.rs/shlex/latest/shlex/) crate. Any interpolation other
than `ins` or `outs` is automatically shell escaped.

- `script`: A multi-line script declared with the YAML `|` block style. The
entire block is passed to an interpreter (currently `/bin/sh`).
entire block is passed to an interpreter (currently `/bin/sh`). For `/bin/sh`
scripts, each interpolation is automatically passed through the `shell_escape`
filter unless a `| raw` filter is applied. Future versions will allow
configurable script languages with their own escaping rules.

Exactly one of `command` or `script` must be provided. The manifest parser
enforces this rule to prevent invalid states.
Expand Down Expand Up @@ -848,12 +853,15 @@ The command generation logic within the `ninja_gen.rs` module must not use
simple string formatting (like `format!`) to construct the final command strings
for the `build.ninja` file. Doing so would be inherently insecure.

Instead, the implementation must parse the Netsuke command template (e.g., `{cc}
-c {ins} -o {outs}`) and build the final command string piece by piece. For
each segment of the command, if it is a variable substitution (like `{ins}`),
the value of that variable must be passed through the `shell-quote` API before
being appended to the output string. This ensures that every dynamic part of the
command is correctly and safely quoted for the target shell.
Instead, the implementation must parse the Netsuke command template (e.g.,
`{cc} -c {ins} -o {outs}`) and build the final command string piece by piece.
The placeholders `{{ ins }}` and `{{ outs }}` remain as Ninja's $in and $out
variables. After substitution, Netsuke verifies that the resulting command
string can be parsed by the `shlex` crate. For each segment of the command, if
it is a variable substitution (like `{ins}`), the value of that variable must be
passed through the `shell-quote` API before being appended to the output string.
This ensures that every dynamic part of the command is correctly and safely
quoted for the target shell.

### 6.4 Automatic Security as a "Friendliness" Feature

Expand Down
2 changes: 2 additions & 0 deletions docs/roadmap.md
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,8 @@ CLI ergonomics.
- [ ] **Mandate** its use for all variable substitutions within the `command`
strings during Ninja file synthesis to prevent command injection
vulnerabilities. This is a critical security feature.
- [ ] Ensure the interpolated `command` value parses successfully with
`shlex`.

Comment on lines +118 to 120
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick (assertive)

Wrap the new checklist line to 80 columns.

The added bullet slightly exceeds the mandated 80-column limit for Markdown list items. Re-wrap and align the continuation to keep markdownlint (MD013) happy.

-  - [ ] Ensure the interpolated `command` value parses successfully with `shlex`
+  - [ ] Ensure the interpolated `command` value parses successfully
+        with `shlex`
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
- [ ] Ensure the interpolated `command` value parses successfully with
`shlex`.
- [ ] Ensure the interpolated `command` value parses successfully
with `shlex`
🤖 Prompt for AI Agents
In docs/roadmap.md around lines 118 to 120, the new checklist line exceeds the
80-column limit for Markdown list items. Reformat the line by wrapping the text
so that no line goes beyond 80 characters, and align the continuation lines
properly to maintain Markdown list formatting and satisfy markdownlint (MD013).

- [ ] Implement custom Jinja filters for shell safety and path manipulation,
such as `| shell_escape`, `| to_path`, and `| parent`.
Expand Down