From: Mikko Rasa Date: Thu, 25 Feb 2021 23:09:21 +0000 (+0200) Subject: Don't allow arbitrary statements in structs or interface blocks X-Git-Url: http://git.tdb.fi/?a=commitdiff_plain;h=7a9e93a313c1fe35aa8ab4c4a3191df32fa7c9d1;p=libs%2Fgl.git Don't allow arbitrary statements in structs or interface blocks --- diff --git a/source/glsl/parser.cpp b/source/glsl/parser.cpp index 4b6bd7ed..b493c677 100644 --- a/source/glsl/parser.cpp +++ b/source/glsl/parser.cpp @@ -339,7 +339,8 @@ RefPtr Parser::parse_layout() return layout; } -void Parser::parse_block(Block &block, bool require_braces) +template +void Parser::parse_block(Block &block, bool require_braces, RefPtr (Parser::*parse_content)()) { bool have_braces = (require_braces || tokenizer.peek_token()=="{"); if(have_braces) @@ -348,10 +349,10 @@ void Parser::parse_block(Block &block, bool require_braces) if(have_braces) { while(tokenizer.peek_token()!="}") - block.body.push_back(parse_statement()); + block.body.push_back((this->*parse_content)()); } else - block.body.push_back(parse_statement()); + block.body.push_back((this->*parse_content)()); block.use_braces = (require_braces || block.body.size()!=1); @@ -486,7 +487,7 @@ RefPtr Parser::parse_struct_declaration() strct->line = tokenizer.get_location().line; strct->name = expect_identifier(); - parse_block(strct->members, true); + parse_block(strct->members, true, &Parser::parse_variable_declaration); tokenizer.expect(";"); declared_types.insert(strct->name); @@ -536,6 +537,18 @@ RefPtr Parser::parse_variable_declaration() return var; } +RefPtr Parser::parse_variable_declaration_with_layout() +{ + RefPtr layout; + if(tokenizer.peek_token()=="layout") + layout = parse_layout(); + + RefPtr var = parse_variable_declaration(); + var->layout = layout; + + return var; +} + RefPtr Parser::parse_function_declaration() { RefPtr func = new FunctionDeclaration; @@ -564,7 +577,7 @@ RefPtr Parser::parse_function_declaration() if(token=="{") { func->definition = func.get(); - parse_block(func->body, true); + parse_block(func->body, true, &Parser::parse_statement); } else if(token==";") tokenizer.parse_token(); @@ -585,7 +598,7 @@ RefPtr Parser::parse_interface_block() throw parse_error(tokenizer.get_location(), iface->interface, "an interface qualifier"); iface->name = expect_identifier(); - parse_block(iface->members, true); + parse_block(iface->members, true, &Parser::parse_variable_declaration_with_layout); if(!check(";")) { iface->instance_name = expect_identifier(); @@ -610,13 +623,13 @@ RefPtr Parser::parse_conditional() cond->condition = parse_expression(); tokenizer.expect(")"); - parse_block(cond->body, false); + parse_block(cond->body, false, &Parser::parse_statement); string token = tokenizer.peek_token(); if(token=="else") { tokenizer.parse_token(); - parse_block(cond->else_body, false); + parse_block(cond->else_body, false, &Parser::parse_statement); } return cond; @@ -649,7 +662,7 @@ RefPtr Parser::parse_for() loop->loop_expression = parse_expression(); tokenizer.expect(")"); - parse_block(loop->body, false); + parse_block(loop->body, false, &Parser::parse_statement); return loop; } @@ -664,7 +677,7 @@ RefPtr Parser::parse_while() loop->condition = parse_expression(); tokenizer.expect(")"); - parse_block(loop->body, false); + parse_block(loop->body, false, &Parser::parse_statement); return loop; } diff --git a/source/glsl/parser.h b/source/glsl/parser.h index 1572128f..9ab1232a 100644 --- a/source/glsl/parser.h +++ b/source/glsl/parser.h @@ -64,12 +64,14 @@ private: RefPtr parse_import(); RefPtr parse_precision(); RefPtr parse_layout(); - void parse_block(Block &, bool); + template + void parse_block(Block &, bool, RefPtr (Parser::*)()); RefPtr parse_expression(unsigned = 0); RefPtr parse_binary(const RefPtr &, const Operator *); RefPtr parse_function_call(const VariableReference &); RefPtr parse_struct_declaration(); RefPtr parse_variable_declaration(); + RefPtr parse_variable_declaration_with_layout(); RefPtr parse_function_declaration(); RefPtr parse_interface_block(); RefPtr parse_conditional();