In our solution, I noticed that sCalcout (scalc R3-7-4) failed to parse the following CALC on Linux (Ubuntu 22) but succeeded on Windows:
CC:=BB;BB:=AA;F:=E;E:=D;H:=G;G:=1;(AA#CC)|(D#F)|(H=0)
When I enabled logs (sCalcPostfixDebug=5), I got following sequences:
-
Linux:
get_element:FETCH_CC (CC) runtime_depth=0
get_element:STORE_A (:=) runtime_depth=1
get_element:FETCH_BB (BB) runtime_depth=0
get_element:NOT_GENERATED (;) runtime_depth=1
get_element:FETCH_BB (BB) runtime_depth=1
get_element:STORE_A (:=) runtime_depth=2
STORE_OPERATOR:pout[-1] is a string fetch
...
-
Windows:
get_element:FETCH_CC (CC) runtime_depth=0
get_element:STORE_A (:=) runtime_depth=1
STORE_OPERATOR:pout[-1] is a string fetch
get_element:FETCH_BB (BB) runtime_depth=0
get_element:NOT_GENERATED (;) runtime_depth=1
EXPR_TERMINATOR op ';': moved ':=' from stack
get_element:FETCH_BB (BB) runtime_depth=0
get_element:STORE_A (:=) runtime_depth=1
STORE_OPERATOR:pout[-1] is a string fetch
I tried to identify the source and came up with the following observation:
- It all happens inside
sCalcPostfix().
- Before the processing loop,
pstacktop points at stack.
- The first token to be processed is
FETCH_CC. That is an OPERAND and does nothing with pstacktop.
- The next token is
STORE_A is processed. That is a STORE_OPERATOR. Since pstacktop == stack at this time, the loop in case STORE_OPERATOR exits immediately. It leaves ps1 set to stack. Yet, stack has not been updated/written yet. So, it contains random garbage from memory. Luckily enough, this garbage happen to cause ps1->code == A_FETCH which sets handled to 1 and sends the code towards different path than on Windows.
Just to test the idea, I tried to memset the first item of stack to 0 (code 0 means END_EXPRESSION which seems to be safe) prior to entering the processing loop. And, sCalcout parsed the expression right (no error). I admit I did not run a test IOC with calc only. I tried to insert the expression into scalcTest but it parsed without any problem unless I injected stack[0].code = A_FETCH right after declaring stack.
Do you see this as something to fix? I can try to prepare a pull request.
In our solution, I noticed that sCalcout (scalc R3-7-4) failed to parse the following CALC on Linux (Ubuntu 22) but succeeded on Windows:
When I enabled logs (sCalcPostfixDebug=5), I got following sequences:
Linux:
Windows:
I tried to identify the source and came up with the following observation:
sCalcPostfix().pstacktoppoints atstack.FETCH_CC. That is anOPERANDand does nothing withpstacktop.STORE_Ais processed. That is aSTORE_OPERATOR. Sincepstacktop == stackat this time, the loop incase STORE_OPERATORexits immediately. It leavesps1set tostack. Yet,stackhas not been updated/written yet. So, it contains random garbage from memory. Luckily enough, this garbage happen to causeps1->code == A_FETCHwhich setshandledto 1 and sends the code towards different path than on Windows.Just to test the idea, I tried to
memsetthe first item ofstackto 0 (code 0 meansEND_EXPRESSIONwhich seems to be safe) prior to entering the processing loop. And, sCalcout parsed the expression right (no error). I admit I did not run a test IOC with calc only. I tried to insert the expression intoscalcTestbut it parsed without any problem unless I injectedstack[0].code = A_FETCHright after declaringstack.Do you see this as something to fix? I can try to prepare a pull request.