Opened 10 years ago
Closed 5 years ago
#2955 closed Bug (Fixed)
Using Is### breaks Maps passed ByRef
Reported by: | anonymous | Owned by: | Jon |
---|---|---|---|
Milestone: | 3.3.15.3 | Component: | AutoIt |
Version: | 3.3.13.19 | Severity: | None |
Keywords: | Cc: |
Description
Depending on various things, some map values can be broken
Shortest working example i got:
#AutoIt3Wrapper_Version=Beta #include <Debug.au3> WTF() ; works, if outside of func MsgBox(0, Default, "Yep!") Func WTF() Local $MAP[] $MAP["mod"] = "Mod" $MAP["more"] = "More actions" $MAP["delete"] = "Delete" Local $sTest1 = $MAP["more"] ; after this $Map["more"] is Null Local $sTest2 = $MAP["more"] _Assert("$sTest1 == $sTest2") ; Assertion Failed EndFunc
Attachments (0)
Change History (9)
comment:1 Changed 10 years ago by Melba23
comment:2 Changed 10 years ago by Melba23
- Resolution set to No Bug
- Status changed from new to closed
comment:3 Changed 10 years ago by anonymous
Um... Sorry... There is no problem with _Assert() at all. I trying to make a shorter example and lost problem in process.
Seems that this problem is related to some non-trivial code when passing maps or sub-maps to user function without and using Is<KindOf> functions AND only if you use some specific keys.
Here is a valid example (no assertion is used here):
#AutoIt3Wrapper_Version=Beta AutoItSetOption("MustDeclareVars", 1) Global $TEST = "more" ; works correctly if you use other sting Global $mMap = Map() Error($mMap) Func Error($mTest) ; works correctly if you use ByRef Local $sTest1 = $mTest[$TEST] IsString($mTest["mod"]) ; works correctly if you comment this line Local $sTest2 = $mTest[$TEST] MsgBox(0, Default, VarGetType($sTest1) & ":" & $sTest1 & @CRLF & VarGetType($sTest2) & ":" & $sTest2) EndFunc Func Map() Local $mTest[] $mTest["mod"] = "Mod" $mTest["caption"] = "Mod list (%s)" $mTest["no_game_dir1"] = "no game dir - select from ""More actions""" $mTest["up"] = "Move up" $mTest["down"] = "Move down" $mTest["enable"] = "Enable" $mTest["disable"] = "Disable" $mTest["missing"] = "%s (missing mod)" $mTest["remove"] = "Remove" $mTest[$TEST] = "More actions" ; works correctly if you comment remaining items $mTest["plugins"] = "Plugins" $mTest["homepage"] = "Go to webpage" $mTest["delete"] = "Delete" $mTest["delete_confirm"] = "Do you really want to delete this mod? \n%s\n\n(The mod will be moved to recycle bin, if it's possible))" $mTest["add_new"] = "Add new mod(s)" $mTest["compatibility"] = "Compatibility" $mTest["open_dir"] = "Open mod directory" Return $mTest EndFunc
comment:4 Changed 10 years ago by Melba23
- Resolution No Bug deleted
- Status changed from closed to reopened
- Summary changed from Map content is randomly broken to Using Is### breaks Maps passed ByRef
I now agree that there is a problem - but not the one you think you have found. I believe it happens when you pass a Map ByRef and check on the values. This example shows it clearly:
#AutoIt3Wrapper_Version=Beta AutoItSetOption("MustDeclareVars", 1) Global $TEST = "more" Global $mMap = Map() For $vKey In MapKeys($mMap) ConsoleWrite($vKey & ": " & @TAB & $mMap[$vKey] & @CRLF) Next ConsoleWrite(@CRLF) _Error_ByRef($mMap) ConsoleWrite(@CRLF) _Error_Global() Func _Error_ByRef($mTest) ConsoleWrite(@CRLF & "ByRef - before IsString" & @CRLF) For $vKey In MapKeys($mTest) ConsoleWrite($vKey & ": " & @TAB & $mTest[$vKey] & @CRLF) Next Local $sTest1 = $mTest[$TEST] IsString($mTest["mod"]) ; This is the problem line <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< ConsoleWrite(@CRLF & "ByRef - after IsString" & @CRLF) For $vKey In MapKeys($mTest) ConsoleWrite($vKey & ": " & @TAB & $mTest[$vKey] & @CRLF) Next Local $sTest2 = $mTest[$TEST] MsgBox(0, "ByRef", VarGetType($sTest1) & ": " & $sTest1 & @CRLF & VarGetType($sTest2) & ": " & $sTest2) EndFunc Func _Error_Global() ConsoleWrite(@CRLF & "Direct - before IsString" & @CRLF) For $vKey In MapKeys($mMap) ConsoleWrite($vKey & ": " & @TAB & $mMap[$vKey] & @CRLF) Next Local $sTest1 = $mMap[$TEST] IsString($mMap["mod"]) ConsoleWrite(@CRLF & "Direct - after IsString" & @CRLF) For $vKey In MapKeys($mMap) ConsoleWrite($vKey & ": " & @TAB & $mMap[$vKey] & @CRLF) Next Local $sTest2 = $mMap[$TEST] MsgBox(0, "Global", VarGetType($sTest1) & ": " & $sTest1 & @CRLF & VarGetType($sTest2) & ": " & $sTest2) EndFunc Func Map() Local $mTest[] $mTest["mod"] = "Mod" $mTest["caption"] = "Mod list (%s)" $mTest["no_game_dir1"] = "no game dir - select from ""More actions""" $mTest["up"] = "Move up" $mTest["down"] = "Move down" $mTest["enable"] = "Enable" $mTest["disable"] = "Disable" $mTest["missing"] = "%s (missing mod)" $mTest["remove"] = "Remove" $mTest[$TEST] = "More actions" ; works correctly if you comment remaining items $mTest["plugins"] = "Plugins" $mTest["homepage"] = "Go to webpage" $mTest["delete"] = "Delete" $mTest["delete_confirm"] = "Do you really want to delete this mod? \n%s\n\n(The mod will be moved to recycle bin, if it's possible))" $mTest["add_new"] = "Add new mod(s)" $mTest["compatibility"] = "Compatibility" $mTest["open_dir"] = "Open mod directory" Return $mTest EndFunc
So the bug appears to be using Is##### on a Map passed ByRef - I have amended the title.
M23
P.S. By the way, I notice the reference to "game" in your script - could I gently point you to the Forum rules:
http://www.autoitscript.com/forum/index.php?app=forums&module=extras§ion=boardrules
comment:5 Changed 10 years ago by anonymous
... but not the one you think you have found...
I don't know what sort of problem it is. There is so many things should be used together to reproduce this bug (so i can make some small changes to code and it will work correctly)... but in any way Is<KindOf> should not modify its param.
... reference to "game" ...
This script don't interact with game (only can launch process) or game server in any way.
See gen_lng_validate.au3, lng_auto.au3 (this "bug" affects only "more" key) and lng\english.json for details
https://bitbucket.org/SyDr/ramm/src/0d6f035cf547b66d425f91a72dda41a189e8f25d?at=no_regrets
comment:6 Changed 10 years ago by jchd18
M23,
$mTest is not passed ByRef in the code exposed.
If one changes the function into:
Func _Error_ByRef(ByRef $mTest)
then everything works as expected.
But with your code, this:
Local $sTest1 = $mTest[$TEST]
assigns Null to $sTest1.
comment:7 Changed 10 years ago by Melba23
jchd,
I realised that last night as I went to bed - the problem happens when the Map is passed as a parameter and a copy is made. Sorry for the confusion.
I will try and get a simple reproducer script working today and post it in "Dev Chat" - this needs more scrutiny that it is getting in Trac.
M23
comment:8 Changed 10 years ago by anonymous
Hi. Any news?
comment:9 Changed 5 years ago by Jon
- Milestone set to 3.3.15.3
- Owner set to Jon
- Resolution set to Fixed
- Status changed from reopened to closed
Fixed by revision [12297] in version: 3.3.15.3
Guidelines for posting comments:
- You cannot re-open a ticket but you may still leave a comment if you have additional information to add.
- In-depth discussions should take place on the forum.
For more information see the full version of the ticket guidelines here.
Nothing wrong with the Map itself - the problem is in way the statement is passed to the _Assert function. I am investigating further.
M23
Edit: The problem arises because the 2 variables in the passed statement are Local to the WTF function and so are not recognised by the _Assert function. So the passed string is executed as a literal string and fails. You can see this happening in this example script:
As you can see the Map contents are unchanged, but when the passed variables are not Global in scope the _Assert function fails.
The basic problem is that Execute needs to recognise the variable names in the passed string as variables - and it seems that it only looks in the Global variable list. So a possible bug, but nothing to do with Maps per se I suggest that you open a new ticket that covers the failure of _Assert when passed Local variables.
M23