Skip to content

Commit cd0208c

Browse files
committed
Escape single '<' and '>' in text.
This prevents cli_bullet_raw() from evaluating variables inside <>, which would lead to a crash, as the parent environment by design is not passed along.
1 parent 14bb86c commit cd0208c

File tree

4 files changed

+121
-0
lines changed

4 files changed

+121
-0
lines changed

NEWS.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@
33
* New `{.num}` and `{.bytes}` inline styles to format numbers
44
and bytes (@m-muecke, #644, #588, #643).
55

6+
* Fix escaping of `<>` so that `cli_bullets_raw()` doesn't attempt to
7+
perform string interpolation on them (@mcol, #789).
8+
69
# cli 3.6.5
710

811
* `code_highlight()` supports long strings and symbols

R/utils.R

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ has_packages <- function(pkgs) {
1313
cli_escape <- function(x) {
1414
x <- gsub("{", "{{", x, fixed = TRUE)
1515
x <- gsub("}", "}}", x, fixed = TRUE)
16+
x <- gsub("<", "<<", x, fixed = TRUE)
17+
x <- gsub(">", ">>", x, fixed = TRUE)
1618
x
1719
}
1820

tests/testthat/_snaps/bullets.md

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -214,3 +214,99 @@
214214
→ This is some text that is longer than the width. This is some text that is
215215
longer than the width. This is some text that is longer than the width.
216216

217+
# bullets_raw glue [plain]
218+
219+
Code
220+
cli_bullets_raw(c("noindent {.key {1:3}}", ` ` = "space {.key {1:3}}", v = "success {.key {1:3}}",
221+
x = "danger {.key {1:3}}", `!` = "warning {.key {1:3}}", i = "info {.key {1:3}}",
222+
`*` = "bullet {.key {1:3}}", `>` = "arrow {.key {1:3}}"))
223+
Message
224+
noindent {{.key {{1:3}}}}
225+
space {{.key {{1:3}}}}
226+
v success {{.key {{1:3}}}}
227+
x danger {{.key {{1:3}}}}
228+
! warning {{.key {{1:3}}}}
229+
i info {{.key {{1:3}}}}
230+
* bullet {{.key {{1:3}}}}
231+
> arrow {{.key {{1:3}}}}
232+
233+
# bullets_raw glue [ansi]
234+
235+
Code
236+
cli_bullets_raw(c("noindent {.key {1:3}}", ` ` = "space {.key {1:3}}", v = "success {.key {1:3}}",
237+
x = "danger {.key {1:3}}", `!` = "warning {.key {1:3}}", i = "info {.key {1:3}}",
238+
`*` = "bullet {.key {1:3}}", `>` = "arrow {.key {1:3}}"))
239+
Message
240+
noindent {{.key {{1:3}}}}
241+
space {{.key {{1:3}}}}
242+
v success {{.key {{1:3}}}}
243+
x danger {{.key {{1:3}}}}
244+
! warning {{.key {{1:3}}}}
245+
i info {{.key {{1:3}}}}
246+
* bullet {{.key {{1:3}}}}
247+
> arrow {{.key {{1:3}}}}
248+
249+
# bullets_raw glue [unicode]
250+
251+
Code
252+
cli_bullets_raw(c("noindent {.key {1:3}}", ` ` = "space {.key {1:3}}", v = "success {.key {1:3}}",
253+
x = "danger {.key {1:3}}", `!` = "warning {.key {1:3}}", i = "info {.key {1:3}}",
254+
`*` = "bullet {.key {1:3}}", `>` = "arrow {.key {1:3}}"))
255+
Message
256+
noindent {{.key {{1:3}}}}
257+
space {{.key {{1:3}}}}
258+
✔ success {{.key {{1:3}}}}
259+
✖ danger {{.key {{1:3}}}}
260+
! warning {{.key {{1:3}}}}
261+
ℹ info {{.key {{1:3}}}}
262+
• bullet {{.key {{1:3}}}}
263+
→ arrow {{.key {{1:3}}}}
264+
265+
# bullets_raw glue [fancy]
266+
267+
Code
268+
cli_bullets_raw(c("noindent {.key {1:3}}", ` ` = "space {.key {1:3}}", v = "success {.key {1:3}}",
269+
x = "danger {.key {1:3}}", `!` = "warning {.key {1:3}}", i = "info {.key {1:3}}",
270+
`*` = "bullet {.key {1:3}}", `>` = "arrow {.key {1:3}}"))
271+
Message
272+
noindent {{.key {{1:3}}}}
273+
space {{.key {{1:3}}}}
274+
✔ success {{.key {{1:3}}}}
275+
✖ danger {{.key {{1:3}}}}
276+
! warning {{.key {{1:3}}}}
277+
ℹ info {{.key {{1:3}}}}
278+
• bullet {{.key {{1:3}}}}
279+
→ arrow {{.key {{1:3}}}}
280+
281+
# bullets_raw handles <> (#789) [plain]
282+
283+
Code
284+
cli_bullets_raw(c("{.field field} <x>", "{.field field} <<x>>"))
285+
Message
286+
{{.field field}} <x>
287+
{{.field field}} <<x>>
288+
289+
# bullets_raw handles <> (#789) [ansi]
290+
291+
Code
292+
cli_bullets_raw(c("{.field field} <x>", "{.field field} <<x>>"))
293+
Message
294+
{{.field field}} <x>
295+
{{.field field}} <<x>>
296+
297+
# bullets_raw handles <> (#789) [unicode]
298+
299+
Code
300+
cli_bullets_raw(c("{.field field} <x>", "{.field field} <<x>>"))
301+
Message
302+
{{.field field}} <x>
303+
{{.field field}} <<x>>
304+
305+
# bullets_raw handles <> (#789) [fancy]
306+
307+
Code
308+
cli_bullets_raw(c("{.field field} <x>", "{.field field} <<x>>"))
309+
Message
310+
{{.field field}} <x>
311+
{{.field field}} <<x>>
312+

tests/testthat/test-bullets.R

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,3 +40,23 @@ test_that_cli("bullets wrapping", {
4040
">" = txt
4141
)))
4242
})
43+
44+
test_that_cli("bullets_raw glue", {
45+
expect_snapshot(cli_bullets_raw(c(
46+
"noindent {.key {1:3}}",
47+
" " = "space {.key {1:3}}",
48+
"v" = "success {.key {1:3}}",
49+
"x" = "danger {.key {1:3}}",
50+
"!" = "warning {.key {1:3}}",
51+
"i" = "info {.key {1:3}}",
52+
"*" = "bullet {.key {1:3}}",
53+
">" = "arrow {.key {1:3}}"
54+
)))
55+
})
56+
57+
test_that_cli("bullets_raw handles <> (#789)", {
58+
expect_snapshot(cli_bullets_raw(c(
59+
"{.field field} <x>",
60+
"{.field field} <<x>>"
61+
)))
62+
})

0 commit comments

Comments
 (0)