From: Lukas Krickl Date: Mon, 4 Nov 2024 20:48:46 +0000 (+0100) Subject: Fixed macro expansion not allowing #defines to expand X-Git-Url: https://git.krickl.dev/?a=commitdiff_plain;h=f4af5b6cf85816466fb325732d3497fe4a17620d;p=ulas%2F.git Fixed macro expansion not allowing #defines to expand --- diff --git a/src/test.c b/src/test.c index 8b912b2..c54a422 100644 --- a/src/test.c +++ b/src/test.c @@ -90,7 +90,7 @@ void test_strbuf(void) { FILE *dst = fmemopen(dstbuf, ULAS_LINEMAX, "we"); \ assert(ulas_preproc(dst, src) == (expect_ret)); \ fclose(src); \ - fclose(dst); \ + fclose(dst); printf("%s\n", dstbuf); \ assert(strcmp(dstbuf, (expect_dst)) == 0); \ } @@ -123,12 +123,12 @@ void test_preproc(void) { "#macro test\n line $1 1 label$$$$,$$ $$\n line $2 2\n line $3 3 " "$0\n#endmacro\ntest p1, p2, p3"); assert_preproc("test macro with no args\n", 0, - "#macro test\ntest macro with no args\n#endmacro\ntest"); + "#macro mtest\ntest macro with no args\n#endmacro\nmtest"); assert_preproc("", -1, "#macro test\n not terminated\n"); assert_preproc( - "nested macro t1\nafter\ncontent n1\n", 0, - "#macro test\nnested macro $1\n#macro " - "nested\ncontent $1\n#endmacro\nafter\nnested n1\n#endmacro\ntest t1"); + "content macro t1\nt1\nafter\ncontent n1\n", 0, + "#macro test\nmnested macro $1\n$1\n#macro " + "mnested\ncontent $1\n#endmacro\nafter\nmnested n1\n#endmacro\ntest t1"); // this macro caused a heap buffer overflow in production code assert_preproc("ld a, verylongmacroinput & 0xFF\nld [hl+], a\nld a, " diff --git a/src/ulas.c b/src/ulas.c index 4cca861..a7767aa 100644 --- a/src/ulas.c +++ b/src/ulas.c @@ -959,6 +959,18 @@ char *ulas_preprocexpand(struct ulas_preproc *pp, const char *raw_line, strncat(pp->line.buf, tocat, tocatlen); } } + // expand macro result again to allow + // defines to appear in the macro + ulas_strensr(&pp->line2, strlen(pp->line.buf) + 1); + sprintf(pp->line2.buf, "%s", pp->line.buf); + unsigned long n = strlen(pp->line.buf); + pp->exp_depth++; + if (pp->exp_depth > ULAS_PREPROC_MAX_MACRO_DEPTH) { + ULASERR("Max macro recursion depth reached\n"); + goto end; + } + ulas_preprocexpand(pp, pp->line2.buf, &n); + pp->exp_depth--; goto end; } } @@ -1215,7 +1227,7 @@ int ulas_preprocnext(struct ulas_preproc *pp, FILE *dst, FILE *src, char *buf, } struct ulas_preproc ulas_preprocinit(void) { - struct ulas_preproc pp = {NULL, 0, ulas_str(1), ulas_str(1)}; + struct ulas_preproc pp = {NULL, 0, ulas_str(1), ulas_str(1), ulas_str(1)}; for (unsigned long i = 0; i < ULAS_MACROPARAMMAX; i++) { pp.macroparam[i] = ulas_str(8); } @@ -1224,7 +1236,8 @@ struct ulas_preproc ulas_preprocinit(void) { // set up initial defs for (int i = 0; i < ulascfg.defslen; i++) { - struct ulas_ppdef def = {ULAS_PPDEF, strdup(ulascfg.defs[i]), strdup(""), 0}; + struct ulas_ppdef def = {ULAS_PPDEF, strdup(ulascfg.defs[i]), strdup(""), + 0}; ulas_preprocdef(&pp, def); } @@ -1246,6 +1259,7 @@ void ulas_preprocclear(struct ulas_preproc *pp) { void ulas_preprocfree(struct ulas_preproc *pp) { ulas_strfree(&pp->line); + ulas_strfree(&pp->line2); ulas_strfree(&pp->tok); ulas_preprocclear(pp); diff --git a/src/ulas.h b/src/ulas.h index f85c5bf..4d09d37 100644 --- a/src/ulas.h +++ b/src/ulas.h @@ -263,12 +263,17 @@ struct ulas_symbuf { * Assembly context */ +#define ULAS_PREPROC_MAX_MACRO_DEPTH 255 + struct ulas_preproc { struct ulas_ppdef *defs; unsigned long defslen; struct ulas_str tok; struct ulas_str line; + struct ulas_str line2; + + int exp_depth; // macro parameter buffers struct ulas_str macroparam[ULAS_MACROPARAMMAX]; diff --git a/tests/t0.bin b/tests/t0.bin index bd436c2..aa12497 100644 Binary files a/tests/t0.bin and b/tests/t0.bin differ diff --git a/tests/t0.s b/tests/t0.s index 684ffa3..10a7bee 100644 --- a/tests/t0.s +++ b/tests/t0.s @@ -167,3 +167,12 @@ toplevel 5, 6 #ifndef ULAS_PREDEF xor a, a #endif + +#define DEFARG 1 + +#macro defarg + .db $1 + 1, $2 + .db $1 +#endmacro + +defarg DEFARG, 2 diff --git a/tests/t0_dasm.s b/tests/t0_dasm.s index c682cad..bddc3ef 100644 --- a/tests/t0_dasm.s +++ b/tests/t0_dasm.s @@ -120,4 +120,7 @@ dec b inc b ld b, 0x76 -.db 0x76 + halt + ld [bc], a + ld [bc], a +.db 0x1