@@ -614,18 +614,19 @@ IllPos: MesPrint("&Illegal character at this position: %s",in);
614614 if ( error == 0 && ( numexp = simp3atoken (AC .tokens ,leftright ) ) < 0 )
615615 error = 1 ;
616616 if ( numexp > 0 ) {
617+ // Make some space at the beginning of AC.tokens, filled with TEMPTY.
617618 SBYTE * tt ;
618619 out = AC .tokens ;
619620 while ( * out != TENDOFIT ) out ++ ;
620- while ( out + numexp * 9 + 20 > outtop ) {
621+ while ( out + numexp * 9 > outtop ) {
621622 LONG oldsize = (LONG )(out - AC .tokens );
622623 SBYTE * * ppp = & (AC .tokens ); /* to avoid a compiler warning */
623624 SBYTE * * pppp = & (AC .toptokens );
624625 DoubleBuffer ((void * * )ppp ,(void * * )pppp ,sizeof (SBYTE ),"out tokens" );
625626 out = AC .tokens + oldsize ;
626627 outtop = AC .toptokens - MAXNUMSIZE ;
627628 }
628- tt = out + numexp * 9 + 20 ;
629+ tt = out + numexp * 9 ;
629630 while ( out >= AC .tokens ) { * tt -- = * out -- ; }
630631 while ( tt >= AC .tokens ) { * tt -- = TEMPTY ; }
631632 if ( error == 0 && simp3btoken (AC .tokens ,leftright ) ) error = 1 ;
@@ -1441,15 +1442,33 @@ int simp3btoken(SBYTE *s, int mode)
14411442 SBYTE * t , c , * fill , * ff , * ss ;
14421443 LONG num ;
14431444 WORD * prot ;
1445+
1446+ // Work in a temporary buffer, to avoid clashes between input and output
1447+ SBYTE * tmptokens = (SBYTE * )Malloc1 ((AC .toptokens - AC .tokens )* sizeof (SBYTE ), "simp3btoken scratch" );
1448+ SBYTE * tmptoptokens = tmptokens + (AC .toptokens - AC .tokens );
1449+ fill = tmptokens ;
1450+
14441451 if ( mode == RHSIDE ) {
14451452 prot = AC .ProtoType ;
14461453 numprot = prot [1 ] - SUBEXPSIZE ;
14471454 prot += SUBEXPSIZE ;
14481455 }
14491456 else { prot = 0 ; numprot = 0 ; }
1450- fill = s ;
14511457 while ( * s == TEMPTY ) s ++ ;
14521458 while ( * s != TENDOFIT ) {
1459+ // If we are near the end of the output buffer, we'd better reallocate
1460+ // both tmptokens and AC.tokens (which must fit the final result).
1461+ // Experimentally, fill can move by at most 5 per loop iteration, but
1462+ // this buffer of 20 of might not be enough for all cases!
1463+ while ( tmptoptokens - fill < 20 ) {
1464+ LONG tmppos ;
1465+ tmppos = s - AC .tokens ;
1466+ DoubleBuffer ((void * * )& (AC .tokens ), (void * * )& (AC .toptokens ), sizeof (SBYTE ), "simp3btoken double" );
1467+ s = AC .tokens + tmppos ;
1468+ tmppos = fill - tmptokens ;
1469+ DoubleBuffer ((void * * )& tmptokens , (void * * )& tmptoptokens , sizeof (SBYTE ), "simp3btoken scratch double" );
1470+ fill = tmptokens + tmppos ;
1471+ }
14531472 if ( * s == TEMPTY ) { s ++ ; continue ; }
14541473 denom = 1 ;
14551474 if ( * s == TDIVIDE ) { denom = -1 ; * fill ++ = * s ++ ; }
@@ -1807,9 +1826,17 @@ nodot: MesPrint("&Illegal second element in dotproduct");
18071826 }
18081827 }
18091828 * fill = TENDOFIT ;
1829+ // Now copy the modified tokens back to the original buffer
1830+ fill = tmptokens ;
1831+ s = AC .tokens ;
1832+ do {
1833+ * s ++ = * fill ;
1834+ } while ( * fill ++ != TENDOFIT );
1835+ M_free (tmptokens , "simp3btoken scratch" );
18101836 return (error );
18111837doublepower :;
18121838 MesPrint ("&Dubious notation with power of power" );
1839+ M_free (tmptokens , "simp3btoken scratch" );
18131840 return (-1 );
18141841}
18151842
0 commit comments