Fix for fuzzer-discovered error with invalid var-initializers.
If a VarDeclaration line contained multiple variables, and the first variable had an illegal initializer-expression, the Declare() would return a Nop. AddVarDeclaration did not expect to see a Nop and would assert once we tried to process the second var-declaration. Now, we allow adding var declarations to a Nop. Bulked up some tests to cover local and global variables (since those are parsed in separate functions) and to check both the first initializer as well as follow-on initializers (since those are parsed in separate parts of the var-decl handler). Change-Id: I66341191698175b490a659715cb8edaafe2f75ae Bug: oss-fuzz:39032 Reviewed-on: https://skia-review.googlesource.com/c/skia/+/452696 Commit-Queue: John Stiles <johnstiles@google.com> Auto-Submit: John Stiles <johnstiles@google.com> Reviewed-by: Brian Osman <brianosman@google.com>
This commit is contained in:
parent
fcc0ef1ee4
commit
b05bbd03f9
@ -1 +1,7 @@
|
||||
void main() { x = float2(1); }
|
||||
void a() { x = float2(1); }
|
||||
void b() { float w = x; }
|
||||
void c() { float w = x, y; }
|
||||
void d() { float w = x, y = z; }
|
||||
|
||||
float e = f, g = h;
|
||||
float i = j, k;
|
||||
|
@ -1,4 +1,11 @@
|
||||
int func() { return 1; }
|
||||
|
||||
void expect_constructor_invocation() { int x = int; }
|
||||
void expect_function_call() { int x = func; }
|
||||
void expect_constructor_invocation() { int x = int; }
|
||||
void expect_constructor_invocation_extra_initializer() { int x, y = int; }
|
||||
void expect_function_call() { int x = func; }
|
||||
void expect_function_call_extra_initializer() { int x, y = func; }
|
||||
|
||||
int g_expect_constructor_invocation = int;
|
||||
int g_expect_constructor_invocation_extra_initializer, ix = int;
|
||||
int g_expect_function_call = func;
|
||||
int g_expect_function_call_extra_initializer, iy = func;
|
||||
|
@ -430,7 +430,9 @@ void DSLParser::globalVarDeclarationEnd(PositionInfo pos, const dsl::DSLModifier
|
||||
if (!this->parseArrayDimensions(offset, &type)) {
|
||||
return;
|
||||
}
|
||||
this->parseInitializer(offset, &initializer);
|
||||
if (!this->parseInitializer(offset, &initializer)) {
|
||||
return;
|
||||
}
|
||||
DSLGlobalVar first(mods, type, name, std::move(initializer), pos);
|
||||
Declare(first);
|
||||
AddToSymbolTable(first);
|
||||
@ -448,7 +450,8 @@ void DSLParser::globalVarDeclarationEnd(PositionInfo pos, const dsl::DSLModifier
|
||||
if (!this->parseInitializer(offset, &anotherInitializer)) {
|
||||
return;
|
||||
}
|
||||
DSLGlobalVar next(mods, type, this->text(identifierName), std::move(anotherInitializer));
|
||||
DSLGlobalVar next(mods, type, this->text(identifierName), std::move(anotherInitializer),
|
||||
this->position(offset));
|
||||
Declare(next);
|
||||
AddToSymbolTable(next, this->position(identifierName));
|
||||
}
|
||||
@ -466,7 +469,9 @@ DSLStatement DSLParser::localVarDeclarationEnd(PositionInfo pos, const dsl::DSLM
|
||||
if (!this->parseArrayDimensions(offset, &type)) {
|
||||
return {};
|
||||
}
|
||||
this->parseInitializer(offset, &initializer);
|
||||
if (!this->parseInitializer(offset, &initializer)) {
|
||||
return {};
|
||||
}
|
||||
DSLVar first(mods, type, name, std::move(initializer), pos);
|
||||
DSLStatement result = Declare(first);
|
||||
AddToSymbolTable(first);
|
||||
@ -484,7 +489,8 @@ DSLStatement DSLParser::localVarDeclarationEnd(PositionInfo pos, const dsl::DSLM
|
||||
if (!this->parseInitializer(offset, &anotherInitializer)) {
|
||||
return result;
|
||||
}
|
||||
DSLVar next(mods, type, this->text(identifierName), std::move(anotherInitializer));
|
||||
DSLVar next(mods, type, this->text(identifierName), std::move(anotherInitializer),
|
||||
this->position(offset));
|
||||
DSLWriter::AddVarDeclaration(result, next);
|
||||
AddToSymbolTable(next, this->position(identifierName));
|
||||
}
|
||||
|
@ -138,13 +138,15 @@ void DSLWriter::AddVarDeclaration(DSLStatement& existing, DSLVar& additional) {
|
||||
SkSL::Block& block = existing.fStatement->as<Block>();
|
||||
SkASSERT(!block.isScope());
|
||||
block.children().push_back(Declare(additional).release());
|
||||
} else {
|
||||
SkASSERT(existing.fStatement->is<VarDeclaration>());
|
||||
} else if (existing.fStatement->is<VarDeclaration>()) {
|
||||
StatementArray stmts;
|
||||
stmts.reserve_back(2);
|
||||
stmts.push_back(std::move(existing.fStatement));
|
||||
stmts.push_back(Declare(additional).release());
|
||||
existing.fStatement = SkSL::Block::MakeUnscoped(/*offset=*/-1, std::move(stmts));
|
||||
} else if (existing.fStatement->isEmpty()) {
|
||||
// If the variable declaration generated an error, we can end up with a Nop statement here.
|
||||
existing.fStatement = Declare(additional).release();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,4 @@
|
||||
### Compilation failed:
|
||||
|
||||
error: 1: expected expression, but found ''
|
||||
error: 1: expected ';', but found ''
|
||||
2 errors
|
||||
1 error
|
||||
|
@ -1,5 +1,4 @@
|
||||
### Compilation failed:
|
||||
|
||||
error: 1: expected expression, but found ''
|
||||
error: 1: expected ';', but found ''
|
||||
2 errors
|
||||
1 error
|
||||
|
@ -1,4 +1,11 @@
|
||||
### Compilation failed:
|
||||
|
||||
error: 1: unknown identifier 'x'
|
||||
1 error
|
||||
error: 2: unknown identifier 'x'
|
||||
error: 3: unknown identifier 'x'
|
||||
error: 4: unknown identifier 'x'
|
||||
error: 4: unknown identifier 'z'
|
||||
error: 6: unknown identifier 'f'
|
||||
error: 6: unknown identifier 'h'
|
||||
error: 7: unknown identifier 'j'
|
||||
8 errors
|
||||
|
@ -1,5 +1,11 @@
|
||||
### Compilation failed:
|
||||
|
||||
error: 3: expected '(' to begin constructor invocation
|
||||
error: 4: expected '(' to begin function call
|
||||
2 errors
|
||||
error: 4: expected '(' to begin constructor invocation
|
||||
error: 5: expected '(' to begin function call
|
||||
error: 6: expected '(' to begin function call
|
||||
error: 8: expected '(' to begin constructor invocation
|
||||
error: 9: expected '(' to begin constructor invocation
|
||||
error: 10: expected '(' to begin function call
|
||||
error: 11: expected '(' to begin function call
|
||||
8 errors
|
||||
|
Loading…
Reference in New Issue
Block a user