+2007-09-14 Darin Adler <darin@apple.com>
+
+ Reviewed by Geoff Garen and Tim Hatcher.
+
+ - fixed <rdar://problem/5482745> initFromCoder: and initWithPropertyList: functions
+ should guard against incorrect types
+
+ * WebView/WebArchive.m:
+ (isArrayOfClass): Added helper function.
+ (-[WebArchive _initWithPropertyList:]): Tweaked function to remove the need for a
+ type cast.
+ (-[WebArchive initWithCoder:]): Added type checking for the main resource,
+ subresources array, and subframe archives array. Also replaced NS_DURING with @try.
+ * WebView/WebPreferences.m: (-[WebPreferences initWithCoder:]): Added type checking
+ for the identifier and the values dictionary, including ensuring that it's a mutable
+ dictionary.
+ * WebView/WebResource.mm:
+ (-[WebResource initWithCoder:]): Added type checking for all the fields.
+ (-[WebResource _initWithPropertyList:]): Added type checking for the NSURLResponse.
+
+ * WebKit.exp: Removed accidentally exported internal symbol; I checked and it's not
+ used anywhere.
+
2007-09-13 Darin Adler <darin@apple.com>
Reviewed by Oliver.
_WebKitErrorPlugInNameKey
_WebKitErrorPlugInPageURLStringKey
_WebLocalizedString
-_WebMainResourceKey
_WebPlugInAttributesKey
_WebPlugInBaseURLKey
_WebPlugInContainerKey
/*
- * Copyright (C) 2005 Apple Computer, Inc. All rights reserved.
+ * Copyright (C) 2005, 2006, 2007 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#import <WebKit/WebArchive.h>
+#import "WebArchive.h"
-#import <WebKit/WebKitLogging.h>
-#import <WebKit/WebResourcePrivate.h>
+#import "WebKitLogging.h"
+#import "WebResourcePrivate.h"
-NSString *WebArchivePboardType = @"Apple Web Archive pasteboard type";
-NSString *WebMainResourceKey = @"WebMainResource";
-NSString *WebSubresourcesKey = @"WebSubresources";
-NSString *WebSubframeArchivesKey = @"WebSubframeArchives";
+NSString *WebArchivePboardType = @"Apple Web Archive pasteboard type";
-#define WebArchiveVersion 1
+static NSString * const WebMainResourceKey = @"WebMainResource";
+static NSString * const WebSubresourcesKey = @"WebSubresources";
+static NSString * const WebSubframeArchivesKey = @"WebSubframeArchives";
@interface WebArchivePrivate : NSObject
{
@end
+static BOOL isArrayOfClass(id object, Class elementClass)
+{
+ if (![object isKindOfClass:[NSArray class]])
+ return NO;
+ NSArray *array = (NSArray *)object;
+ NSUInteger count = [array count];
+ for (NSUInteger i = 0; i < count; ++i)
+ if (![[array objectAtIndex:i] isKindOfClass:elementClass])
+ return NO;
+ return YES;
+}
+
@implementation WebArchive
- (id)init
_private->subresources = [[WebResource _resourcesFromPropertyLists:[propertyList objectForKey:WebSubresourcesKey]] retain];
NSEnumerator *enumerator = [[propertyList objectForKey:WebSubframeArchivesKey] objectEnumerator];
- _private->subframeArchives = [[NSMutableArray alloc] init];
+ NSMutableArray *subframeArchives = [[NSMutableArray alloc] init];
NSDictionary *archivePropertyList;
while ((archivePropertyList = [enumerator nextObject]) != nil) {
WebArchive *archive = [[WebArchive alloc] _initWithPropertyList:archivePropertyList];
if (archive) {
- [(NSMutableArray *)_private->subframeArchives addObject:archive];
+ [subframeArchives addObject:archive];
[archive release];
}
}
-
+ _private->subframeArchives = subframeArchives;
+
return self;
}
self = [self init];
if (!self)
return nil;
-
- NS_DURING
- _private->mainResource = [[decoder decodeObjectForKey:WebMainResourceKey] retain];
- _private->subresources = [[decoder decodeObjectForKey:WebSubresourcesKey] retain];
- _private->subframeArchives = [[decoder decodeObjectForKey:WebSubframeArchivesKey] retain];
- NS_HANDLER
+
+ @try {
+ id object = [decoder decodeObjectForKey:WebMainResourceKey];
+ if ([object isKindOfClass:[WebResource class]])
+ _private->mainResource = [object retain];
+ object = [decoder decodeObjectForKey:WebSubresourcesKey];
+ if (isArrayOfClass(object, [WebResource class]))
+ _private->subresources = [object retain];
+ object = [decoder decodeObjectForKey:WebSubframeArchivesKey];
+ if (isArrayOfClass(object, [WebArchive class]))
+ _private->subframeArchives = [object retain];
+ } @catch(...) {
+ [self release];
+ return nil;
+ }
+
+ if (!_private->mainResource) {
[self release];
return nil;
- NS_ENDHANDLER
+ }
+
return self;
}
/*
- * Copyright (C) 2005 Apple Computer, Inc. All rights reserved.
+ * Copyright (C) 2005, 2006, 2007 Apple Inc. All rights reserved.
* (C) 2006 Graham Dennis (graham.dennis@gmail.com)
*
* Redistribution and use in source and binary forms, with or without
- (id)initWithCoder:(NSCoder *)decoder
{
- volatile id result = nil;
-
-NS_DURING
-
- int version;
+ self = [super init];
+ if (!self)
+ return nil;
_private = [[WebPreferencesPrivate alloc] init];
_private->IBCreatorID = [[WebPreferences _IBCreatorID] retain];
_private->automaticallyDetectsCacheModel = YES;
-
- if ([decoder allowsKeyedCoding]){
- _private->identifier = [[decoder decodeObjectForKey:@"Identifier"] retain];
- _private->values = [[decoder decodeObjectForKey:@"Values"] retain];
- LOG (Encoding, "Identifier = %@, Values = %@\n", _private->identifier, _private->values);
- }
- else {
- [decoder decodeValueOfObjCType:@encode(int) at:&version];
- if (version == 1){
- _private->identifier = [[decoder decodeObject] retain];
- _private->values = [[decoder decodeObject] retain];
+
+ @try {
+ id identifier = nil;
+ id values = nil;
+ if ([decoder allowsKeyedCoding]) {
+ identifier = [decoder decodeObjectForKey:@"Identifier"];
+ values = [decoder decodeObjectForKey:@"Values"];
+ } else {
+ int version;
+ [decoder decodeValueOfObjCType:@encode(int) at:&version];
+ if (version == 1) {
+ identifier = [decoder decodeObject];
+ values = [decoder decodeObject];
+ }
}
+
+ if ([identifier isKindOfClass:[NSString class]])
+ _private->identifier = [identifier copy];
+ if ([values isKindOfClass:[NSDictionary class]])
+ _private->values = [values mutableCopy]; // ensure dictionary is mutable
+
+ LOG(Encoding, "Identifier = %@, Values = %@\n", _private->identifier, _private->values);
+ } @catch(...) {
+ [self release];
+ return nil;
}
-
+
// If we load a nib multiple times, or have instances in multiple
// nibs with the same name, the first guy up wins.
WebPreferences *instance = [[self class] _getInstanceForIdentifier:_private->identifier];
- if (instance){
+ if (instance) {
[self release];
- result = [instance retain];
- }
- else {
+ self = [instance retain];
+ } else {
[[self class] _setInstance:self forIdentifier:_private->identifier];
- result = self;
}
-
-NS_HANDLER
- result = nil;
- [self release];
-
-NS_ENDHANDLER
-
- return result;
+ return self;
}
- (void)encodeWithCoder:(NSCoder *)encoder
/*
- * Copyright (C) 2005 Apple Computer, Inc. All rights reserved.
+ * Copyright (C) 2005, 2006, 2007 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#import <WebKit/WebFrameBridge.h>
-#import <WebKit/WebResourcePrivate.h>
-#import <WebKit/WebNSDictionaryExtras.h>
-#import <WebKit/WebNSURLExtras.h>
+#import "WebResourcePrivate.h"
-NSString *WebResourceDataKey = @"WebResourceData";
-NSString *WebResourceFrameNameKey = @"WebResourceFrameName";
-NSString *WebResourceMIMETypeKey = @"WebResourceMIMEType";
-NSString *WebResourceURLKey = @"WebResourceURL";
-NSString *WebResourceTextEncodingNameKey = @"WebResourceTextEncodingName";
-NSString *WebResourceResponseKey = @"WebResourceResponse";
+#import "WebFrameBridge.h"
+#import "WebNSDictionaryExtras.h"
+#import "WebNSURLExtras.h"
+
+static NSString * const WebResourceDataKey = @"WebResourceData";
+static NSString * const WebResourceFrameNameKey = @"WebResourceFrameName";
+static NSString * const WebResourceMIMETypeKey = @"WebResourceMIMEType";
+static NSString * const WebResourceURLKey = @"WebResourceURL";
+static NSString * const WebResourceTextEncodingNameKey = @"WebResourceTextEncodingName";
+static NSString * const WebResourceResponseKey = @"WebResourceResponse";
#define WebResourceVersion 1
if (!self)
return nil;
- NS_DURING
- _private->data = [[decoder decodeObjectForKey:WebResourceDataKey] retain];
- _private->URL = [[decoder decodeObjectForKey:WebResourceURLKey] retain];
- _private->MIMEType = [[decoder decodeObjectForKey:WebResourceMIMETypeKey] retain];
- _private->textEncodingName = [[decoder decodeObjectForKey:WebResourceTextEncodingNameKey] retain];
- _private->frameName = [[decoder decodeObjectForKey:WebResourceFrameNameKey] retain];
- _private->response = [[decoder decodeObjectForKey:WebResourceResponseKey] retain];
- NS_HANDLER
+ @try {
+ id object = [decoder decodeObjectForKey:WebResourceDataKey];
+ if ([object isKindOfClass:[NSData class]])
+ _private->data = [object retain];
+ object = [decoder decodeObjectForKey:WebResourceURLKey];
+ if ([object isKindOfClass:[NSURL class]])
+ _private->URL = [object retain];
+ object = [decoder decodeObjectForKey:WebResourceMIMETypeKey];
+ if ([object isKindOfClass:[NSString class]])
+ _private->MIMEType = [object retain];
+ object = [decoder decodeObjectForKey:WebResourceTextEncodingNameKey];
+ if ([object isKindOfClass:[NSString class]])
+ _private->textEncodingName = [object retain];
+ object = [decoder decodeObjectForKey:WebResourceFrameNameKey];
+ if ([object isKindOfClass:[NSString class]])
+ _private->frameName = [object retain];
+ object = [decoder decodeObjectForKey:WebResourceResponseKey];
+ if ([object isKindOfClass:[NSURLResponse class]])
+ _private->response = [object retain];
+ } @catch(...) {
[self release];
return nil;
- NS_ENDHANDLER
+ }
+
return self;
}
NSData *responseData = [propertyList objectForKey:WebResourceResponseKey];
if ([responseData isKindOfClass:[NSData class]]) {
NSKeyedUnarchiver *unarchiver = [[NSKeyedUnarchiver alloc] initForReadingWithData:responseData];
- response = [unarchiver decodeObjectForKey:WebResourceResponseKey];
- [unarchiver finishDecoding];
- [unarchiver release];
+ @try {
+ id responseObject = [unarchiver decodeObjectForKey:WebResourceResponseKey];
+ if ([responseObject isKindOfClass:[NSURLResponse class]])
+ response = responseObject;
+ [unarchiver finishDecoding];
+ } @catch(...) {
+ response = nil;
+ }
+ [unarchiver release];
}
NSData *data = [propertyList objectForKey:WebResourceDataKey];