r-lib / downlit

Syntax Highlighting and Automatic Linking
https://downlit.r-lib.org
Other
90 stars 22 forks source link

BASH globs accidentally interpeted as help queries #137

Closed zkamvar closed 2 years ago

zkamvar commented 2 years ago

Problem

href_topic() assumes that the topic is length 1, but this is not always the case if you try to use parsed BASH code with wildcards.

I ran into an interesting issue when trying to parse the following markdown list:

1. `ls *t*ane.pdb`
2. `ls *t?ne.*`
3. `ls *t??ne.pdb`
4. `ls ethane.*`

Downlit threw this error:

Error in if (has_name(index, topic)) { : the condition has length > 1

Reprex

The error is reproducible via downlit::downlit_html_node(), but I found that this is best explained starting at downlit:::href_expr():

expr <- parse(text = "ls *t??ne.pdb")
downlit:::href_expr(expr[[1]])
#> Error in if (has_name(index, topic)) {: the condition has length > 1

Created on 2022-05-16 by the reprex package (v2.0.1)

The reason why this fails: R tries to interpret this as valid R code:

expr <- parse(text = "ls *t??ne.pdb")
expr[[1]] # R thinks we are looking for the ls * t type in the ne.pdb topic
#> `?`(ls * t, `?`(ne.pdb))
as.character(expr[[1]][[2]]) # `ls * t` parses as a three-element character vector, which is then passed to href_topic()
#> [1] "*"  "ls" "t"

Created on 2022-05-16 by the reprex package (v2.0.1)

Solution

I think this can be fixed by checking that the topic is length 1 in href_topic and returning NA_character_ if it's greater than length 1:

https://github.com/r-lib/downlit/blob/4011b2f470750dc51a8001eaa739dbcff257ffb1/R/link.R#L151-L157