Bound the name-termination scan in the module loader
The only bound on a record's name was "there is a NUL somewhere before the end of the blob". Name length was uncapped and the record count is bounded only by (natives - publics) / defsize, so both scale with the blob and the walk was O(size^2). Six copies of the scan, across the counting and copying passes for publics, natives and pubvars. A blob with defsize=8, the record tables filling half of it, and every record pointing its name at a run whose only NUL sits at size-1 passes every structural check, so the loader walks it. Measured with a host harness before the fix: 6.1 s at 1 MiB, 97.8 s at 4 MiB -- sixteen-fold data, sixteen-fold time, extrapolating to ~26 minutes at 16 MiB. It runs at PASSIVE_LEVEL in the IRP_MJ_DEVICE_CONTROL dispatch routine, so the calling thread is stuck inside the driver and the process cannot be terminated until it returns. The module is rejected in the end; the time is spent entirely in the counting pass. Fold the six copies into find_name_end and stop after 64 bytes. pawncc truncates exported symbols to sEXPMAX = 31 characters, so nothing it emits comes close, and PawnIO's own get_public/get_native cannot look up anything longer than 32 anyway. std::min needs the extra parentheses because the WDK headers define min as a macro. Same harness after the fix: both blobs rejected in under a millisecond, a 63-character name still loads, 64 does not, and pawn/test.amx is unaffected.
N
namazso committed
4965cd7210983ba563cd94710f837c0bddb82bc8
Parent: 74018cb