Patchwork libobjc: Fix sel_registerName and similar when passed a NULL argument

login
register
mail settings
Submitter Nicola Pero
Date Dec. 24, 2010, 8:11 p.m.
Message ID <D450C432-028D-4EC0-8AE1-AEAE4C360ED6@meta-innovation.com>
Download mbox | patch
Permalink /patch/76637/
State New
Headers show

Comments

Nicola Pero - Dec. 24, 2010, 8:11 p.m.
This patch fixes sel_registerName, sel_registerTypedName and  
sel_getTypedSelector to detect a NULL
argument and return NULL for it.

It also updates one test (gnu-api-2-sel) to be executed with the Apple  
runtime as well.  The logic is the
one outlined in my previous email --

 > The purpose wouldn't be to test the Apple runtime; it would
 > rather be to test that the testcase are correct and that the  
behaviour they require
 > from the runtime API is indeed the one of the Apple runtime.  Then,  
if someone makes
 > a change to the GNU runtime API making it incompatible with the  
Apple one, and adds
 > a testcase for it (assuming all changes come with a testcase), they  
would notice
 > when the test runs on the Apple runtime, as it would fail there.

I'll be updating the other tests (probably tomorrow) as well.

Committed to trunk

Thanks

    std::cout << "Testing sel_isEqual () ...\n";
@@ -145,8 +155,12 @@
    {
      if (std::strcmp (sel_getName (sel_registerName ("myMethod")),  
"myMethod") != 0)
        abort ();
+
+    if (sel_registerName (NULL) != NULL)
+      abort ();
    }

+#ifdef __GNU_LIBOBJC__
    std::cout << "Testing set_registerTypedName () ...\n";
    {
      const char *types = method_getTypeEncoding  
(class_getInstanceMethod
@@ -159,7 +173,14 @@

      if (std::strcmp (sel_getTypeEncoding (selector), types) != 0)
        abort ();
+
+    if (sel_registerTypedName (NULL, NULL) != NULL)
+      abort ();
+
+    if (sel_registerTypedName (NULL, types) != NULL)
+      abort ();
    }
+#endif

    return (0);
  }

Patch

Index: selector.c
===================================================================
--- selector.c  (revision 168229)
+++ selector.c  (working copy)
@@ -357,8 +357,12 @@ 
  sel_getTypedSelector (const char *name)
  {
    sidx i;
+
+  if (name == NULL)
+    return NULL;
+
    objc_mutex_lock (__objc_runtime_mutex);
-
+
    /* Look for a typed selector.  */
    i = (sidx) objc_hash_value_for_key (__objc_selector_hash, name);
    if (i != 0)
@@ -658,6 +662,9 @@ 
  sel_registerName (const char *name)
  {
    SEL ret;
+
+  if (name == NULL)
+    return NULL;

    objc_mutex_lock (__objc_runtime_mutex);
    /* Assume that name is not constant static memory and needs to be
@@ -680,6 +687,9 @@ 
  {
    SEL ret;

+  if (name == NULL)
+    return NULL;
+
    objc_mutex_lock (__objc_runtime_mutex);
    /* Assume that name and type are not constant static memory and need
       to be copied before put into a runtime structure.  is_const ==
Index: ChangeLog
===================================================================
--- ChangeLog   (revision 168230)
+++ ChangeLog   (working copy)
@@ -1,5 +1,13 @@ 
  2010-12-24  Nicola Pero  <nicola.pero@meta-innovation.com>

+       * selector.c (sel_getTypedSelector): Return NULL if given a NULL
+       argument.
+       (sel_registerTypedName): Same.
+       (sel_registerName): Same.
+       * objc/runtime.h: Updated documentation.
+
+2010-12-24  Nicola Pero  <nicola.pero@meta-innovation.com>
+
         * objc/runtime.h (class_addIvar): Updated documentation.  The
         alignment is actually the log_2 of the alignment in bytes.
         * ivars.c (class_addIvar): Corresponding change to the
Index: objc/runtime.h
===================================================================
--- objc/runtime.h      (revision 168230)
+++ objc/runtime.h      (working copy)
@@ -191,14 +191,14 @@ 
     you know the types, it is better to call sel_registerTypedName().
     If a selector with this name and no types already exists, it is
     returned.  Note that this function should really be called
-   'objc_registerSelector'.  */
+   'objc_registerSelector'.  Return NULL if 'name' is NULL.  */
  objc_EXPORT SEL sel_registerName (const char *name);

  /* Register a selector with a given name and types.  If a selector
     with this name and types already exists, it is returned.  Note that
     this function should really be called 'objc_registerTypedSelector',
     and it's called 'sel_registerTypedName' only for consistency with
-   'sel_registerName'.
+   'sel_registerName'.  Return NULL if 'name' is NULL.

     Compatibility Note: the Apple/NeXT runtime has untyped selectors,
     so it does not have this function, which is specific to the GNU
@@ -227,7 +227,7 @@ 

  /* Return a selector with name 'name' and a non-zero type encoding, if
     any such selector is registered with the runtime.  If there is no
-   such selector, NULL is returned.
+   such selector, NULL is returned.  Return NULL if 'name' is NULL.

     This is useful if you have the name of the selector, and would
     really like to get a selector for it that includes the type
Index: ChangeLog
===================================================================
--- ChangeLog   (revision 168230)
+++ ChangeLog   (working copy)
@@ -1,5 +1,12 @@ 
  2010-12-24  Nicola Pero  <nicola.pero@meta-innovation.com>

+       * objc.dg/gnu-api-2-sel.m: Test calling sel_getUid,
+       sel_registerName and sel_registerTypedName with NULL arguments.
+       Updated the test to work with the Apple runtime as well.
+       * obj-c++.dg/gnu-api-2-sel.mm: Same change.
+
+2010-12-24  Nicola Pero  <nicola.pero@meta-innovation.com>
+
         * objc.dg/gnu-api-2-class.m: Updated test to pass log_2 of the
         alignment to class_addIvar, instead of the alignment itself.
         * obj-c++.dg/gnu-api-2-class.mm: Same change.
Index: objc.dg/gnu-api-2-sel.m
===================================================================
--- objc.dg/gnu-api-2-sel.m     (revision 168229)
+++ objc.dg/gnu-api-2-sel.m     (working copy)
@@ -3,7 +3,6 @@ 
    This is test 'sel', covering all functions starting with 'sel'.  */

  /* { dg-do run } */
-/* { dg-skip-if "" { *-*-* } { "-fnext-runtime" } { "" } } */

  /* To get the modern GNU Objective-C Runtime API, you include
     objc/runtime.h.  */
@@ -16,11 +15,13 @@ 
  { Class isa; }
  + alloc;
  - init;
++ initialize;
  @end

  @implementation MyRootClass
  + alloc { return class_createInstance (self, 0); }
  - init  { return self; }
++ initialize { return self; }
  @end

  @protocol MyProtocol
@@ -49,6 +50,7 @@ 
  {
    /* Functions are tested in alphabetical order.  */

+#ifdef __GNU_LIBOBJC__
    printf ("Testing sel_copyTypedSelectorList ()...\n");
    {
      unsigned int count;
@@ -72,6 +74,7 @@ 
      if (list[2] != NULL)
        abort ();
    }
+#endif

    printf ("Testing sel_getName () ...\n");
    {
@@ -82,6 +85,7 @@ 
        abort ();
    }

+#ifdef __GNU_LIBOBJC__
    printf ("Testing sel_getTypeEncoding () ...\n");
    {
      /* Get a selector from a real class, so it has interesting
@@ -96,7 +100,9 @@ 
      if (sel_getTypeEncoding (NULL) != NULL)
        abort ();
    }
+#endif

+#ifdef __GNU_LIBOBJC__
    printf ("Testing sel_getTypedSelector () ...\n");
    {
      /* First try with a selector where we know that a typed one has
@@ -128,11 +134,15 @@ 
      if (selector != NULL)
        abort ();
    }
+#endif

    printf ("Testing sel_getUid () ...\n");
    {
      if (strcmp (sel_getName (sel_getUid ("myMethod")), "myMethod") ! 
= 0)
        abort ();
+
+    if (sel_getUid (NULL) != NULL)
+      abort ();
    }

    printf ("Testing sel_isEqual () ...\n");
@@ -145,8 +155,12 @@ 
    {
      if (strcmp (sel_getName (sel_registerName ("myMethod")),  
"myMethod") != 0)
        abort ();
+
+    if (sel_registerName (NULL) != NULL)
+      abort ();
    }

+#ifdef __GNU_LIBOBJC__
    printf ("Testing set_registerTypedName () ...\n");
    {
      const char *types = method_getTypeEncoding  
(class_getInstanceMethod
@@ -159,7 +173,14 @@ 

      if (strcmp (sel_getTypeEncoding (selector), types) != 0)
        abort ();
+
+    if (sel_registerTypedName (NULL, NULL) != NULL)
+      abort ();
+
+    if (sel_registerTypedName (NULL, types) != NULL)
+      abort ();
    }
+#endif

    return 0;
  }
Index: obj-c++.dg/gnu-api-2-sel.mm
===================================================================
--- obj-c++.dg/gnu-api-2-sel.mm (revision 168229)
+++ obj-c++.dg/gnu-api-2-sel.mm (working copy)
@@ -3,7 +3,6 @@ 
    This is test 'sel', covering all functions starting with 'sel'.  */

  /* { dg-do run } */
-/* { dg-skip-if "" { *-*-* } { "-fnext-runtime" } { "" } } */

  /* To get the modern GNU Objective-C Runtime API, you include
     objc/runtime.h.  */
@@ -16,11 +15,13 @@ 
  { Class isa; }
  + alloc;
  - init;
++ initialize;
  @end

  @implementation MyRootClass
  + alloc { return class_createInstance (self, 0); }
  - init  { return self; }
++ initialize { return self; }
  @end

  @protocol MyProtocol
@@ -49,6 +50,7 @@ 
  {
    /* Functions are tested in alphabetical order.  */

+#ifdef __GNU_LIBOBJC__
    std::cout << "Testing sel_copyTypedSelectorList ()...\n";
    {
      unsigned int count;
@@ -72,6 +74,7 @@ 
      if (list[2] != NULL)
        abort ();
    }
+#endif

    std::cout << "Testing sel_getName () ...\n";
    {
@@ -82,6 +85,7 @@ 
        abort ();
    }

+#ifdef __GNU_LIBOBJC__
    std::cout << "Testing sel_getTypeEncoding () ...\n";
    {
      /* Get a selector from a real class, so it has interesting
@@ -96,7 +100,9 @@ 
      if (sel_getTypeEncoding (NULL) != NULL)
        abort ();
    }
+#endif

+#ifdef __GNU_LIBOBJC__
    std::cout << "Testing sel_getTypedSelector () ...\n";
    {
      /* First try with a selector where we know that a typed one has
@@ -128,11 +134,15 @@ 
      if (selector != NULL)
        abort ();
    }
+#endif

    std::cout << "Testing sel_getUid () ...\n";
    {
      if (std::strcmp (sel_getName (sel_getUid ("myMethod")),  
"myMethod") != 0)
        abort ();
+
+    if (sel_getUid (NULL) != NULL)
+      abort ();
    }