mirror of
https://github.com/nim-lang/Nim.git
synced 2026-08-03 22:18:40 +00:00
1. A trailing `$` at the end of a replacement string could read out of
bounds via `how[i + 1]`; this now raises `ValueError` instead.
2. Numeric capture parsing used `id += (id * 10) + digit` instead of `id
= (id * 10) + digit`, so multi-digit refs were parsed incorrectly (e.g.
`$12` resolved as capture 13 instead of 12).
4. Unterminated named replacement syntax (e.g. `${foo)` is now rejected
with ValueError instead of being accepted and parsed inconsistently.
Found and fixed by GPT 5.3 Codex.
57 lines
1.6 KiB
Nim
57 lines
1.6 KiB
Nim
## INTERNAL FILE FOR USE ONLY BY nre.nim.
|
|
import std/tables
|
|
|
|
const Ident = {'a'..'z', 'A'..'Z', '0'..'9', '_', '\128'..'\255'}
|
|
const StartIdent = Ident - {'0'..'9'}
|
|
|
|
template formatStr*(howExpr, namegetter, idgetter): untyped =
|
|
let how = howExpr
|
|
var val = newStringOfCap(how.len)
|
|
var i = 0
|
|
var lastNum = 1
|
|
|
|
while i < how.len:
|
|
if how[i] != '$':
|
|
val.add(how[i])
|
|
i += 1
|
|
else:
|
|
if i + 1 >= how.len:
|
|
raise newException(ValueError, "Syntax error in format string at " & $i)
|
|
|
|
if how[i + 1] == '$':
|
|
val.add('$')
|
|
i += 2
|
|
elif how[i + 1] == '#':
|
|
var id {.inject.} = lastNum
|
|
val.add(idgetter)
|
|
lastNum += 1
|
|
i += 2
|
|
elif how[i + 1] in {'0'..'9'}:
|
|
i += 1
|
|
var id {.inject.} = 0
|
|
while i < how.len and how[i] in {'0'..'9'}:
|
|
id = (id * 10) + (ord(how[i]) - ord('0'))
|
|
i += 1
|
|
val.add(idgetter)
|
|
lastNum = id + 1
|
|
elif how[i + 1] in StartIdent:
|
|
i += 1
|
|
var name {.inject.} = ""
|
|
while i < how.len and how[i] in Ident:
|
|
name.add(how[i])
|
|
i += 1
|
|
val.add(namegetter)
|
|
elif how[i + 1] == '{':
|
|
i += 2
|
|
var name {.inject.} = ""
|
|
while i < how.len and how[i] != '}':
|
|
name.add(how[i])
|
|
i += 1
|
|
if i >= how.len or how[i] != '}':
|
|
raise newException(ValueError, "Syntax error in format string at " & $i)
|
|
i += 1
|
|
val.add(namegetter)
|
|
else:
|
|
raise newException(ValueError, "Syntax error in format string at " & $i)
|
|
val
|