From 0e8089432b8f1ef140b19ac24bd46293fb3ff522 Mon Sep 17 00:00:00 2001 From: David Griffith Date: Sun, 23 Jun 2019 17:11:45 -0700 Subject: [PATCH] Fix problem of os_fatal() trying to write to SDL window when SDL not active. If we have a showstopping problem right from the start, like trying to load a file that's not a Zcode file or Blorb file that lacks a Zcode chunk, then Frotz will call os_fatal() to complain about it and then exit. But sfrotz's version of os_fatal doesn't check if SDL is active or not before calling functions that depend on SDL. The first of these is os_set_text_style(). This leads to a segfault when a call of current.font->getglyph(current.font,c,1); dereferences getglyph, which does not exist because current is not properly initialized yet. --- src/sdl/sf_frotz.h | 2 ++ src/sdl/sf_resource.c | 44 +++++++++++++++++++++++++------------------ src/sdl/sf_video.c | 5 +++++ 3 files changed, 33 insertions(+), 18 deletions(-) diff --git a/src/sdl/sf_frotz.h b/src/sdl/sf_frotz.h index 7fbf312..22e6aaa 100644 --- a/src/sdl/sf_frotz.h +++ b/src/sdl/sf_frotz.h @@ -93,6 +93,8 @@ extern int m_frequency; extern double m_gamma; +extern bool sdl_active; + // sf_resource.c // must be called as soon as possible (i.e. by os_process_arguments()) diff --git a/src/sdl/sf_resource.c b/src/sdl/sf_resource.c index 386cf31..f3a91f5 100644 --- a/src/sdl/sf_resource.c +++ b/src/sdl/sf_resource.c @@ -50,6 +50,8 @@ char * m_reslist_file = NULL; char * m_setupfile = ".sfrotzrc"; extern int m_frequency; +bool sdl_active; + static int countedpics = 0; static int maxlegalpic = 0; static int releaseno = 0; @@ -780,37 +782,41 @@ void os_fatal(const char *s, ...) // if (theWnd != NULL) // theWnd->FlushDisplay(); - os_set_text_style(0); - - - os_display_string((zchar *)"\n\n"); - os_beep(BEEP_HIGH); - os_set_text_style(BOLDFACE_STYLE); - fprintf(stderr,"\n%s: ",sf_msgstring(IDS_FATAL)); va_start( m, s); vfprintf( stderr, s, m); va_end(m); fprintf(stderr,"\n"); - os_display_string((zchar *)"Fatal error: "); - os_set_text_style(0); - os_display_string((zchar *)s); - os_display_string((zchar *)"\n\n"); - new_line(); - flush_buffer(); + if (sdl_active) { + os_set_text_style(0); + os_display_string((zchar *)"\n\n"); + os_beep(BEEP_HIGH); + os_set_text_style(BOLDFACE_STYLE); - if (f_setup.ignore_errors) { - os_display_string((zchar *)"Continuing anyway..."); - new_line(); + os_display_string((zchar *)"Fatal error: "); + os_set_text_style(0); + os_display_string((zchar *)s); + os_display_string((zchar *)"\n\n"); new_line(); + flush_buffer(); + } + + if (f_setup.ignore_errors) { + if (sdl_active) { + os_display_string((zchar *)"Continuing anyway..."); + new_line(); + new_line(); + } fprintf(stderr, "Continuing anyway...\n"); return; } - os_reset_screen(); + if (sdl_active) { + os_reset_screen(); + SDL_Quit(); + } sf_cleanup_all(); - SDL_Quit(); exit(EXIT_FAILURE); // ::MessageBox(AfxGetMainWnd()->GetSafeHwnd(),s,CResString(IDS_FATAL),MB_ICONERROR|MB_OK); @@ -1068,4 +1074,6 @@ void os_init_setup(void) f_setup.sound = 1; f_setup.err_report_mode = ERR_DEFAULT_REPORT_MODE; f_setup.restore_mode = 0; + + sdl_active = FALSE; } diff --git a/src/sdl/sf_video.c b/src/sdl/sf_video.c index d10782a..6dbceb6 100644 --- a/src/sdl/sf_video.c +++ b/src/sdl/sf_video.c @@ -22,6 +22,8 @@ static SDL_Renderer *renderer = NULL; static SDL_Texture *texture = NULL; int m_timerinterval = 100; +bool sdl_active; + static void sf_quitconf(); // clipping region @@ -433,6 +435,9 @@ void sf_initvideo( int W, int H, int full) if ( SDL_Init(initflags) < 0 ) { os_fatal("Couldn't initialize SDL: %s", SDL_GetError()); } + + sdl_active = TRUE; + /* We don't handle text edit events. Not that I know why anyone would want to use such an IME with Frotz. */ SDL_SetHint(SDL_HINT_IME_INTERNAL_EDITING, "1"); -- 2.34.1