8c172e6c4b985af79bf1a1f47c9db92ce0578999
max
  Tue Sep 15 05:47:36 2026 -0700
errCatch: put errAbort's doContentType back the way it found it, refs #38353

hVaUserAbort() turns doContentType on so that a user error reaches the browser when the CGI
has not pushed a warn handler of its own.  Inside an errCatch that is pointless -- the abort
is caught and never reaches the default handler -- and the flag stayed on afterwards, so a
later genuine abort on a page that had already written its header would print a second
Content-Type line into the body.  Everywhere else in the tree the flag is something a caller
turns back off.

errCatchPushHandlers() now records the flag and errCatchEnd() restores it, which covers every
caller rather than just the one that set it.  errAbortGetDoContentType() is the reader.

diff --git src/inc/errCatch.h src/inc/errCatch.h
index bcaec62dfc3..2c28edc6bd2 100644
--- src/inc/errCatch.h
+++ src/inc/errCatch.h
@@ -16,30 +16,31 @@
 #ifndef ERRCATCH_H
 #define ERRCATCH_H
 
 #ifndef DYSTRING_H
     #include "dystring.h"
 #endif
 
 struct errCatch
 /* Something to help catch errors.   */
     {
     struct errCatch *next;	 /* Next in stack. */
     jmp_buf jmpBuf;		 /* Where to jump back to for recovery. */
     struct dyString *message; /* Error message if any */
     boolean gotError;		 /* Some sort of error was caught. */
     boolean gotWarning;		 /* Some sort of error warning was raised. */
+    boolean savedDoContentType;  /* errAbort's doContentType as it was on entry; see below. */
     };
 
 struct errCatch *errCatchNew();
 /* Return new error catching structure. */
 
 void errCatchFree(struct errCatch **pErrCatch);
 /* Free up resources associated with errCatch */
 
 #define errCatchStart(e) (errCatchPushHandlers(e) && setjmp(e->jmpBuf) == 0)
 /* Little wrapper around setjmp.  This returns TRUE
  * on the main execution thread, FALSE after abort. */
 
 
 boolean errCatchPushHandlers(struct errCatch *errCatch);
 /* Push error handlers.  Not usually called directly.