Skip to content

Commit 4af8e56

Browse files
committed
platform_darwin: fix URLForResource filter dir extraction
GCC on 10.5 SDK emitted: platform_darwin.m:465: warning: passing argument 2 of strlcpy from incompatible pointer type ROOT CAUSE: the expression [[url baseURL] fileSystemRepresentation] had two separate problems. 1. LOGIC BUG (preexisting, silent): -[NSURL baseURL] returns the URL that the receiver was constructed relative to. For URLs made absolutely - which is what -[NSBundle URLForResource:withExtension: subdirectory:] returns - baseURL is nil. Messaging -fileSystemRepresentation on nil returns (const char *)0, and strlcpy then reads from a NULL source pointer. This was a latent bug that predates this audit. 2. COMPILE WARNING (the reported symptom): on the 10.5 SDK, NSURL doesn't declare -fileSystemRepresentation (that selector was only added to NSURL in 10.9). GCC 4.0 resolves the selector against NSString's declaration - which returns const char * and would match strlcpy - but warns about incompatible pointer type because the receiver [url baseURL] is typed NSURL*, not NSString*. FIX: replace both sites with [[[url path] stringByDeletingLastPathComponent] UTF8String] All three selectors are 10.0-era NSString methods, unambiguous, and warning-clean. Also semantically correct: URLForResource:nil with a subdirectory returns the URL of the *first matching file* in that subdirectory; what we want is its containing directory, which is exactly what stringByDeletingLastPathComponent gives us. The pattern matches ui/drivers/ui_cocoa.m:193 which already does [url.path UTF8String] for the same NSURL-to-C-string conversion. No behavioral change on bundles that don't ship inline filter files (the URLForResource: call returns nil and the fill_pathname_join fallback runs as before). On bundles that do, the audio/video filter dirs will now resolve to the correct directory instead of dereferencing NULL.
1 parent da2b16d commit 4af8e56

1 file changed

Lines changed: 13 additions & 2 deletions

File tree

frontend/drivers/platform_darwin.m

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -455,14 +455,25 @@ static void frontend_darwin_get_env(int *argc, char *argv[],
455455
if ([[NSBundle mainBundle] respondsToSelector:url_for_resource_sel])
456456
url = [[NSBundle mainBundle] URLForResource:nil withExtension:@"dsp" subdirectory:@"filters/audio"];
457457
if (url)
458-
strlcpy(g_defaults.dirs[DEFAULT_DIR_AUDIO_FILTER], [[url baseURL] fileSystemRepresentation], sizeof(g_defaults.dirs[DEFAULT_DIR_AUDIO_FILTER]));
458+
/* URLForResource: with a nil name returns a URL pointing at
459+
* the first matching .dsp file. What we want is the directory
460+
* it lives in, so strip the last path component.
461+
*
462+
* The previous code used [[url baseURL] fileSystemRepresentation],
463+
* which was wrong on two counts: -baseURL returns nil for URLs
464+
* constructed absolutely (which is what URLForResource: returns),
465+
* so the result was a NULL source pointer into strlcpy; and on
466+
* pre-10.9 SDKs NSURL doesn't declare -fileSystemRepresentation,
467+
* so GCC resolved the selector against NSString's version with
468+
* an incompatible-receiver warning. */
469+
strlcpy(g_defaults.dirs[DEFAULT_DIR_AUDIO_FILTER], [[[url path] stringByDeletingLastPathComponent] UTF8String], sizeof(g_defaults.dirs[DEFAULT_DIR_AUDIO_FILTER]));
459470
else
460471
fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_AUDIO_FILTER], application_data, "filters/audio", sizeof(g_defaults.dirs[DEFAULT_DIR_AUDIO_FILTER]));
461472
url = nil;
462473
if ([[NSBundle mainBundle] respondsToSelector:url_for_resource_sel])
463474
url = [[NSBundle mainBundle] URLForResource:nil withExtension:@"filt" subdirectory:@"filters/video"];
464475
if (url)
465-
strlcpy(g_defaults.dirs[DEFAULT_DIR_VIDEO_FILTER], [[url baseURL] fileSystemRepresentation], sizeof(g_defaults.dirs[DEFAULT_DIR_VIDEO_FILTER]));
476+
strlcpy(g_defaults.dirs[DEFAULT_DIR_VIDEO_FILTER], [[[url path] stringByDeletingLastPathComponent] UTF8String], sizeof(g_defaults.dirs[DEFAULT_DIR_VIDEO_FILTER]));
466477
else
467478
fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_VIDEO_FILTER], application_data, "filters/video", sizeof(g_defaults.dirs[DEFAULT_DIR_VIDEO_FILTER]));
468479
fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_CORE_INFO], application_data, "info", sizeof(g_defaults.dirs[DEFAULT_DIR_CORE_INFO]));

0 commit comments

Comments
 (0)