From bc309fe725168c74c9704f8659976e16504d3138 Mon Sep 17 00:00:00 2001 From: Christopher Snowhill Date: Sun, 26 Jun 2022 02:47:49 -0700 Subject: [PATCH] [Sandbox] Suggest URLs that are contained in CUEs Cuesheets can now expose which URLs they contain, which may help with sandbox path configuration. That is, if the CUE sheets are already readable. Signed-off-by: Christopher Snowhill --- Audio/AudioContainer.h | 1 + Audio/AudioContainer.m | 6 +++ Audio/CogPluginMulti.h | 1 + Audio/CogPluginMulti.m | 13 ++++++ Audio/Plugin.h | 4 ++ Audio/PluginController.mm | 23 +++++++++++ Plugins/CueSheet/CueSheetContainer.m | 40 +++++++++++++++++++ Preferences/Preferences/PathSuggester.m | 12 +++++- .../Preferences.xcodeproj/project.pbxproj | 2 + 9 files changed, 101 insertions(+), 1 deletion(-) diff --git a/Audio/AudioContainer.h b/Audio/AudioContainer.h index 0b92da666..f8aa73685 100644 --- a/Audio/AudioContainer.h +++ b/Audio/AudioContainer.h @@ -13,5 +13,6 @@ } + (NSArray *)urlsForContainerURL:(NSURL *)url; ++ (NSArray *)dependencyUrlsForContainerURL:(NSURL *)url; @end diff --git a/Audio/AudioContainer.m b/Audio/AudioContainer.m index 4390d936b..06204791d 100644 --- a/Audio/AudioContainer.m +++ b/Audio/AudioContainer.m @@ -18,4 +18,10 @@ } } ++ (NSArray *)dependencyUrlsForContainerURL:(NSURL *)url { + @autoreleasepool { + return [[PluginController sharedPluginController] dependencyUrlsForContainerURL:url]; + } +} + @end diff --git a/Audio/CogPluginMulti.h b/Audio/CogPluginMulti.h index 0fed368e4..00671ed0a 100644 --- a/Audio/CogPluginMulti.h +++ b/Audio/CogPluginMulti.h @@ -23,6 +23,7 @@ } + (NSArray *)urlsForContainerURL:(NSURL *)url containers:(NSArray *)containers; ++ (NSArray *)dependencyUrlsForContainerURL:(NSURL *)url containers:(NSArray *)containers; @end diff --git a/Audio/CogPluginMulti.m b/Audio/CogPluginMulti.m index 6bd90251d..66f2bdffb 100644 --- a/Audio/CogPluginMulti.m +++ b/Audio/CogPluginMulti.m @@ -171,6 +171,19 @@ static void *kCogDecoderMultiContext = &kCogDecoderMultiContext; return nil; } ++ (NSArray *)dependencyUrlsForContainerURL:(NSURL *)url containers:(NSArray *)containers { + NSArray *sortedContainers = sortClassesByPriority(containers); + for(NSString *classString in sortedContainers) { + Class container = NSClassFromString(classString); + if([container respondsToSelector:@selector(dependencyUrlsForContainerURL:)]) { + NSArray *urls = [container dependencyUrlsForContainerURL:url]; + if([urls count]) + return urls; + } + } + return nil; +} + @end @implementation CogMetadataReaderMulti diff --git a/Audio/Plugin.h b/Audio/Plugin.h index 3c6119520..e3db69361 100644 --- a/Audio/Plugin.h +++ b/Audio/Plugin.h @@ -25,6 +25,9 @@ + (float)priority; + (NSArray *)urlsForContainerURL:(NSURL *)url; + +@optional ++ (NSArray *)dependencyUrlsForContainerURL:(NSURL *)url; @end @protocol CogDecoder @@ -93,6 +96,7 @@ - (id)audioSourceForURL:(NSURL *)url; - (NSArray *)urlsForContainerURL:(NSURL *)url; +- (NSArray *)dependencyUrlsForContainerURL:(NSURL *)url; - (NSDictionary *)metadataForURL:(NSURL *)url skipCue:(BOOL)skip; - (NSDictionary *)propertiesForURL:(NSURL *)url skipCue:(BOOL)skip; - (id)audioDecoderForSource:(id)source skipCue:(BOOL)skip; diff --git a/Audio/PluginController.mm b/Audio/PluginController.mm index 799f518b7..bc4207e28 100644 --- a/Audio/PluginController.mm +++ b/Audio/PluginController.mm @@ -567,6 +567,29 @@ static NSString *xmlEscapeString(NSString * string) { return [container urlsForContainerURL:url]; } +- (NSArray *)dependencyUrlsForContainerURL:(NSURL *)url { + NSString *ext = [url pathExtension]; + NSArray *containerSet = [containers objectForKey:[ext lowercaseString]]; + NSString *classString; + if(containerSet) { + if([containerSet count] > 1) { + return [CogContainerMulti dependencyUrlsForContainerURL:url containers:containerSet]; + } else { + classString = [containerSet objectAtIndex:0]; + } + } else { + return nil; + } + + Class container = NSClassFromString(classString); + + if([container respondsToSelector:@selector(dependencyUrlsForContainerURL:)]) { + return [container dependencyUrlsForContainerURL:url]; + } else { + return nil; + } +} + // Note: Source is assumed to already be opened. - (id)audioDecoderForSource:(id)source skipCue:(BOOL)skip { NSString *ext = [[source url] pathExtension]; diff --git a/Plugins/CueSheet/CueSheetContainer.m b/Plugins/CueSheet/CueSheetContainer.m index 1fd287394..7f8b5a4e1 100644 --- a/Plugins/CueSheet/CueSheetContainer.m +++ b/Plugins/CueSheet/CueSheetContainer.m @@ -70,4 +70,44 @@ return tracks; } ++ (NSArray *)dependencyUrlsForContainerURL:(NSURL *)url { + if(![url isFileURL]) { + return @[]; + } + + if([url fragment]) { + NSString *pathString = [url path]; + NSString *lastComponent = [url lastPathComponent]; + + // Find that last component in the string from the end to make sure + // to get the last one + NSRange fragmentRange = [pathString rangeOfString:lastComponent options:NSBackwardsSearch]; + + // Chop the fragment. + NSString *newPathString = [pathString substringToIndex:fragmentRange.location + fragmentRange.length]; + + url = [NSURL fileURLWithPath:newPathString]; + } + + NSMutableArray *tracks = [NSMutableArray array]; + + CueSheet *cuesheet = nil; + + NSString *ext = [url pathExtension]; + if([ext caseInsensitiveCompare:@"cue"] != NSOrderedSame) { + return @[]; + } else + cuesheet = [CueSheet cueSheetWithFile:[url path]]; + + if(!cuesheet) + return @[]; + + for(CueSheetTrack *track in [cuesheet tracks]) { + if(![tracks containsObject:track.url]) + [tracks addObject:track.url]; + } + + return tracks; +} + @end diff --git a/Preferences/Preferences/PathSuggester.m b/Preferences/Preferences/PathSuggester.m index fe0223243..1391c4066 100644 --- a/Preferences/Preferences/PathSuggester.m +++ b/Preferences/Preferences/PathSuggester.m @@ -11,6 +11,8 @@ #import "SandboxBroker.h" +#import "AudioContainer.h" + // Sync, only declare items we need @interface PlaylistEntry @property(nonatomic) NSURL *_Nullable url; @@ -95,7 +97,15 @@ static NSURL *defaultMoviesDirectory(void) { NSMutableArray *items = [[NSMutableArray alloc] init]; NSMutableArray *itemPaths = [[NSMutableArray alloc] init]; - NSMutableArray *array = [[results valueForKey:@"url"] mutableCopy]; + NSArray *originalArray = [results valueForKey:@"url"]; + NSMutableArray *array = [originalArray mutableCopy]; + + for(NSURL *url in originalArray) { + NSArray *containedUrls = [AudioContainer dependencyUrlsForContainerURL:url]; + if(containedUrls && [containedUrls count] > 0) { + [array addObjectsFromArray:containedUrls]; + } + } // Add other system paths to this setting NSString *fileTreePath = [[NSUserDefaults standardUserDefaults] stringForKey:@"fileTreeRootURL"]; diff --git a/Preferences/Preferences/Preferences.xcodeproj/project.pbxproj b/Preferences/Preferences/Preferences.xcodeproj/project.pbxproj index cc920f0b2..0687baf01 100644 --- a/Preferences/Preferences/Preferences.xcodeproj/project.pbxproj +++ b/Preferences/Preferences/Preferences.xcodeproj/project.pbxproj @@ -102,6 +102,7 @@ 8307D31328606EAF000FF8EB /* growl@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "growl@2x.png"; path = "Icons/growl@2x.png"; sourceTree = ""; }; 8307D31428606EAF000FF8EB /* general.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = general.png; path = Icons/general.png; sourceTree = ""; }; 8307D31528606EAF000FF8EB /* growl.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = growl.png; path = Icons/growl.png; sourceTree = ""; }; + 832FAE812868566F008B48B3 /* AudioContainer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AudioContainer.h; path = ../../Audio/AudioContainer.h; sourceTree = ""; }; 833F681B1CDBCAA700AFB9F0 /* es */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.strings; name = es; path = es.lproj/InfoPlist.strings; sourceTree = ""; }; 833F681C1CDBCAA700AFB9F0 /* es */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = es; path = es.lproj/Localizable.strings; sourceTree = ""; }; 8347435D20E6D58800063D45 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/Preferences.strings; sourceTree = ""; }; @@ -203,6 +204,7 @@ 08FB77AFFE84173DC02AAC07 /* Classes */ = { isa = PBXGroup; children = ( + 832FAE812868566F008B48B3 /* AudioContainer.h */, 839E3B5728659B2700880EA2 /* AppController.h */, 83AC573E2861B77E009D6F50 /* SandboxBroker.h */, 8307D30828604ECF000FF8EB /* PlaylistController.h */,