Skip to content

Commit

Permalink
a better way to escape data
Browse files Browse the repository at this point in the history
Signed-off-by: George Lemon <[email protected]>
  • Loading branch information
georgelemon committed Apr 25, 2024
1 parent 7f26fcc commit f6331d7
Show file tree
Hide file tree
Showing 3 changed files with 24 additions and 19 deletions.
13 changes: 6 additions & 7 deletions src/tim/engine/ast.nim
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ type
ntMathInfixExpr = "MathExpression"
ntCommandStmt = "CommandStatement"
ntIdent = "Identifier"
ntEscape = "EscapedIdentifier"
ntCall = "FunctionCall"
ntIdentPair
ntDotExpr = "DotExpression"
Expand Down Expand Up @@ -191,11 +192,8 @@ type
identSafe*: bool
# whether to escape the stored value of `identName`
identArgs*: seq[Node]
# of ntCall:
# callIdent*: string
# ## identifier name of a callable function
# callArgs*: seq[Node]
# ## a sequence of arguments to to pass
of ntEscape:
escapeIdent*: Node # ntIdent
of ntDotExpr:
storageType*: StorageType
## holds the storage type of a dot expression
Expand Down Expand Up @@ -489,8 +487,9 @@ proc `$`*(x: Ast): string =
toJson(x)

when not defined release:
proc debugEcho*(node: Node) =
echo pretty(toJson(node), 2)
proc debugEcho*(node: Node) {.gcsafe.} =
{.gcsafe.}:
echo pretty(toJson(node), 2)

#
# AST Generators
Expand Down
10 changes: 8 additions & 2 deletions src/tim/engine/compilers/html.nim
Original file line number Diff line number Diff line change
Expand Up @@ -759,6 +759,10 @@ proc getValue(c: var HtmlCompiler, node: Node,
if node.identArgs.len > 0:
compileErrorWithArgs(fnUndeclared, [node.identName])
compileErrorWithArgs(undeclaredVariable, [node.identName])
of ntEscape:
result = c.getValue(node.escapeIdent, scopetables)
notnil result:
result.sVal = result.sVal.escapeValue
of ntAssignableSet, ntIndexRange:
# return literal nodes
result = node
Expand Down Expand Up @@ -1338,16 +1342,18 @@ proc getAttrs(c: var HtmlCompiler, attrs: HtmlAttributes,
add attrStr, c.toString(attrNode, scopetables)
of ntLitObject, ntLitArray:
add attrStr, c.toString(attrNode, scopetables, escape = true)
of ntEscape:
let xVal = c.getValue(attrNode, scopetables)
notnil xVal:
add attrStr, xVal.toString.escapeValue
of ntIdent:
let xVal = c.getValue(attrNode, scopetables)
notnil xVal:
add attrStr, xVal.toString(xVal.nt in [ntLitObject, ntLitArray])
# else: return # undeclaredVariable
of ntDotExpr:
let xVal = c.dotEvaluator(attrNode, scopetables)
notnil xVal:
add attrStr, xVal.toString()
# else: return # undeclaredVariable
else: discard
if not c.isClientSide:
add result, attrStr.join(" ")
Expand Down
20 changes: 10 additions & 10 deletions src/tim/engine/parser.nim
Original file line number Diff line number Diff line change
Expand Up @@ -348,6 +348,7 @@ proc parseBracketExpr(p: var Parser, lhs: Node): Node {.gcsafe.} =

prefixHandle pIdent:
# parse an identifier
var isEscaped = p.curr is tkIdentVarSafe
result = ast.newIdent(p.curr)
let storageType = p.getStorageType()
walk p
Expand Down Expand Up @@ -380,6 +381,10 @@ prefixHandle pIdent:
of tkTernary:
result = p.parseTernaryExpr(result)
else: discard
if isEscaped:
var safeVarNode = ast.newNode(ntEscape)
safeVarNode.escapeIdent = result
return safeVarNode

prefixHandle pIdentOrAssignment:
let ident = p.curr
Expand All @@ -389,8 +394,8 @@ prefixHandle pIdentOrAssignment:
caseNotNil varValue:
return ast.newAssignment(ident, varValue)
result = p.pIdent()
if result.nt == ntIdent:
result.identSafe = ident.kind == tkIdentVarSafe
# if result.nt == ntIdent:
# result.identSafe = ident.kind == tkIdentVarSafe

prefixHandle pAssignment:
# parse assignment
Expand All @@ -414,27 +419,22 @@ prefixHandle pEchoCommand:
let tk = p.curr
walk p
var varNode: Node
var isEscaped: bool
case p.curr.kind
of tkAssignableSet:
if p.curr in {tkIdentVar, tkIdentVarSafe}:
let safeEscape = p.curr is tkIdentVarSafe
isEscaped = p.curr is tkIdentVarSafe
if p.next.isInfix:
varNode = p.getPrefixOrInfix()
else:
varNode = p.pIdent()
case varNode.nt
of ntIdent:
varNode.identSafe = safeEscape
of ntDotExpr:
varNode.lhs.identSafe = safeEscape
else: discard
if p.curr.isInfix and p.curr.line == p.prev.line:
# todo move line checker to `isInfix`
varNode = p.parseInfix(varNode)
else:
varNode = p.getPrefixOrInfix()
caseNotNil varNode:
return ast.newCommand(cmdEcho, varNode, tk)
return ast.newCommand(cmdEcho, varNode, tk)
else: errorWithArgs(unexpectedToken, p.curr, [p.curr.value])

prefixHandle pReturnCommand:
Expand Down

0 comments on commit f6331d7

Please sign in to comment.