Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: support hidden code lines #254

Merged
merged 12 commits into from
Jul 8, 2024

Conversation

dmackdev
Copy link
Contributor

@dmackdev dmackdev commented May 27, 2024

This PR adds support for hidden code lines for the languages Rust, Python, Shell and Bash using prefixes at the start of the line, particular to each language. Support for more languages can be added in future.

The hidden code lines will not be visible in snippets in the presentation, but still be evaluated as normal if executed.

See the example presentation for demonstration.

@dmackdev dmackdev force-pushed the feat/support-hidden-code-lines branch from e9259eb to f9bdfc0 Compare May 27, 2024 16:18
@dmackdev
Copy link
Contributor Author

dmackdev commented May 27, 2024

From #242 (comment):

@dmackdev I think it would be nice if we didn't use /// for every language but this was configurable instead (defaulting to nothing so we don't have to preemptively define it for every language we support highlighting for). /// is valid rust so that would mean I can no longer use doc comments in code snippets, and even worse it would be pretty confusing if you don't know about this, add a /// section and then it doesn't show up in the presentation.

I like the doc tests approach in rust better where # is used to hide lines, see this. Could this be made optional and language-defined so CodeLanguage has some fn hidden_line_prefix(&self) -> Option<&'static str> that can be used to configure this? If you'd like to create the PR and move the conversation there that'd be great.

Totally makes sense @mfontanini - I can make those changes.

So is the thinking that from CodeLanguage::hidden_line_prefix, we return Some("#") for CodeLanguage::Rust, something for CodeLanguage::Bash/Shell, and None for all other languages for now, and we can support for "hidden code lines" for more languages as we go?

@dmackdev
Copy link
Contributor Author

I'd imagine that not all of the supported languages definitely have some equivalent for this prefix in their own docs' syntax. Would we just decide on some sensible prefix in those cases, should the need arise?

@mfontanini
Copy link
Owner

Would we just decide on some sensible prefix in those cases, should the need arise?

Yeah I'd fix those as they come. I imagine in most cases, rust being an exception, the hidden line prefix would be an extension to the language's comment syntax. So e.g. for python/shell script it could be ##, for java /// (but I don't know if this is used for something specifically so I'm unsure). But I wouldn't commit to a default for all languages blindly just in case as it may have a meaning in some of them already.

pub(crate) fn hidden_line_prefix(&self) -> Option<&'static str> {
match self {
CodeLanguage::Rust => Some("# "),
CodeLanguage::Python | CodeLanguage::Shell(_) | CodeLanguage::Bash => Some("## "),
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I wonder if there is a better prefix over to use for these languages since a single # denotes a comment in them, so if you wanted to show comments in the snippet, that could potentially be confusing?

Copy link
Owner

Choose a reason for hiding this comment

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

How about using ///? I only dislike that in rust because it has a meaning but for the rest of the languages that could work.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

That makes sense, can roll with ///.

@@ -0,0 +1,111 @@
---
Copy link
Contributor Author

@dmackdev dmackdev May 28, 2024

Choose a reason for hiding this comment

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

This presentation was primarily for demonstration purposes (especially around the line numbering and highlighting). Let me know if you think I should remove/amend it @mfontanini.

Copy link
Owner

Choose a reason for hiding this comment

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

This is great but for now I'd like to remove it. I usually write docs about new features along when I'm about to release the next version, and I'll use some of these examples there. I'm planning on, besides having docs for this (and snippet code execution in general, touching the examples/code.md example presentation to include more cases like these ones.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Removed.

@dmackdev dmackdev marked this pull request as ready for review May 28, 2024 18:42
@mfontanini
Copy link
Owner

I'm starting to have second thoughts about this change, specifically from the security angle. With this change you could run a code snippet in a presentation and it could do something like an rm -rf $HOME or other malicious actions without you knowing ahead of time. I think this could make people not want to share presentations / run someone else's presentations. The same goes for the "local executors to the presentation file" that we mentioned in the other issue. If we let the user define this on a per presentation basis, we'd be giving them arbitrary code execution capabilities on whoever runs their presentations' machines.

Thoughts? Am I too paranoid?

@dmackdev
Copy link
Contributor Author

A good point. I think the risk of executing malicious code is present regardless of hidden code lines. All it would take is a user to execute code in a presentation without actually inspecting/understanding: the snippet as it is seen in the presentation, the markdown file, or any local executors. Even without hidden code lines and local executors, there has to be some level of trust that a shared/downloaded presentation does not contain malicious code snippets. Of course, hidden code lines/local executor scripts could elevate this risk - if users rely only on viewing the presentation output and do not inspect the sources.

Indeed, other tools like patat disclose a warning about executing arbitrary code from presentations.

But perhaps we could add some sort of safeguard around this for hidden code lines - maybe a CLI flag --enable-hidden-code-lines, so users have to explicitly take some action to actually hide the prefixed code lines in the presentation. Without the flag, the prefixed code lines would appear in the presentation as normal (without the prefix). Not sure if that would be too much overhead for users, but just a thought.

@mfontanini
Copy link
Owner

there has to be some level of trust that a shared/downloaded presentation does not contain malicious code snippets

Yeah, definitely, but hidden code lines make this a lot more dangerous.

maybe a CLI flag --enable-hidden-code-lines, so users have to explicitly take some action to actually hide the prefixed code lines in the presentation

I agree, if this was implemented we'd need this. However, then it would become annoying for the user that's building a presentation. Now, we could put this as a config option in the config file but this ends up defeating the purpose with foreign presentations. I have mixed feelings about this :/

@dmackdev
Copy link
Contributor Author

dmackdev commented Jun 8, 2024

Fair enough @mfontanini.
In the absence of any other ideas or a way forward to address the security concerns, feel free to close this PR 🙂

@mfontanini mfontanini mentioned this pull request Jul 3, 2024
Copy link
Owner

@mfontanini mfontanini left a comment

Choose a reason for hiding this comment

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

Hey @dmackdev, I'm reviving this! I recently added a configuration/CLI arg that you need to use to explicitly enable snippet code execution in #276. Since that was my main concern and it's now there, I'd like to get this PR in as it adds a lot of value.

I left a couple of comments and it looks like there's some conflicts as well.

Comment on lines 199 to 203
let mut line = format!("{}\n", line);
if line.starts_with(prefix) {
line.replace_range(..prefix.len(), "");
}
line
Copy link
Owner

Choose a reason for hiding this comment

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

I think you can replace all of this with something like

let line = line.strip_prefix(prefix).unwrap_or(&line);
format!("{line}\n")

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Nice one! I have made that change, but also updated it to use fold instead of map as per the Clippy suggestion.

@@ -0,0 +1,111 @@
---
Copy link
Owner

Choose a reason for hiding this comment

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

This is great but for now I'd like to remove it. I usually write docs about new features along when I'm about to release the next version, and I'll use some of these examples there. I'm planning on, besides having docs for this (and snippet code execution in general, touching the examples/code.md example presentation to include more cases like these ones.

pub(crate) fn hidden_line_prefix(&self) -> Option<&'static str> {
match self {
CodeLanguage::Rust => Some("# "),
CodeLanguage::Python | CodeLanguage::Shell(_) | CodeLanguage::Bash => Some("## "),
Copy link
Owner

Choose a reason for hiding this comment

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

How about using ///? I only dislike that in rust because it has a meaning but for the rest of the languages that could work.

@dmackdev dmackdev requested a review from mfontanini July 8, 2024 08:23
@mfontanini mfontanini merged commit 480f947 into mfontanini:master Jul 8, 2024
6 checks passed
@mfontanini
Copy link
Owner

Thanks, this is great!

@dmackdev dmackdev deleted the feat/support-hidden-code-lines branch July 8, 2024 15:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants