FPtje / GLuaFixer

Linter for Garry's mod Lua.
https://fptje.github.io/glualint-web/
GNU Lesser General Public License v2.1
142 stars 19 forks source link

Syntax Failure #156

Closed Yogpod closed 1 year ago

Yogpod commented 1 year ago
local a = {}
local b = {1}

(a)[1] = b[1]
(a)[2] = 0x1

Since it wasn't addressed in the last issue I made a separate one for it WindowsTerminal_zKgjHpQEjl

FPtje commented 1 year ago

Ah, I forgot about it. Sorry about that!

FPtje commented 1 year ago

This is a nasty one, because the correct parse depends on whitespace, and that's exactly what glualint throws away before doing the parsing.

Take this somewhat smaller example:

a = b
(c)[1] = 1

Now compare it to this:

a = b         (c)[1] = 1

The first example is two separate statements, and it's correct Lua. The second example is one statement, because instead of a newline there are just some spaces. The second example is syntactically incorrect, because that second = is bad. Glualint thinks the first example is the second example, because it threw away whitespace.

The annoying thing is that the parsing of Lua is entirely independent of whitespace (if you don't count lexing), except for here. That's annoying.

At least it's nice to know that some other Lua tool has a similar problem :sweat_smile:

FPtje commented 1 year ago

Oh wow, https://www.lua.org/cgi-bin/demo also fails on this example. Is this a luajit only thing?

Yogpod commented 1 year ago

I took an example from the obfuscation but it may have beautified incorrectly, this code exactly appears to not actually work in garry's mod

FPtje commented 1 year ago

Looks like we reached the same conclusion at the same time, as I was trying it in gmod as well :sweat_smile: . Could it be that the original code was this?

a = b;
(c)[1] = 1

With a semicolon it's all valid, but glualint likes removing semicolons because they're usually not necessary.

Yogpod commented 1 year ago

I think so

FPtje commented 1 year ago

Turns out there was already some code that was intended to disambiguate things. It looks like you found a case that wasn't caught. I revamped the code, going back to the question "when is stuff ambiguous, and when is it not?". In the fix I've left a big comment to precisely explain the situation:

https://github.com/FPtje/GLuaFixer/blob/52d295183312d971f58c26ec71d3130071e070c9/src/GLua/AG/PrettyPrint.ag#L299-L313