poiuyqwert / PyMS

Broodwar Modding Suite
47 stars 18 forks source link

PyICE/IScriptBIN: incorrect unused label detection: header reference is not always considered #146

Open myocytebd opened 3 weeks ago

myocytebd commented 3 weeks ago

It seems that if some label is not referenced by script jump or "local" header, it would be incorrectly treated as "unused label" -- even if it is referenced by "non-local" headers.

.headerstart ...
CommonAttk1: ...

.headerstart ...
GndAttkInit             CommonAttk1
# CommonAttk1 is treated as unused label

It is more than a bogus warning, since IScriptBIN then removes the label and script block, leading to iscript.bin generation failure.

https://github.com/poiuyqwert/PyMS/blob/03a714b15c49faf2a085177b55599f46e3721b4f/PyMS/FileFormats/IScriptBIN.py#L860-L875

IMO there should be some code under state==header to remove label from unused, but there isn't.

poiuyqwert commented 2 weeks ago

Hey @myocytebd, thanks for the report. Are you able to provide a self contained example script that I can use to test? I am a bit busier than usual right now, so not sure when I'll have time to look at this bug, and having an already build full example will go a long way to being able to look at this issue without having to recreate it first.

Thanks!

myocytebd commented 2 weeks ago

issue_146.zip

iscript.bin
iscript.issue.txt  =>modified to reproduce (most lines of change is to rename duplicated labels)
iscript.org_all.txt  => decompiled (ids=all)

This warning shows on import: Interpreting Warning: The label 'CommonAttk1' is unused, label is discarded This exception raises on save, since the label/code is deleted.

Exception in Tkinter callback
Traceback (most recent call last):
  File "/usr/lib/python2.7/lib-tk/Tkinter.py", line 1550, in __call__
    return self.func(*args)
  File "/home/ulp/.var/app/com.usebottles.bottles/data/bottles/bottles/111/drive_c/bnet/scr.modding/PyMS/PyMS/PyICE/PyICE.py", line 370, in save
    self.saveas(file_path=self.file)
  File "/home/ulp/.var/app/com.usebottles.bottles/data/bottles/bottles/111/drive_c/bnet/scr.modding/PyMS/PyMS/PyICE/PyICE.py", line 380, in saveas
    self.ibin.compile(file_path)
  File "/home/ulp/.var/app/com.usebottles.bottles/data/bottles/bottles/111/drive_c/bnet/scr.modding/PyMS/PyMS/FileFormats/IScriptBIN.py", line 1178, in compile
    entry += struct.pack('<H', offsets[o])
KeyError: 39001

This seems to fix the issue.

diff --git a/PyMS/FileFormats/IScriptBIN.py b/PyMS/FileFormats/IScriptBIN.py
index 34d1ce27..a812270a 100755
--- a/PyMS/FileFormats/IScriptBIN.py
+++ b/PyMS/FileFormats/IScriptBIN.py
@@ -866,6 +866,8 @@ class IScriptBIN:
                            label = m.group(2)
                            if label in labels:
                                header[3].append(labels[label])
+                               if label in unused:
+                                   unused.remove(label)
                            else:
                                if label != '[NONE]':
                                    if not label in findlabels: