FuPeiJiang/ahk_parser.js

Page Freeze, then Out_Of_Memory

Opened this issue · 10 comments

Hi,
Tried out pasting in the v1 code from Splashy. The raw file is here. No response in the page. Big file size, although ~150k should be okay.
Thanks.

(writing this helps me remember)

I opened up chrome devtools at tab Sources, then pasted raw file, it froze, but I was able to click Pause script execution F8 Ctrl+\
Then I click Pretty-print, it's a mess, I probably shouldn't have minimized the javascript.
but luckily, I was able to find this pattern n[m][w], m is probably line number, and w is column number
I see that m===2215 which is actually line 2216

it's this line:
gui, Test: add, text, % spr " h"ySep " w"3*xSep " v" "t_" c "_" r
https://github.com/lmstearn/Splashy/blob/8513d25f71597c0f23e8226e8fc013d7e21237f4/SplashyTest.ahk#L2216

then, I only paste this line, and it still freezes

I'll go into node.js and see what's going on using vscode debugger

v:="str"var

so the parser assumes that concat must have at least 1 whiteSpace

v:="str" var

so this would be the correct version

gui, Test: add, text, % spr{spaceHere}" h" ySep " w"{spaceHere}3*xSep " v" "t_" c "_" r
gui, Test: add, text, % spr " h" ySep " w" 3*xSep " v" "t_" c "_" r

I should fix my parser, this is valid ahk

so it's only "str" that doesn't need whiteSpace right after, for concat

note that this is not valid in AHK_H v2:
Error: Missing space or operator before this.

var:=123
v:=" h"var

should be fixed now

I added a test
doIt('v:=spr " h"ySep " w"3*xSep " v" "t_" c "_" r','v:=spr " h" ySep " w" 3*xSep " v" "t_" c "_" r')

it now freezes here:
%SplashyRef%(Splashy, {release: 1}*)
https://github.com/lmstearn/Splashy/blob/8513d25f71597c0f23e8226e8fc013d7e21237f4/SplashyTest.ahk#L2584

MouseGetPos, xpos, ypos
(A_Gui) && (xpos<3*xSep || ypos<3*ySep) && move()
%SplashyRef%(Splashy, {release: 1}*)

https://www.autohotkey.com/docs/Scripts.htm#non-continuation

) [v1.1.01+]: If a closing parenthesis appears in the continuation section's options (except as a parameter of the Join option), the line is reinterpreted as an expression instead of the beginning of a continuation section. This allows expressions like (x.y)z to work without the need to escape the opening parenthesis.

this is valid ahk

MouseGetPos, xpos, y
(
pos
)

this is going to be for another day

technically, this is legal ahk, :cry

msg
(
box
) hello world

@mr Doge, Thanks for looking at this- the code causing the issues is certainly not standard for sure. Beginning to think that once this script passes, the parser will be close to invincible to all such scripts! 🔐

continuation:

msgbox,
(Join(2) Join(3)
a
b
c
)

->a(3))b(3))c
so what is taken is the last join
and whiteSpace: space or tab is a delimeter


group:

msgbox "hi"
(ok() && Join(2))

so start from end, lastIndexOf(')'), from there, get next whiteSpace,
here: )

(ok() && Join(2))
---------------^

whiteSpace

(ok() && Join(2))
--------^

get next 4 letters

(ok() && Join(2))
---------^^^^

if it toLowerCase() is 'join'
continue

(ok() && Join(2))
----^

say the first ( is equivalent to a whiteSpace as a condition

(ok() && Join(2))
^

get next 4 letters

(ok() && Join(2))
-^^^^

this is not 'join'
, so this whole thing is a 'group'

Join(X): is that a thing in the js parser?
From what they say in the docs, Join only has one parameter. Does it even make sense to include Join more than once like

msgbox,
(Join( Join2 Join) Join( Join3 Join)
a
b
c
)

Surely only the first (or last parameter applies)

Join looks like a major headache in any case where it can also be defined as a use function in script:

join(strArray)
{
s := ""
	for i,v in strArray
	s .= "," . v
return substr(s, 2)
}

sorry, forgot to put (writing this helps me remember)
this was actually taken into account and fixed


Join(X): is that a thing in the js parser?

no, it's (continuation section: parameter join) OR the user-defined function join(), depending on the context/parsing


Surely only the first (or last parameter applies)

it is the last parameter, I quote myself:

->a(3))b(3))c
so what is taken is the last join

how should I have said that? to be clearer/understood?
like this ? : "so only the last join{parameter here} is applied"


in this case: (Join(3) && Join(2))
continuation section takes priority, so this is a continuation section, even if it's invalid
here, it doesn't matter if Join is a function or not, this is a continuation section

Join(num) {
  return num num
}
msgbox hi
(Join(3) && Join(2))
Exitapp

---------------------------
Line Text: msgbox hi(2))(2))Exitapp(2))f3::Exitapp
Error: Missing ")"
The program will exit.
---------------------------

I see. Very unusual v1 allows for all those useless Joins in the continuation section.
msgbox hi(2))(2))Exitapp(2))f3::Exitapp
Displays the text in v1. Is that v2?
...
Interesting, now there is Error code: STATUS_BREAKPOINT.

this is v1
you need to run this code, to get that error (sorry, forgot to include my ExitApp)

Join(num) {
  return num num
}
msgbox hi
(Join(3) && Join(2))
Exitapp

you ran this: msgbox hi(2))(2))Exitapp(2))f3::Exitapp