diff --git a/src/asm/rpn.c b/src/asm/rpn.c index bb7aa871..cf94333e 100644 --- a/src/asm/rpn.c +++ b/src/asm/rpn.c @@ -46,17 +46,19 @@ static uint8_t *reserveSpace(struct Expression *expr, uint32_t size) /* If there isn't enough room to reserve the space, realloc */ if (!expr->tRPN) expr->nRPNCapacity = 256; /* Initial size */ - else if (expr->nRPNCapacity >= MAXRPNLEN) - /* - * To avoid generating humongous object files, cap the - * size of RPN expressions - */ - fatalerror("RPN expression cannot grow larger than " - EXPAND_AND_STR(MAXRPNLEN) " bytes\n"); - else if (expr->nRPNCapacity > MAXRPNLEN / 2) - expr->nRPNCapacity = MAXRPNLEN; - else - expr->nRPNCapacity *= 2; + while (expr->nRPNCapacity - expr->nRPNLength < size) { + if (expr->nRPNCapacity >= MAXRPNLEN) + /* + * To avoid generating humongous object files, cap the + * size of RPN expressions + */ + fatalerror("RPN expression cannot grow larger than " + EXPAND_AND_STR(MAXRPNLEN) " bytes\n"); + else if (expr->nRPNCapacity > MAXRPNLEN / 2) + expr->nRPNCapacity = MAXRPNLEN; + else + expr->nRPNCapacity *= 2; + } expr->tRPN = realloc(expr->tRPN, expr->nRPNCapacity); if (!expr->tRPN) diff --git a/test/asm/long-rpn-expression.asm b/test/asm/long-rpn-expression.asm index 150c8444..723c341a 100644 --- a/test/asm/long-rpn-expression.asm +++ b/test/asm/long-rpn-expression.asm @@ -27,3 +27,10 @@ X EQUS "{X7E}" X+X+X+X+X+X+X+X+X+X+X+X+X+X+X+X+X+X+X+X+X+X+X+X+X+X+X+X+X+X+X+X+X+X+X x: db 0 + +; this tests long RPN expressions being used as the RHS, as this once triggered +; a realloc bug + db 1+(x+X) + +; likewise, a long symbol could result in an insufficient *initial* allocation + db A00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000+0+0