vweb: escape html; table: rename parent_typ to parent_type

pull/5491/head
Alexander Medvednikov 2020-06-24 22:12:33 +02:00
parent 67d9d94fb3
commit 83b300435a
10 changed files with 71 additions and 35 deletions

View File

@ -44,7 +44,7 @@ fn main() {
foptions := FormatOptions{ foptions := FormatOptions{
is_c: '-c' in args is_c: '-c' in args
is_l: '-l' in args is_l: '-l' in args
is_w: '-w' in args is_w: '-ww' in args
is_diff: '-diff' in args is_diff: '-diff' in args
is_verbose: '-verbose' in args || '--verbose' in args is_verbose: '-verbose' in args || '--verbose' in args
is_all: '-all' in args || '--all' in args is_all: '-all' in args || '--all' in args

View File

@ -34,20 +34,23 @@ pub fn (c &Checker) check_basic(got, expected table.Type) bool {
return true return true
} }
// TODO i64 as int etc // TODO i64 as int etc
if (exp_idx in table.pointer_type_idxs || exp_idx in table.number_type_idxs) && (got_idx in if (exp_idx in table.pointer_type_idxs ||
table.pointer_type_idxs || got_idx in table.number_type_idxs) { exp_idx in table.number_type_idxs) &&
(got_idx in table.pointer_type_idxs || got_idx in table.number_type_idxs) {
return true return true
} }
// if exp_idx in pointer_type_idxs && got_idx in pointer_type_idxs { // if exp_idx in pointer_type_idxs && got_idx in pointer_type_idxs {
// return true // return true
// } // }
// see hack in checker IndexExpr line #691 // see hack in checker IndexExpr line #691
if (got_idx == table.byte_type_idx && exp_idx == table.byteptr_type_idx) || (exp_idx == if (got_idx == table.byte_type_idx &&
table.byte_type_idx && got_idx == table.byteptr_type_idx) { exp_idx == table.byteptr_type_idx) ||
(exp_idx == table.byte_type_idx && got_idx == table.byteptr_type_idx) {
return true return true
} }
if (got_idx == table.char_type_idx && exp_idx == table.charptr_type_idx) || (exp_idx == if (got_idx == table.char_type_idx &&
table.char_type_idx && got_idx == table.charptr_type_idx) { exp_idx == table.charptr_type_idx) ||
(exp_idx == table.char_type_idx && got_idx == table.charptr_type_idx) {
return true return true
} }
if expected == table.t_type && got == table.t_type { if expected == table.t_type && got == table.t_type {
@ -63,8 +66,8 @@ pub fn (c &Checker) check_basic(got, expected table.Type) bool {
return true return true
} }
// allow enum value to be used as int // allow enum value to be used as int
if (got_type_sym.is_int() && exp_type_sym.kind == .enum_) || (exp_type_sym.is_int() && if (got_type_sym.is_int() && exp_type_sym.kind == .enum_) ||
got_type_sym.kind == .enum_) { (exp_type_sym.is_int() && got_type_sym.kind == .enum_) {
return true return true
} }
// TODO // TODO
@ -83,13 +86,15 @@ pub fn (c &Checker) check_basic(got, expected table.Type) bool {
} }
// TODO // TODO
// accept [] when an expected type is an array // accept [] when an expected type is an array
if got_type_sym.kind == .array && got_type_sym.name == 'array_void' && exp_type_sym.kind == if got_type_sym.kind == .array &&
.array { got_type_sym.name == 'array_void' &&
exp_type_sym.kind == .array {
return true return true
} }
// type alias // type alias
if (got_type_sym.kind == .alias && got_type_sym.parent_idx == exp_idx) || (exp_type_sym.kind == if (got_type_sym.kind == .alias &&
.alias && exp_type_sym.parent_idx == got_idx) { got_type_sym.parent_idx == exp_idx) ||
(exp_type_sym.kind == .alias && exp_type_sym.parent_idx == got_idx) {
return true return true
} }
// sum type // sum type
@ -271,8 +276,16 @@ pub fn (c &Checker) get_default_fmt(ftyp, typ table.Type) byte {
return `p` return `p`
} else { } else {
sym := c.table.get_type_symbol(ftyp) sym := c.table.get_type_symbol(ftyp)
if ftyp in [table.string_type, table.bool_type] || sym.kind in [.enum_, .array, .array_fixed, if sym.kind == .alias {
.struct_, .map, .multi_return] || ftyp.has_flag(.optional) || sym.has_method('str') { // string aliases should be printable
info := sym.info as table.Alias
if info.parent_type == table.string_type {
return `s`
}
}
if ftyp in [table.string_type, table.bool_type] ||
sym.kind in [.enum_, .array, .array_fixed, .struct_, .map, .multi_return] || ftyp.has_flag(.optional) ||
sym.has_method('str') {
return `s` return `s`
} else { } else {
return `_` return `_`
@ -308,12 +321,13 @@ pub fn (c &Checker) string_inter_lit(mut node ast.StringInterLiteral) table.Type
if node.pluss[i] && !typ.is_number() { if node.pluss[i] && !typ.is_number() {
c.error('plus prefix only allowd for numbers', node.fmt_poss[i]) c.error('plus prefix only allowd for numbers', node.fmt_poss[i])
} }
if (typ.is_unsigned() && fmt !in [`u`, `x`, `X`, `o`, `c`]) || (typ.is_signed() && if (typ.is_unsigned() && fmt !in [`u`, `x`, `X`, `o`, `c`]) ||
fmt !in [`d`, `x`, `X`, `o`, `c`]) || (typ.is_any_int() && fmt !in [`d`, `c`, `x`, `X`, `o`, (typ.is_signed() && fmt !in [`d`, `x`, `X`, `o`, `c`]) ||
`u`, `x`, `X`, `o`]) || (typ.is_float() && fmt !in [`E`, `F`, `G`, `e`, `f`, `g`]) || (typ.is_pointer() && (typ.is_any_int() && fmt !in [`d`, `c`, `x`, `X`, `o`, `u`, `x`, `X`, `o`]) ||
fmt !in [`p`, `x`, `X`]) || (typ.is_string() && fmt != `s`) || (typ.idx() in [table.i64_type_idx, (typ.is_float() && fmt !in [`E`, `F`, `G`, `e`, `f`, `g`]) ||
table.f64_type_idx (typ.is_pointer() && fmt !in [`p`, `x`, `X`]) ||
] && fmt == `c`) { (typ.is_string() && fmt != `s`) ||
(typ.idx() in [table.i64_type_idx, table.f64_type_idx] && fmt == `c`) {
c.error('illegal format specifier `${fmt:c}` for type `${c.table.get_type_name(ftyp)}`', c.error('illegal format specifier `${fmt:c}` for type `${c.table.get_type_name(ftyp)}`',
node.fmt_poss[i]) node.fmt_poss[i])
} }

View File

@ -345,7 +345,7 @@ pub fn (mut c Checker) struct_init(mut struct_init ast.StructInit) table.Type {
} }
if type_sym.kind == .alias { if type_sym.kind == .alias {
info := type_sym.info as table.Alias info := type_sym.info as table.Alias
if info.parent_typ.is_number() { if info.parent_type.is_number() {
c.error('cannot instantiate number type alias `$type_sym.name`', struct_init.pos) c.error('cannot instantiate number type alias `$type_sym.name`', struct_init.pos)
return table.void_type return table.void_type
} }
@ -363,7 +363,7 @@ pub fn (mut c Checker) struct_init(mut struct_init ast.StructInit) table.Type {
mut info := table.Struct{} mut info := table.Struct{}
if type_sym.kind == .alias { if type_sym.kind == .alias {
info_t := type_sym.info as table.Alias info_t := type_sym.info as table.Alias
sym := c.table.get_type_symbol(info_t.parent_typ) sym := c.table.get_type_symbol(info_t.parent_type)
if sym.kind != .struct_ { if sym.kind != .struct_ {
c.error('alias type name: $sym.name is not struct type', struct_init.pos) c.error('alias type name: $sym.name is not struct type', struct_init.pos)
} }

View File

@ -13,8 +13,8 @@ import v.depgraph
// NB: keywords after 'new' are reserved in C++ // NB: keywords after 'new' are reserved in C++
const ( const (
c_reserved = ['delete', 'exit', 'link', 'unix', 'error', 'calloc', 'malloc', 'free', 'panic', 'auto', c_reserved = ['delete', 'exit', 'link', 'unix', 'error', 'calloc', 'malloc', 'free', 'panic',
'char', 'default', 'do', 'double', 'extern', 'float', 'inline', 'int', 'long', 'register', 'auto', 'char', 'default', 'do', 'double', 'extern', 'float', 'inline', 'int', 'long', 'register',
'restrict', 'short', 'signed', 'sizeof', 'static', 'switch', 'typedef', 'union', 'unsigned', 'restrict', 'short', 'signed', 'sizeof', 'static', 'switch', 'typedef', 'union', 'unsigned',
'void', 'volatile', 'while', 'new', 'namespace', 'class', 'typename'] 'void', 'volatile', 'while', 'new', 'namespace', 'class', 'typename']
// same order as in token.Kind // same order as in token.Kind
@ -89,6 +89,7 @@ mut:
sql_i int sql_i int
sql_stmt_name string sql_stmt_name string
sql_side SqlExprSide // left or right, to distinguish idents in `name == name` sql_side SqlExprSide // left or right, to distinguish idents in `name == name`
inside_vweb_tmpl bool
} }
const ( const (
@ -1695,13 +1696,13 @@ fn (mut g Gen) infix_expr(node ast.InfixExpr) {
// g.infix_op = node.op // g.infix_op = node.op
left_type := if node.left_type == table.t_type { g.cur_generic_type } else { node.left_type } left_type := if node.left_type == table.t_type { g.cur_generic_type } else { node.left_type }
left_sym := g.table.get_type_symbol(left_type) left_sym := g.table.get_type_symbol(left_type)
unaliased_left := if left_sym.kind == .alias { (left_sym.info as table.Alias).parent_typ } else { left_type } unaliased_left := if left_sym.kind == .alias { (left_sym.info as table.Alias).parent_type } else { left_type }
if node.op in [.key_is, .not_is] { if node.op in [.key_is, .not_is] {
g.is_expr(node) g.is_expr(node)
return return
} }
right_sym := g.table.get_type_symbol(node.right_type) right_sym := g.table.get_type_symbol(node.right_type)
unaliased_right := if right_sym.kind == .alias { (right_sym.info as table.Alias).parent_typ } else { node.right_type } unaliased_right := if right_sym.kind == .alias { (right_sym.info as table.Alias).parent_type } else { node.right_type }
if left_type == table.ustring_type_idx && node.op != .key_in && node.op != .not_in { if left_type == table.ustring_type_idx && node.op != .key_in && node.op != .not_in {
fn_name := match node.op { fn_name := match node.op {
.plus { .plus {
@ -3004,7 +3005,13 @@ fn (mut g Gen) string_inter_literal(node ast.StringInterLiteral) {
// Build args // Build args
for i, expr in node.exprs { for i, expr in node.exprs {
if node.expr_types[i] == table.string_type { if node.expr_types[i] == table.string_type {
g.expr(expr) if g.inside_vweb_tmpl {
g.write('vweb__filter(')
g.expr(expr)
g.write(')')
} else {
g.expr(expr)
}
} else if node.expr_types[i] == table.bool_type { } else if node.expr_types[i] == table.bool_type {
g.expr(expr) g.expr(expr)
g.write(' ? _SLIT("true") : _SLIT("false")') g.write(' ? _SLIT("true") : _SLIT("false")')
@ -3049,7 +3056,13 @@ fn (mut g Gen) gen_expr_to_string(expr ast.Expr, etype table.Type) ?bool {
g.write('${str_fn_name}(') g.write('${str_fn_name}(')
g.expr(expr) g.expr(expr)
g.write(')') g.write(')')
} else if sym.kind == .enum_ { }
else if sym.kind == .alias && (sym.info as table.Alias).parent_type == table.string_type {
// handle string aliases
g.expr(expr)
return true
}
else if sym.kind == .enum_ {
is_var := match expr { is_var := match expr {
ast.SelectorExpr { true } ast.SelectorExpr { true }
ast.Ident { true } ast.Ident { true }

View File

@ -13,7 +13,9 @@ fn (g &Gen) comptime_call(node ast.ComptimeCall) {
fn_decl := stmt as ast.FnDecl fn_decl := stmt as ast.FnDecl
// insert stmts from vweb_tmpl fn // insert stmts from vweb_tmpl fn
if fn_decl.name.starts_with('vweb_tmpl') { if fn_decl.name.starts_with('vweb_tmpl') {
g.inside_vweb_tmpl = true
g.stmts(fn_decl.stmts) g.stmts(fn_decl.stmts)
g.inside_vweb_tmpl = false
break break
} }
} }
@ -23,8 +25,7 @@ fn (g &Gen) comptime_call(node ast.ComptimeCall) {
} }
g.writeln('// $' + 'method call. sym="$node.sym.name"') g.writeln('// $' + 'method call. sym="$node.sym.name"')
mut j := 0 mut j := 0
result_type := g.table.find_type_idx('vweb.Result') result_type := g.table.find_type_idx('vweb.Result') // TODO not just vweb
println('!!!!! $result_type')
for method in node.sym.methods { for method in node.sym.methods {
// if method.return_type != table.void_type { // if method.return_type != table.void_type {
if method.return_type != result_type { if method.return_type != result_type {

View File

@ -1577,7 +1577,7 @@ fn (mut p Parser) type_decl() ast.TypeDecl {
parent_idx: pid parent_idx: pid
mod: p.mod mod: p.mod
info: table.Alias{ info: table.Alias{
parent_typ: parent_type parent_type: parent_type
language: language language: language
} }
is_public: is_pub is_public: is_pub

View File

@ -634,7 +634,7 @@ pub:
pub struct Alias { pub struct Alias {
pub: pub:
parent_typ Type parent_type Type
language Language language Language
} }

View File

@ -202,7 +202,7 @@ pub fn (t &Table) get_type_name(typ Type) string {
pub fn (t &Table) unalias_num_type(typ Type) Type { pub fn (t &Table) unalias_num_type(typ Type) Type {
sym := t.get_type_symbol(typ) sym := t.get_type_symbol(typ)
if sym.kind == .alias { if sym.kind == .alias {
pt := (sym.info as Alias).parent_typ pt := (sym.info as Alias).parent_type
if pt <= f64_type && pt >= void_type { if pt <= f64_type && pt >= void_type {
return pt return pt
} }

View File

@ -152,7 +152,8 @@ _ = footer
} }
} else { } else {
// HTML, may include `@var` // HTML, may include `@var`
s.writeln(line.replace('@', '\x24').replace("'", '"')) // escaped by cgen, unless it's a `vweb.RawHtml` string
s.writeln(line.replace('@', '$').replace("'", '"'))
} }
} }
s.writeln(str_end) s.writeln(str_end)
@ -161,3 +162,4 @@ _ = footer
s.writeln('// === end of vweb html template ===') s.writeln('// === end of vweb html template ===')
return s.str() return s.str()
} }

View File

@ -411,3 +411,9 @@ fn strip(s string) string {
pub fn not_found() Result { pub fn not_found() Result {
return Result{} return Result{}
} }
fn filter(s string) string {
return s.replace('<', '&lt;')
}
pub type RawHtml = string