From b0368a7010e00a5521acb12b20e23d68e77f35ae Mon Sep 17 00:00:00 2001 From: Christopher Snowhill Date: Wed, 15 Jan 2025 17:43:03 -0800 Subject: [PATCH] Visualization: Fix race condition on first launch crashing Due to a race condition with the visualization control racing with the Crashlytics consent dialog, it was possible that the repaint function would be called before the control was fully initialized, which would cause the visualization drawing code to crash due to division by zero error. The fix is two-fold: First guards were added to the borrowed code so that the draw functions won't run if they would later divide by zero on an uninitialized width property. Secondly, the top level visualization windows added a startup variable guard so their drawing code will return immediately if setup has not completed yet. Note that this bug was only just noticed in a recent App Store submission, but was unrelated to the recent commits to the code base, and could have triggered much earlier in the development cycle. Strangely, it did not. Signed-off-by: Christopher Snowhill --- Visualization/SpectrumViewCG.m | 5 +++++ Visualization/SpectrumViewSK.m | 5 +++++ Visualization/ThirdParty/deadbeef/analyzer.c | 4 ++++ 3 files changed, 14 insertions(+) diff --git a/Visualization/SpectrumViewCG.m b/Visualization/SpectrumViewCG.m index 3b42ccb75..dc633ff0a 100644 --- a/Visualization/SpectrumViewCG.m +++ b/Visualization/SpectrumViewCG.m @@ -26,6 +26,7 @@ extern NSString *CogPlaybackDidStopNotificiation; float saLowerBound; BOOL paused; BOOL stopped; + BOOL isSetup; BOOL isListening; BOOL observersAdded; BOOL isFullView; @@ -114,6 +115,8 @@ extern NSString *CogPlaybackDidStopNotificiation; _analyzer.mode = freqMode ? DDB_ANALYZER_MODE_FREQUENCIES : DDB_ANALYZER_MODE_OCTAVE_NOTE_BANDS; [self addObservers]; + + isSetup = YES; } - (void)enableFullView { @@ -385,6 +388,8 @@ extern NSString *CogPlaybackDidStopNotificiation; - (void)drawRect:(NSRect)dirtyRect { [super drawRect:dirtyRect]; + if(!isSetup) return; + [self updateVisListening]; [backgroundColor setFill]; diff --git a/Visualization/SpectrumViewSK.m b/Visualization/SpectrumViewSK.m index 3542ec914..6eae05045 100644 --- a/Visualization/SpectrumViewSK.m +++ b/Visualization/SpectrumViewSK.m @@ -29,6 +29,7 @@ extern NSString *CogPlaybackDidStopNotificiation; NSTimer *timer; BOOL paused; BOOL stopped; + BOOL isSetup; BOOL isListening; BOOL bandsReset; BOOL cameraControlEnabled; @@ -226,6 +227,8 @@ extern NSString *CogPlaybackDidStopNotificiation; _analyzer.mode = freqMode ? DDB_ANALYZER_MODE_FREQUENCIES : DDB_ANALYZER_MODE_OCTAVE_NOTE_BANDS; [self addObservers]; + + isSetup = YES; } - (void)addObservers { @@ -303,6 +306,8 @@ extern NSString *CogPlaybackDidStopNotificiation; } - (void)repaint { + if(!isSetup) return; + [self updateVisListening]; if(stopped) { diff --git a/Visualization/ThirdParty/deadbeef/analyzer.c b/Visualization/ThirdParty/deadbeef/analyzer.c index f98c0d5de..664e51e2f 100644 --- a/Visualization/ThirdParty/deadbeef/analyzer.c +++ b/Visualization/ThirdParty/deadbeef/analyzer.c @@ -241,6 +241,8 @@ _get_bar_height(ddb_analyzer_t *analyzer, float normalized_height, int view_heig static void _generate_frequency_labels(ddb_analyzer_t *analyzer) { + if(!analyzer->view_width) return; + float min_freq_log = log10(analyzer->min_freq); float max_freq_log = log10(analyzer->max_freq); float view_width = analyzer->view_width; @@ -273,6 +275,8 @@ _generate_frequency_labels(ddb_analyzer_t *analyzer) { static void _generate_frequency_bars(ddb_analyzer_t *analyzer) { + if(!analyzer->view_width) return; + float min_freq = analyzer->min_freq; float min_freq_log; float view_width = analyzer->view_width;