diff --git a/check/fixes.frm b/check/fixes.frm index fa21fc7b..61e9c522 100644 --- a/check/fixes.frm +++ b/check/fixes.frm @@ -5141,3 +5141,17 @@ Global F1 = E{`i' % 10}*E2*E3*E4; .end assert succeeded? *--#] Issue808 : +*--#[ Issue242 : +* An #endif without a matching #if must be diagnosed deterministically. +* Previously the preprocessor peeked at the uninitialized sentinel slot of +* the PreTypes stack (PreTypes[0] with NumPreTypes == 0), so the behavior +* depended on heap garbage (Valgrind: "Conditional jump or move depends on +* uninitialised value" in DoEndif, reported at +* https://github.com/form-dev/form/issues/242). +#ifdef `A' +#message A is defined +#endif +#endif +.end +assert preprocess_error?("#endif without corresponding #if") +*--#] Issue242 : diff --git a/sources/startup.c b/sources/startup.c index 126b7d3b..b444f498 100644 --- a/sources/startup.c +++ b/sources/startup.c @@ -1306,6 +1306,13 @@ void StartVariables(void) AP.MaxPreTypes = 10; AP.NumPreTypes = 0; AP.PreTypes = (int *)Malloc1(sizeof(int)*(AP.MaxPreTypes+1),"preprocessor types"); +/* + The sentinel slot must be initialized: with an empty stack the + preprocessor termination handlers (DoEndif, DoElse, DoElseif, ...) + peek at PreTypes[NumPreTypes] == PreTypes[0], and Malloc1 does not + zero the memory. +*/ + AP.PreTypes[0] = PRETYPENONE; AP.inside.buffer = 0; AP.inside.size = 0;