This issue was discovered when using Claude to create a test system for Python based subsystems (message boards, citylife, banking, et al.)
Summary: CFDataFile.putData destroys CFData instance on first write, causing KeyError: '#' on any subsequent write through the same object
Component: crossfire-maps
File: python/CFDataFile.py
Function: CFDataFile.putData()
Severity: Major (data write silently corrupts in-memory state; second write crashes)
TL;DR Description:
CFDataFile.putData() mutates the dictionary it is given rather than working from a read-only view of it. This corrupts the calling CFData instance after the first write, making it impossible to perform a second write through the same object without a crash.
CFDataFile.putData() is always called with CFData.datadb as its argument:
self.datafile.putData(self.datadb)
Python passes dicts by reference, so inside putData the parameter dic and the instance variable self.datadb refer to the same object. The function reads the column header from the '#' key and then deletes it to avoid writing it as a data row:
header = dic['#']
del dic['#'] # <-- modifies self.datadb in-place
index = list(dic.keys())
index.sort()
After this runs, self.datadb no longer contains the '#' key. The write to disk completes correctly, but the in-memory object is permanently damaged. Any subsequent call to put_record(), remove_record(), or any other method that calls putData() will reach:
header = dic['#'] # KeyError: '#'
and crash.