severity 375518 grave
tags 375518 + confirmed patch
thanks

"Index 0 is out of range 0 (in 'objectAtIndex:')" is raised in
localLibrary (functions.m:45) because the NSArray, returned by
NSSearchPathForDirectoriesInDomains, is empty.

It is completely valid for NSSearchPathForDirectoriesInDomains to
return an empty array, so the caller must not assume that a non-empty
array is returned and must check the size of the array before calling
objectAtIndex.

Since the same problem is shared among all calls to
NSSearchPathForDirectoriesInDomains in functions.m, it is suitable to
define a safer wrapper function (named firstPathWithComponent) which
takes the combined arguments of NSSearchPathForDirectoriesInDomains
and stringByAppendingPathComponent and makes the apropriate checks
before calling objectAtIndex and stringByAppendingPathComponent.
Then, we just use it instead direct calls to
NSSearchPathForDirectoriesInDomains.

The proposed patch is attached.
diff -ur c2/cenon.app-3.81/functions.h cenon.app-3.81/functions.h
--- c2/cenon.app-3.81/functions.h       2006-03-26 22:09:11.000000000 +0300
+++ cenon.app-3.81/functions.h  2006-11-03 15:46:02.000000000 +0200
@@ -38,6 +38,10 @@
     UNIT_POINT = 2     // 1/72 inch    // x 1
 } CenonUnit;
 
+NSString *firstPathWithComponent(NSSearchPathDirectory directoryKey,
+                                                                
NSSearchPathDomainMask domainMask,
+                                                                BOOL 
expandTilde,
+                                                                NSString* 
pathComponent);
 NSString *localLibrary(void);
 NSString *userLibrary(void);
 NSString *localBundlePath(void);
diff -ur c2/cenon.app-3.81/functions.m cenon.app-3.81/functions.m
--- c2/cenon.app-3.81/functions.m       2006-03-26 22:09:11.000000000 +0300
+++ cenon.app-3.81/functions.m  2006-11-03 15:42:24.000000000 +0200
@@ -33,6 +33,17 @@
 #include "functions.h"
 #include "locations.h"
 
+NSString *firstPathWithComponent(NSSearchPathDirectory directoryKey,
+                                                                
NSSearchPathDomainMask domainMask,
+                                                                BOOL 
expandTilde,
+                                                                NSString* 
pathComponent)
+{
+    NSArray                    *path;
+       path = NSSearchPathForDirectoriesInDomains(directoryKey, domainMask, 
expandTilde);
+       if ([path count] == 0) return nil;
+       return [[path objectAtIndex:0] 
stringByAppendingPathComponent:pathComponent];
+}
+
 /* return library paths
  */
 NSString *localLibrary(void)
@@ -42,12 +53,10 @@
     NSString           *lPath, *sPath;
 
     /* we return the local path or the system path, whichever exists - local 
has priority */
-    lPath = [[NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, 
NSLocalDomainMask, YES) objectAtIndex:0]
-             stringByAppendingPathComponent:APPNAME];
+       lPath = firstPathWithComponent(NSLibraryDirectory, NSLocalDomainMask, 
YES, APPNAME);
     if ( lPath && [fileManager fileExistsAtPath:lPath] )
         return lPath;
-    sPath = [[NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, 
NSSystemDomainMask, YES) objectAtIndex:0]
-             stringByAppendingPathComponent:APPNAME];
+       sPath = firstPathWithComponent(NSLibraryDirectory, NSSystemDomainMask, 
YES, APPNAME);
     if ( sPath && [fileManager fileExistsAtPath:sPath] )
         return sPath;
     return lPath;
@@ -58,8 +67,7 @@
 NSString *userLibrary(void)
 {
 #if defined(GNUSTEP_BASE_VERSION) || defined(__APPLE__)
-    return [[NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, 
NSUserDomainMask, YES) objectAtIndex:0]
-            stringByAppendingPathComponent:APPNAME];
+    return firstPathWithComponent(NSLibraryDirectory, NSUserDomainMask, YES, 
APPNAME);
 #else
     return vhfPathWithPathComponents(NSHomeDirectory(), HOMELIBRARY, nil);
 #endif
@@ -68,8 +76,7 @@
 NSString *localBundlePath(void)
 {
 #if defined(GNUSTEP_BASE_VERSION) || defined(__APPLE__)
-    return [[NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, 
NSLocalDomainMask, YES) objectAtIndex:0]
-            stringByAppendingPathComponent:BUNDLEFOLDER];
+    return firstPathWithComponent(NSLibraryDirectory, NSLocalDomainMask, YES, 
BUNDLEFOLDER);
 #else
     return vhfPathWithPathComponents(@"/LocalLibrary", BUNDLEFOLDER, nil);
 #endif
@@ -77,8 +84,7 @@
 NSString *systemBundlePath(void)
 {
 #if defined(GNUSTEP_BASE_VERSION) || defined(__APPLE__)
-    return [[NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, 
NSSystemDomainMask, YES) objectAtIndex:0]
-            stringByAppendingPathComponent:BUNDLEFOLDER];
+    return firstPathWithComponent(NSLibraryDirectory, NSSystemDomainMask, YES, 
BUNDLEFOLDER);
 #else  // OpenStep
     return vhfPathWithPathComponents(@"/NextLibrary", BUNDLEFOLDER, nil);
 #endif
@@ -86,8 +92,7 @@
 NSString *userBundlePath(void)
 {
 #if defined(GNUSTEP_BASE_VERSION) || defined(__APPLE__)
-    return [[NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, 
NSUserDomainMask, YES) objectAtIndex:0]
-            stringByAppendingPathComponent:BUNDLEFOLDER];
+    return firstPathWithComponent(NSLibraryDirectory, NSUserDomainMask, YES, 
BUNDLEFOLDER);
 #else
     return vhfPathWithPathComponents(NSHomeDirectory(), @"Library", 
BUNDLEFOLDER, nil);
 #endif

-- 
Protect your digital freedom and privacy, eliminate DRM, learn more at
http://www.defectivebydesign.org/what_is_drm

Reply via email to