diff mbox

=?UTF-8?Q?Fix=20for=20PR=20libobjc/18764=20("segfault=20in=20libobjc=20w?= =?UTF-8?Q?hen=20sending=20a=20message=20to=20a=20conflicting=20class")?=

Message ID 1292971791.565414440@192.168.2.228
State New
Headers show

Commit Message

Nicola Pero Dec. 21, 2010, 10:49 p.m. UTC
This patch fixes libobjc/18764.  It detects when a module contains a class
that already exists, and in that case, rather than segfaulting, it aborts
ordinately with an explanatory error message.

Committed to trunk.

Thanks
diff mbox

Patch

Index: init.c
===================================================================
--- init.c      (revision 168133)
+++ init.c      (working copy)
@@ -879,22 +879,26 @@  void
 __objc_init_class (Class class)
 {
   /* Store the class in the class table and assign class numbers.  */
-  __objc_add_class_to_hash (class);
-  
-  /* Register all of the selectors in the class and meta class.  */
-  __objc_register_selectors_from_class (class);
-  __objc_register_selectors_from_class ((Class) class->class_pointer);
-
-  /* Install the fake dispatch tables.  */
-  __objc_install_premature_dtable (class);
-  __objc_install_premature_dtable (class->class_pointer);
-
-  /* Register the instance methods as class methods, this is only done
-     for root classes.  */
-  __objc_register_instance_methods_to_class (class);
-
-  if (class->protocols)
-    __objc_init_protocols (class->protocols);
+  if (__objc_add_class_to_hash (class))
+    {
+      /* Register all of the selectors in the class and meta class.  */
+      __objc_register_selectors_from_class (class);
+      __objc_register_selectors_from_class ((Class) class->class_pointer);
+      
+      /* Install the fake dispatch tables.  */
+      __objc_install_premature_dtable (class);
+      __objc_install_premature_dtable (class->class_pointer);
+      
+      /* Register the instance methods as class methods, this is only
+        done for root classes.  */
+      __objc_register_instance_methods_to_class (class);
+      
+      if (class->protocols)
+       __objc_init_protocols (class->protocols);
+    }
+  else
+    _objc_abort ("Module contains duplicate class '%s'\n",
+                class->name);
 }
 
 /* __objc_init_protocol must be called with __objc_runtime_mutex
Index: objc-private/runtime.h
===================================================================
--- objc-private/runtime.h      (revision 168132)
+++ objc-private/runtime.h      (working copy)
@@ -52,17 +52,17 @@  objc/runtime.h.  */
 extern "C" {
 #endif /* __cplusplus */
 
-extern void __objc_add_class_to_hash(Class);   /* (objc-class.c) */
-extern void __objc_init_class_tables(void);    /* (objc-class.c) */
-extern void __objc_init_dispatch_tables(void); /* (objc-dispatch.c) */
-extern void __objc_install_premature_dtable(Class); /* (objc-dispatch.c) */
-extern void __objc_resolve_class_links(void);  /* (objc-class.c) */
+extern BOOL __objc_add_class_to_hash (Class);   /* (objc-class.c) */
+extern void __objc_init_class_tables (void);    /* (objc-class.c) */
+extern void __objc_init_dispatch_tables (void); /* (objc-dispatch.c) */
+extern void __objc_install_premature_dtable (Class); /* (objc-dispatch.c) */
+extern void __objc_resolve_class_links (void);  /* (objc-class.c) */
 extern void __objc_update_dispatch_table_for_class (Class);/* (objc-msg.c) */
 
-extern int  __objc_init_thread_system(void);    /* thread.c */
-extern int  __objc_fini_thread_system(void);    /* thread.c */
+extern int  __objc_init_thread_system (void);    /* thread.c */
+extern int  __objc_fini_thread_system (void);    /* thread.c */
 extern void __objc_init_class (Class class);  /* init.c */
-extern void class_add_method_list(Class, struct objc_method_list *);
+extern void class_add_method_list (Class, struct objc_method_list *);
 
 /* Registering instance methods as class methods for root classes */
 extern void __objc_register_instance_methods_to_class(Class);
Index: ChangeLog
===================================================================
--- ChangeLog   (revision 168133)
+++ ChangeLog   (working copy)
@@ -1,5 +1,15 @@ 
 2010-12-21  Nicola Pero  <nicola.pero@meta-innovation.com>
 
+       PR libobjc/18764
+       * class.c (__objc_add_class_to_hash): Return YES if the class was
+       added, and NO if it already existed.
+       * init.c (__objc_init_class): If __objc_add_class_to_hash returns
+       NO, then abort the program with an error message.
+       * objc-private/runtime.h (__objc_add_class_to_hash): Updated
+       declaration.
+
+2010-12-21  Nicola Pero  <nicola.pero@meta-innovation.com>     
+
        * init.c (_objc_load_callback): Initialize with 0.
        (__objc_call_callback): Renamed to __objc_call_load_callback.
        Check _objc_load_callback only once, and if it is not set, return
Index: class.c
===================================================================
--- class.c     (revision 168132)
+++ class.c     (working copy)
@@ -446,11 +446,12 @@  __objc_init_class_tables (void)
 }  
 
 /* This function adds a class to the class hash table, and assigns the
-   class a number, unless it's already known.  */
-void
+   class a number, unless it's already known.  Return 'YES' if the
+   class was added.  Return 'NO' if the class was already known.  */
+BOOL
 __objc_add_class_to_hash (Class class)
 {
-  Class h_class;
+  Class existing_class;
 
   objc_mutex_lock (__objc_runtime_mutex);
 
@@ -461,21 +462,28 @@  __objc_add_class_to_hash (Class class)
   assert (CLS_ISCLASS (class));
 
   /* Check to see if the class is already in the hash table.  */
-  h_class = class_table_get_safe (class->name);
-  if (! h_class)
+  existing_class = class_table_get_safe (class->name);
+
+  if (existing_class)
     {
-      /* The class isn't in the hash table.  Add the class and assign a class
-         number.  */
+      objc_mutex_unlock (__objc_runtime_mutex);
+      return NO;      
+    }
+  else
+    {
+      /* The class isn't in the hash table.  Add the class and assign
+         a class number.  */
       static unsigned int class_number = 1;
-
+      
       CLS_SETNUMBER (class, class_number);
       CLS_SETNUMBER (class->class_pointer, class_number);
 
       ++class_number;
       class_table_insert (class->name, class);
+
+      objc_mutex_unlock (__objc_runtime_mutex);
+      return YES;
     }
-
-  objc_mutex_unlock (__objc_runtime_mutex);
 }
 
 Class