[feature] add arbitrary code execution to strformat (#17694)
* changed parser to ignore ':' within parens * Update strformat.nim * Update lib/pure/strformat.nim Co-authored-by: flywind <xzsflywind@gmail.com> Co-authored-by: Andreas Rumpf <rumpf_a@web.de>
This commit is contained in:
parent
3aaec0647b
commit
a5b30c94c2
1 changed files with 28 additions and 9 deletions
|
|
@ -74,6 +74,20 @@ runnableExamples:
|
||||||
assert fmt"{123.456:13e}" == " 1.234560e+02"
|
assert fmt"{123.456:13e}" == " 1.234560e+02"
|
||||||
|
|
||||||
##[
|
##[
|
||||||
|
# Expressions
|
||||||
|
]##
|
||||||
|
runnableExamples:
|
||||||
|
let x = 3.14
|
||||||
|
assert fmt"{(if x!=0: 1.0/x else: 0):.5}" == "0.31847"
|
||||||
|
assert fmt"""{(block:
|
||||||
|
var res: string
|
||||||
|
for i in 1..15:
|
||||||
|
res.add (if i mod 15 == 0: "FizzBuzz"
|
||||||
|
elif i mod 5 == 0: "Buzz"
|
||||||
|
elif i mod 3 == 0: "Fizz"
|
||||||
|
else: $i) & " "
|
||||||
|
res)}""" == "1 2 Fizz 4 Buzz Fizz 7 8 Fizz Buzz 11 Fizz 13 14 FizzBuzz "
|
||||||
|
##[
|
||||||
# Debugging strings
|
# Debugging strings
|
||||||
|
|
||||||
`fmt"{expr=}"` expands to `fmt"expr={expr}"` namely the text of the expression,
|
`fmt"{expr=}"` expands to `fmt"expr={expr}"` namely the text of the expression,
|
||||||
|
|
@ -557,7 +571,7 @@ proc strformatImpl(pattern: NimNode; openChar, closeChar: char): NimNode =
|
||||||
# XXX: https://github.com/nim-lang/Nim/issues/8405
|
# XXX: https://github.com/nim-lang/Nim/issues/8405
|
||||||
# When compiling with -d:useNimRtl, certain procs such as `count` from the strutils
|
# When compiling with -d:useNimRtl, certain procs such as `count` from the strutils
|
||||||
# module are not accessible at compile-time:
|
# module are not accessible at compile-time:
|
||||||
let expectedGrowth = when defined(useNimRtl): 0 else: count(f, '{') * 10
|
let expectedGrowth = when defined(useNimRtl): 0 else: count(f, openChar) * 10
|
||||||
result.add newVarStmt(res, newCall(bindSym"newStringOfCap",
|
result.add newVarStmt(res, newCall(bindSym"newStringOfCap",
|
||||||
newLit(f.len + expectedGrowth)))
|
newLit(f.len + expectedGrowth)))
|
||||||
var strlit = ""
|
var strlit = ""
|
||||||
|
|
@ -573,8 +587,12 @@ proc strformatImpl(pattern: NimNode; openChar, closeChar: char): NimNode =
|
||||||
strlit = ""
|
strlit = ""
|
||||||
|
|
||||||
var subexpr = ""
|
var subexpr = ""
|
||||||
while i < f.len and f[i] != closeChar and f[i] != ':':
|
var inParens = 0
|
||||||
if f[i] == '=':
|
while i < f.len and f[i] != closeChar and (f[i] != ':' or inParens!=0):
|
||||||
|
case f[i]
|
||||||
|
of '(': inc inParens
|
||||||
|
of ')': dec inParens
|
||||||
|
of '=':
|
||||||
let start = i
|
let start = i
|
||||||
inc i
|
inc i
|
||||||
i += f.skipWhitespace(i)
|
i += f.skipWhitespace(i)
|
||||||
|
|
@ -582,9 +600,10 @@ proc strformatImpl(pattern: NimNode; openChar, closeChar: char): NimNode =
|
||||||
result.add newCall(bindSym"add", res, newLit(subexpr & f[start ..< i]))
|
result.add newCall(bindSym"add", res, newLit(subexpr & f[start ..< i]))
|
||||||
else:
|
else:
|
||||||
subexpr.add f[start ..< i]
|
subexpr.add f[start ..< i]
|
||||||
else:
|
continue
|
||||||
subexpr.add f[i]
|
else: discard
|
||||||
inc i
|
subexpr.add f[i]
|
||||||
|
inc i
|
||||||
|
|
||||||
var x: NimNode
|
var x: NimNode
|
||||||
try:
|
try:
|
||||||
|
|
@ -608,11 +627,11 @@ proc strformatImpl(pattern: NimNode; openChar, closeChar: char): NimNode =
|
||||||
doAssert false, "invalid format string: missing '}'"
|
doAssert false, "invalid format string: missing '}'"
|
||||||
result.add newCall(formatSym, res, x, newLit(options))
|
result.add newCall(formatSym, res, x, newLit(options))
|
||||||
elif f[i] == closeChar:
|
elif f[i] == closeChar:
|
||||||
if f[i+1] == closeChar:
|
if i<f.len-1 and f[i+1] == closeChar:
|
||||||
strlit.add closeChar
|
strlit.add closeChar
|
||||||
inc i, 2
|
inc i, 2
|
||||||
else:
|
else:
|
||||||
doAssert false, "invalid format string: '}' instead of '}}'"
|
doAssert false, "invalid format string: '$1' instead of '$1$1'" % $closeChar
|
||||||
inc i
|
inc i
|
||||||
else:
|
else:
|
||||||
strlit.add f[i]
|
strlit.add f[i]
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue