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

Proposal for escaping within lexed content #1152

Merged
merged 4 commits into from
Jun 4, 2019
Merged

Proposal for escaping within lexed content #1152

merged 4 commits into from
Jun 4, 2019

Conversation

jneen
Copy link
Member

@jneen jneen commented Jun 3, 2019

We often receive requests to do things such as underline sections of code, or embed arbitrary html inside of highlighted content. This PR is a proposal to address such features, using a similar tactic as Pygments.

We provide a special Escape lexer, which is capable of taking user-defined escape delimiters (default <! and !>) and rendering their contents into the Escape token (also from Pygments). In the HTML formatter (and potentially other formatters), we can allow the Escape token to pass as a raw value.

IMPORTANT

There is a major security concern with this feature: in some applications (such as Gitlab), an untrusted user will control all of the input text, the lexer choice, and the lexer options. We cannot allow such users to pass unescaped HTML into the output.

For this reason, escaping is disabled by default - the base Formatter class will filter all Escape tokens and replace them with Error tokens before passing the token stream to the stream method. In order to enable this feature, a user must explicitly call Rouge::Formatter.enable_escape!. It can also be enabled thread-locally with Rouge::Formatter.with_escape { ... } and explicitly disallowed with Rouge::Formatter.disable_escape!. I think this should have the correct secure defaults and extension opportunities for most applications, but I would appreciate additional security review.

cc @stanhu

@jneen jneen force-pushed the feature.escape branch from 931a5f9 to 444b3b0 Compare June 3, 2019 07:33
@pyrmont pyrmont added the needs-review The PR needs to be reviewed label Jun 3, 2019
@ashmaroli
Copy link
Contributor

ashmaroli commented Jun 3, 2019

@jneen Is the overlap with changes in #1151 a conscious move or mistake?

If a conscious move, please add a "Depends on #1151" somewhere in the OP so that it is clear that this should be merged only after #1151

@jneen
Copy link
Member Author

jneen commented Jun 3, 2019

Good point, we do depend on #1151. I will rebase once that is merged.

@jneen jneen changed the title Proposal for escaping within lexed content Proposal for escaping within lexed content (depends on #1151) Jun 3, 2019
@jneen jneen requested a review from dblessing June 3, 2019 08:28
lib/rouge/lexers/escape.rb Outdated Show resolved Hide resolved
Copy link
Collaborator

@dblessing dblessing left a comment

Choose a reason for hiding this comment

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

Looks and sounds fine from my perspective. I like that it is disabled by default. I'm interested in hearing from @stanhu on whether or how he thinks we might be able to utilize this in GitLab. If not, that's fine. It's still interesting for others.

@jneen jneen force-pushed the feature.escape branch from d5165ef to 0e5f5dd Compare June 3, 2019 23:07
@jneen
Copy link
Member Author

jneen commented Jun 3, 2019

I have rebased, and now I believe it's ready to merge pending yall's +1.

@jneen
Copy link
Member Author

jneen commented Jun 3, 2019

I also added escape functionality to the CLI, which is where I confess I actually need it at this moment, for use in the TeX formatter I'm working on.

@jneen jneen changed the title Proposal for escaping within lexed content (depends on #1151) Proposal for escaping within lexed content Jun 3, 2019
@pyrmont pyrmont merged commit 2e140d8 into master Jun 4, 2019
@pyrmont pyrmont removed the needs-review The PR needs to be reviewed label Jun 4, 2019
@tancnle tancnle deleted the feature.escape branch September 22, 2021 12:24
ole added a commit to ole/middleman-syntax that referenced this pull request Nov 10, 2022
Option in config.rb:

    activate :syntax, :escape => true

This enables Rouge's Escape lexer (introduced in rouge-ruby/rouge#1152), which is useful for formatting/highlighting individual pieces of a code block. This lexer passes the contents of <! … !> sections unchanged as a raw value into the resulting HTML, effectively allowing you to add inline HTML formatting into a code block at arbitrary places.

WARNING: As described in rouge-ruby/rouge#1152, this can be a major security risk if you don't control the input to the lexer. Don't enable this option for formatting e.g. user-generated content.

Example Markdown (Kramdown):

~~~swift
func add(_ x: Int, y: Int) -> Int {
    return <!<span style="text-decoration: underline;"> !>x + y<!</span>!>
}
~~~
ole added a commit to ole/middleman-syntax that referenced this pull request Nov 10, 2022
Option in config.rb:

    activate :syntax, :escape => true

This enables Rouge's Escape lexer (introduced in rouge-ruby/rouge#1152), which is useful for formatting/highlighting individual pieces of a code block. This lexer passes the contents of <! … !> sections unchanged as a raw value into the resulting HTML, effectively allowing you to add inline HTML formatting into a code block at arbitrary places.

WARNING: As described in rouge-ruby/rouge#1152, this can be a major security risk if you don't control the input to the lexer. Don't enable this option for formatting e.g. user-generated content.

Example Markdown (Kramdown):

~~~swift
func add(_ x: Int, y: Int) -> Int {
    return <!<span style="text-decoration: underline;"> !>x + y<!</span>!>
}
~~~
joshuap added a commit to honeybadger-io/middleman-syntax that referenced this pull request Feb 1, 2023
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.

4 participants