aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMax <post@wickenrode.com>2018-01-13 01:32:58 +0100
committerMax <post@wickenrode.com>2018-01-13 01:32:58 +0100
commit7f43f5eb60ba409af7b56b185802f6bac1abe8e7 (patch)
tree0926e1eee8ee20eae03125fb015511224f57759b
parentb6e085eb89bcea1079b7892c6a67176771a25adb (diff)
downloadsequelpro-7f43f5eb60ba409af7b56b185802f6bac1abe8e7.tar.gz
sequelpro-7f43f5eb60ba409af7b56b185802f6bac1abe8e7.tar.bz2
sequelpro-7f43f5eb60ba409af7b56b185802f6bac1abe8e7.zip
Rewrote the theme loading method because it would too easily accept invalid data (part of #2963)
-rw-r--r--Source/SPEditorPreferencePane.m175
1 files changed, 103 insertions, 72 deletions
diff --git a/Source/SPEditorPreferencePane.m b/Source/SPEditorPreferencePane.m
index 7fc810ea..605d8a8b 100644
--- a/Source/SPEditorPreferencePane.m
+++ b/Source/SPEditorPreferencePane.m
@@ -915,92 +915,124 @@ static NSString *SPCustomColorSchemeNameLC = @"user-defined";
- (BOOL)_loadColorSchemeFromFile:(NSString *)filename
{
- NSError *readError = nil;
- NSString *convError = nil;
- NSPropertyListFormat format;
-
NSDictionary *theme = nil;
-
- NSData *pData = [NSData dataWithContentsOfFile:filename options:NSUncachedRead error:&readError];
-
- theme = [[NSPropertyListSerialization propertyListFromData:pData
- mutabilityOption:NSPropertyListImmutable format:&format errorDescription:&convError] retain];
-
- if (!theme || readError != nil || [convError length] || !(format == NSPropertyListXMLFormat_v1_0 || format == NSPropertyListBinaryFormat_v1_0)) {
- NSAlert *alert = [NSAlert alertWithMessageText:[NSString stringWithFormat:NSLocalizedString(@"Error while reading data file", @"error while reading data file")]
- defaultButton:NSLocalizedString(@"OK", @"OK button")
- alternateButton:nil
- otherButton:nil
- informativeTextWithFormat:NSLocalizedString(@"File couldn't be read.", @"error while reading data file")];
+
+ {
+ NSError *error = nil;
+ NSData *pData = [NSData dataWithContentsOfFile:filename options:NSUncachedRead error:&error];
- [alert setAlertStyle:NSCriticalAlertStyle];
- [alert runModal];
- if (theme) [theme release];
- [self updateDisplayColorThemeName];
- return NO;
+ if(pData && !error) {
+ theme = [NSPropertyListSerialization propertyListWithData:pData
+ options:NSPropertyListImmutable
+ format:NULL
+ error:&error];
+ }
+
+ if (!theme || error) {
+ NSAlert *alert = [NSAlert alertWithMessageText:[NSString stringWithFormat:NSLocalizedString(@"Error while reading data file", @"error while reading data file")]
+ defaultButton:NSLocalizedString(@"OK", @"OK button")
+ alternateButton:nil
+ otherButton:nil
+ informativeTextWithFormat:NSLocalizedString(@"File couldn't be read. (%@)", @"error while reading data file"), [error localizedDescription]];
+
+ [alert setAlertStyle:NSCriticalAlertStyle];
+ [alert runModal];
+
+ [self updateDisplayColorThemeName];
+ return NO;
+ }
}
- if ([theme objectForKey:@"settings"]
- && [[theme objectForKey:@"settings"] isKindOfClass:[NSArray class]]
- && [[theme objectForKey:@"settings"] count]
- && [[[theme objectForKey:@"settings"] objectAtIndex:0] isKindOfClass:[NSDictionary class]]
- && [[[theme objectForKey:@"settings"] objectAtIndex:0] objectForKey:@"settings"]) {
+ Class NSDictionaryClass = [NSDictionary class];
+ Class NSStringClass = [NSString class];
+
+ NSUInteger actuallyLoaded = 0;
+ NSArray *themeElements;
+ if ([theme isKindOfClass:NSDictionaryClass]
+ && (themeElements = [theme objectForKey:@"settings"])
+ && [themeElements isKindOfClass:[NSArray class]]
+ && [themeElements count]) {
+
+ NSInteger counter = -1;
- NSInteger counter = 0;
+ NSDictionary *mainPairs = @{
+ @"background": SPCustomQueryEditorBackgroundColor,
+ @"caret": SPCustomQueryEditorCaretColor,
+ @"foreground": SPCustomQueryEditorTextColor,
+ @"lineHighlight": SPCustomQueryEditorHighlightQueryColor,
+ @"selection": SPCustomQueryEditorSelectionColor,
+ };
- for (NSDictionary *dict in [theme objectForKey:@"settings"])
+ NSDictionary *optPairs = @{
+ @"Comment": SPCustomQueryEditorCommentColor,
+ @"String": SPCustomQueryEditorQuoteColor,
+ @"Keyword": SPCustomQueryEditorSQLKeywordColor,
+ @"User-defined constant": SPCustomQueryEditorBacktickColor,
+ @"Number": SPCustomQueryEditorNumericColor,
+ @"Variable": SPCustomQueryEditorVariableColor,
+ };
+
+ for (NSDictionary *dict in themeElements)
{
+ counter++;
+
+ if(![dict isKindOfClass:NSDictionaryClass]) {
+ SPLog(@"skipping unexpected object at settings[%ld]!",(long)counter);
+ continue;
+ }
+
+ //the first item is special and contains all the main theme colors
if (counter == 0) {
- if ([dict objectForKey:@"settings"]) {
- NSDictionary *dic = [dict objectForKey:@"settings"];
- if([dic objectForKey:@"background"])
- [prefs setObject:[NSArchiver archivedDataWithRootObject:[NSColor colorWithRGBHexString:[dic objectForKey:@"background"]]] forKey:SPCustomQueryEditorBackgroundColor];
- if([dic objectForKey:@"caret"])
- [prefs setObject:[NSArchiver archivedDataWithRootObject:[NSColor colorWithRGBHexString:[dic objectForKey:@"caret"]]] forKey:SPCustomQueryEditorCaretColor];
- if([dic objectForKey:@"foreground"])
- [prefs setObject:[NSArchiver archivedDataWithRootObject:[NSColor colorWithRGBHexString:[dic objectForKey:@"foreground"]]] forKey:SPCustomQueryEditorTextColor];
- if([dic objectForKey:@"lineHighlight"])
- [prefs setObject:[NSArchiver archivedDataWithRootObject:[NSColor colorWithRGBHexString:[dic objectForKey:@"lineHighlight"]]] forKey:SPCustomQueryEditorHighlightQueryColor];
- if([dic objectForKey:@"selection"])
- [prefs setObject:[NSArchiver archivedDataWithRootObject:[NSColor colorWithRGBHexString:[dic objectForKey:@"selection"]]] forKey:SPCustomQueryEditorSelectionColor];
- }
+ NSDictionary *dic = [dict objectForKey:@"settings"];
+ if ([dic isKindOfClass:NSDictionaryClass]) {
+ for(NSString *key in mainPairs) {
+ NSString *rgbHex = [dic objectForKey:key];
+ NSColor *color;
+ if([rgbHex isKindOfClass:NSStringClass] && (color = [NSColor colorWithRGBHexString:rgbHex])) {
+ [prefs setObject:[NSArchiver archivedDataWithRootObject:color] forKey:[mainPairs objectForKey:key]];
+ actuallyLoaded++;
+ }
+ else {
+ SPLog(@"Main color key '%@' is either missing in theme or failed parsing as hex color (at settings[0].settings)!", key);
+ }
+ }
+ }
else {
- continue;
+ SPLog(@"Unexpected type for object main settings (at settings[0].settings)");
}
}
else {
- if ([dict objectForKey:@"name"] && [dict objectForKey:@"settings"] && [[dict objectForKey:@"settings"] isKindOfClass:[NSDictionary class]] && [[dict objectForKey:@"settings"] objectForKey:@"foreground"]) {
- if ([[dict objectForKey:@"name"] isEqualToString:@"Comment"])
- [prefs setObject:[NSArchiver archivedDataWithRootObject:
- [NSColor colorWithRGBHexString:[[dict objectForKey:@"settings"] objectForKey:@"foreground"]]]
- forKey:SPCustomQueryEditorCommentColor];
- else if ([[dict objectForKey:@"name"] isEqualToString:@"String"])
- [prefs setObject:[NSArchiver archivedDataWithRootObject:
- [NSColor colorWithRGBHexString:[[dict objectForKey:@"settings"] objectForKey:@"foreground"]]]
- forKey:SPCustomQueryEditorQuoteColor];
- else if ([[dict objectForKey:@"name"] isEqualToString:@"Keyword"])
- [prefs setObject:[NSArchiver archivedDataWithRootObject:
- [NSColor colorWithRGBHexString:[[dict objectForKey:@"settings"] objectForKey:@"foreground"]]]
- forKey:SPCustomQueryEditorSQLKeywordColor];
- else if ([[dict objectForKey:@"name"] isEqualToString:@"User-defined constant"])
- [prefs setObject:[NSArchiver archivedDataWithRootObject:
- [NSColor colorWithRGBHexString:[[dict objectForKey:@"settings"] objectForKey:@"foreground"]]]
- forKey:SPCustomQueryEditorBacktickColor];
- else if ([[dict objectForKey:@"name"] isEqualToString:@"Number"])
- [prefs setObject:[NSArchiver archivedDataWithRootObject:
- [NSColor colorWithRGBHexString:[[dict objectForKey:@"settings"] objectForKey:@"foreground"]]]
- forKey:SPCustomQueryEditorNumericColor];
- else if ([[dict objectForKey:@"name"] isEqualToString:@"Variable"])
- [prefs setObject:[NSArchiver archivedDataWithRootObject:
- [NSColor colorWithRGBHexString:[[dict objectForKey:@"settings"] objectForKey:@"foreground"]]]
- forKey:SPCustomQueryEditorVariableColor];
+ NSString *optName = [dict objectForKey:@"name"];
+ NSDictionary *optSettings = [dict objectForKey:@"settings"];
+
+ if ([optName isKindOfClass:NSStringClass] && [optSettings isKindOfClass:NSDictionaryClass]) {
+ NSString *prefName = [optPairs objectForKey:optName];
+ if(prefName) {
+ NSString *rgbHex = [optSettings objectForKey:@"foreground"];
+ NSColor *color;
+ if([rgbHex isKindOfClass:NSStringClass] && (color = [NSColor colorWithRGBHexString:rgbHex])) {
+ [prefs setObject:[NSArchiver archivedDataWithRootObject:color] forKey:prefName];
+ actuallyLoaded++;
+ }
+ else {
+ SPLog(@"Color for entry '%@' is either missing in theme or failed parsing as hex color (at settings[%ld].settings.foreground)!", optName, counter);
+ }
+ }
+ else {
+ SPLog(@"Skipping unknown color entry '%@' (at settings[%ld].name)", optName, counter);
+ }
+ }
+ else {
+ SPLog(@"Skipping invalid color entry: Either missing keys and/or unexpected objects (at settings[%ld])!", counter);
}
}
-
- counter++;
}
-
- [theme release];
+ }
+ else {
+ SPLog(@"root key 'settings' is missing, has an unexpected type or is empty in theme file!");
+ }
+
+ if(actuallyLoaded > 0) {
[colorSettingTableView setBackgroundColor:[NSUnarchiver unarchiveObjectWithData:[prefs dataForKey:SPCustomQueryEditorBackgroundColor]]];
[colorSettingTableView reloadData];
}
@@ -1013,7 +1045,6 @@ static NSString *SPCustomColorSchemeNameLC = @"user-defined";
[alert setAlertStyle:NSInformationalAlertStyle];
[alert runModal];
- [theme release];
return NO;
}