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