[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 <kode54@gmail.com>
lastfm
Christopher Snowhill 2022-06-26 02:47:49 -07:00
parent 378f710cee
commit bc309fe725
9 changed files with 101 additions and 1 deletions

View File

@ -13,5 +13,6 @@
} }
+ (NSArray *)urlsForContainerURL:(NSURL *)url; + (NSArray *)urlsForContainerURL:(NSURL *)url;
+ (NSArray *)dependencyUrlsForContainerURL:(NSURL *)url;
@end @end

View File

@ -18,4 +18,10 @@
} }
} }
+ (NSArray *)dependencyUrlsForContainerURL:(NSURL *)url {
@autoreleasepool {
return [[PluginController sharedPluginController] dependencyUrlsForContainerURL:url];
}
}
@end @end

View File

@ -23,6 +23,7 @@
} }
+ (NSArray *)urlsForContainerURL:(NSURL *)url containers:(NSArray *)containers; + (NSArray *)urlsForContainerURL:(NSURL *)url containers:(NSArray *)containers;
+ (NSArray *)dependencyUrlsForContainerURL:(NSURL *)url containers:(NSArray *)containers;
@end @end

View File

@ -171,6 +171,19 @@ static void *kCogDecoderMultiContext = &kCogDecoderMultiContext;
return nil; 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 @end
@implementation CogMetadataReaderMulti @implementation CogMetadataReaderMulti

View File

@ -25,6 +25,9 @@
+ (float)priority; + (float)priority;
+ (NSArray *)urlsForContainerURL:(NSURL *)url; + (NSArray *)urlsForContainerURL:(NSURL *)url;
@optional
+ (NSArray *)dependencyUrlsForContainerURL:(NSURL *)url;
@end @end
@protocol CogDecoder <NSObject> @protocol CogDecoder <NSObject>
@ -93,6 +96,7 @@
- (id<CogSource>)audioSourceForURL:(NSURL *)url; - (id<CogSource>)audioSourceForURL:(NSURL *)url;
- (NSArray *)urlsForContainerURL:(NSURL *)url; - (NSArray *)urlsForContainerURL:(NSURL *)url;
- (NSArray *)dependencyUrlsForContainerURL:(NSURL *)url;
- (NSDictionary *)metadataForURL:(NSURL *)url skipCue:(BOOL)skip; - (NSDictionary *)metadataForURL:(NSURL *)url skipCue:(BOOL)skip;
- (NSDictionary *)propertiesForURL:(NSURL *)url skipCue:(BOOL)skip; - (NSDictionary *)propertiesForURL:(NSURL *)url skipCue:(BOOL)skip;
- (id<CogDecoder>)audioDecoderForSource:(id<CogSource>)source skipCue:(BOOL)skip; - (id<CogDecoder>)audioDecoderForSource:(id<CogSource>)source skipCue:(BOOL)skip;

View File

@ -567,6 +567,29 @@ static NSString *xmlEscapeString(NSString * string) {
return [container urlsForContainerURL:url]; 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. // Note: Source is assumed to already be opened.
- (id<CogDecoder>)audioDecoderForSource:(id<CogSource>)source skipCue:(BOOL)skip { - (id<CogDecoder>)audioDecoderForSource:(id<CogSource>)source skipCue:(BOOL)skip {
NSString *ext = [[source url] pathExtension]; NSString *ext = [[source url] pathExtension];

View File

@ -70,4 +70,44 @@
return tracks; 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 @end

View File

@ -11,6 +11,8 @@
#import "SandboxBroker.h" #import "SandboxBroker.h"
#import "AudioContainer.h"
// Sync, only declare items we need // Sync, only declare items we need
@interface PlaylistEntry @interface PlaylistEntry
@property(nonatomic) NSURL *_Nullable url; @property(nonatomic) NSURL *_Nullable url;
@ -95,7 +97,15 @@ static NSURL *defaultMoviesDirectory(void) {
NSMutableArray *items = [[NSMutableArray alloc] init]; NSMutableArray *items = [[NSMutableArray alloc] init];
NSMutableArray *itemPaths = [[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 // Add other system paths to this setting
NSString *fileTreePath = [[NSUserDefaults standardUserDefaults] stringForKey:@"fileTreeRootURL"]; NSString *fileTreePath = [[NSUserDefaults standardUserDefaults] stringForKey:@"fileTreeRootURL"];

View File

@ -102,6 +102,7 @@
8307D31328606EAF000FF8EB /* growl@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "growl@2x.png"; path = "Icons/growl@2x.png"; sourceTree = "<group>"; }; 8307D31328606EAF000FF8EB /* growl@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "growl@2x.png"; path = "Icons/growl@2x.png"; sourceTree = "<group>"; };
8307D31428606EAF000FF8EB /* general.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = general.png; path = Icons/general.png; sourceTree = "<group>"; }; 8307D31428606EAF000FF8EB /* general.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = general.png; path = Icons/general.png; sourceTree = "<group>"; };
8307D31528606EAF000FF8EB /* growl.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = growl.png; path = Icons/growl.png; sourceTree = "<group>"; }; 8307D31528606EAF000FF8EB /* growl.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = growl.png; path = Icons/growl.png; sourceTree = "<group>"; };
832FAE812868566F008B48B3 /* AudioContainer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AudioContainer.h; path = ../../Audio/AudioContainer.h; sourceTree = "<group>"; };
833F681B1CDBCAA700AFB9F0 /* es */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.strings; name = es; path = es.lproj/InfoPlist.strings; sourceTree = "<group>"; }; 833F681B1CDBCAA700AFB9F0 /* es */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.strings; name = es; path = es.lproj/InfoPlist.strings; sourceTree = "<group>"; };
833F681C1CDBCAA700AFB9F0 /* es */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = es; path = es.lproj/Localizable.strings; sourceTree = "<group>"; }; 833F681C1CDBCAA700AFB9F0 /* es */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = es; path = es.lproj/Localizable.strings; sourceTree = "<group>"; };
8347435D20E6D58800063D45 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/Preferences.strings; sourceTree = "<group>"; }; 8347435D20E6D58800063D45 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/Preferences.strings; sourceTree = "<group>"; };
@ -203,6 +204,7 @@
08FB77AFFE84173DC02AAC07 /* Classes */ = { 08FB77AFFE84173DC02AAC07 /* Classes */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
832FAE812868566F008B48B3 /* AudioContainer.h */,
839E3B5728659B2700880EA2 /* AppController.h */, 839E3B5728659B2700880EA2 /* AppController.h */,
83AC573E2861B77E009D6F50 /* SandboxBroker.h */, 83AC573E2861B77E009D6F50 /* SandboxBroker.h */,
8307D30828604ECF000FF8EB /* PlaylistController.h */, 8307D30828604ECF000FF8EB /* PlaylistController.h */,