gmqcc icon indicating copy to clipboard operation
gmqcc copied to clipboard

entfield expressions and ast_member expressions can overwrite immediates and globals table

Open graphitemaster opened this issue 7 years ago • 4 comments

Minimal test case

.vector vec;
void main()
{
	entity e = spawn();
	(e.vec = '0 0 0').x += 1;
	print(vtos(e.vec), "\n");
}

This should print '1 0 0' however the .x += 1 expression binds to the literal '0 0 0' instead of e.vec which overwrites the immediate. Using literal '0 0 0' anywhere now will actually become '1 0 0'. This is true for anything on the right hand side of the entfield assignment, other globals, or entfields will be overwritten too.

graphitemaster avatar Nov 27 '17 11:11 graphitemaster

Upon further inspection this is actually true for all ast_member this also exibits the same problem

void main()
{
	vector x;
	(x = '0 0 0').x += 1;
	print(vtos(x));
}

graphitemaster avatar Nov 27 '17 11:11 graphitemaster

Xonotic has a few places where this is miscompiling and they don't even realise it there yet. Just did a coverage check.

graphitemaster avatar Dec 01 '17 19:12 graphitemaster

This behavior also manifests for arrays too. We shuffle the regular parsing rules for ent.foo[n] to behave as ent.(foo[n]) opposed to (ent.foo)[n], as it should by the binding logic does not follow suit, instead (ent.foo[n] = '0 0 0').x += 1 binds to the literal n and causes a compiler error.

graphitemaster avatar Dec 01 '17 19:12 graphitemaster

The inner workings of the qcvm warrant the label change to 'feature' ;p

Blub avatar Jan 14 '18 10:01 Blub