Enable recursive mmacro support#230
Conversation
c37f9c2 to
52ff78e
Compare
There was a problem hiding this comment.
Pull request overview
This PR updates NASM’s preprocessor (asm/preproc.c) to (1) fix a hang when parsing %clear options (notably %clear context define), and (2) re-enable recursive multi-line macro (%rmacro) support by restoring the saved-invocation mechanism and adjusting cleanup/reference handling.
Changes:
- Fix
%clearoption parsing loop to advance tokens and avoid the previous infinite loop. - Reintroduce recursive mmacro invocation save/restore (
MMacroInvocation,push_mmacro(),pop_rmacro()). - Adjust recursive macro unwind logic and reference counting helpers to support recursion.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| if (fm->in_progress == 0) { | ||
| /* Only do full cleanup when all recursion levels done */ | ||
| if (fm->nolist & NL_LINE) { | ||
| istk->noline--; | ||
| } else if (!istk->noline) { |
| i->prev = m->prev; | ||
| i->params = m->params; | ||
| i->iline = m->iline; | ||
| i->iname = m->iname; | ||
| i->mstk = m->mstk; |
505a802 to
6394ef1
Compare
|
Independently confirmed this via AFL++ fuzzing. The %rmacro refcount bug triggers a heap-use-after-free under ASAN on both 3.01 and 3.02rc7 : |
…pport Fix infinite loop in %clear directive parsing. When parsing options like "%clear context define", the while loop never advanced to the next token, causing the preprocessor to hang indefinitely on the same token. Also re-enable the previously disabled recursive macro (rmacro) support: - Restore MMacroInvocation struct for saving/restoring macro state - Re-enable push_mmacro() to save invocation state before recursion - Add pop_rmacro() to properly restore state after recursive expansion - Add unref_mmacro() helper for reference counting during recursion - Fix macro exit handling to properly clean up at each recursion level
6394ef1 to
3c04ed7
Compare
|
This looks very interesting, but it is not 3.02 material. Holding it for a subsequent release. |
What's this about?
I ran into an issue where
%clear context definewould hang the preprocessor indefinitely. After digging into it, I found a simple bug in the token parsing loop - it never moved to the next token, so it just kept processing the same one forever.While I was in there, I also noticed the recursive macro (rmacro) support was commented out with
#if 0. I've re-enabled it and fixed up the reference counting so macros can properly recurse without leaking memory or crashing.Changes
%clear fix:
t = t->nextat the end of the option parsing loopbreakinstead of settingt = NULL(which would crash on the next iteration)Recursive macro support:
MMacroInvocationstruct that saves/restores macro state between recursive callspush_mmacro()to save state before recursingpop_rmacro()to restore state when unwindingunref_mmacro()helper for cleaner reference count managementTesting
Verified
%clear context defineno longer hangs and error messages for invalid options still work correctly.