summaryrefslogtreecommitdiffstats
path: root/crypto/stack/stack.c
diff options
context:
space:
mode:
authorGeoff Thorpe <geoff@openssl.org>2000-06-01 02:15:40 +0000
committerGeoff Thorpe <geoff@openssl.org>2000-06-01 02:15:40 +0000
commit7bb7043580900b8f06cb418b46004b755ff0fc96 (patch)
tree2c7daae78031c2b18e2ecd27473b57f8a3bef121 /crypto/stack/stack.c
parentf3e9b338e0badedc87f6014bdbb8594e5af00acd (diff)
This is the first of two commits (didn't want to dump them all into the
same one). However, the first will temporarily break things until the second comes through. :-) The safestack.h handling was mapping compare callbacks that externally are of the type (int (*)(type **,type **)) into the underlying callback type used by stack.[ch], which is (int (*)(void *,void *)). After some degree of digging, it appears that the callback type in the underlying stack code should use double pointers too - when the compare operations are invoked (from sk_find and sk_sort), they are being used by bsearch and qsort to compare two pointers to pointers. This change corrects the prototyping (by only casting to the (void*,void*) form at the moment it is needed by bsearch and qsort) and makes the mapping in safestack.h more transparent. It also changes from "void*" to "char*" to stay in keeping with stack.[ch]'s assumed base type of "char". Also - the "const" situation was that safestack.h was throwing away "const"s, and to compound the problem - a close examination of stack.c showed that (const char **) is not really achieving what it is supposed to when the callback is being invoked, what is needed is (const char * const *). So the underlying stack.[ch] and the mapping macros in safestack.h have all been altered to correct this. What will follow are the vast quantities of "const" corrections required in stack-dependant code that was being let "slip" through when safestack.h was discarding "const"s. These now all come up as compiler warnings.
Diffstat (limited to 'crypto/stack/stack.c')
-rw-r--r--crypto/stack/stack.c29
1 files changed, 23 insertions, 6 deletions
diff --git a/crypto/stack/stack.c b/crypto/stack/stack.c
index be132d5dea..8f57daa6f4 100644
--- a/crypto/stack/stack.c
+++ b/crypto/stack/stack.c
@@ -76,9 +76,10 @@ const char *STACK_version="Stack" OPENSSL_VERSION_PTEXT;
#include <errno.h>
-int (*sk_set_cmp_func(STACK *sk, int (*c)(const void *,const void *)))(const void *, const void *)
+int (*sk_set_cmp_func(STACK *sk, int (*c)(const char * const *,const char * const *)))
+ (const char * const *, const char * const *)
{
- int (*old)(const void *,const void *)=sk->comp;
+ int (*old)(const char * const *,const char * const *)=sk->comp;
if (sk->comp != c)
sk->sorted=0;
@@ -108,7 +109,7 @@ err:
return(NULL);
}
-STACK *sk_new(int (*c)(const void *, const void *))
+STACK *sk_new(int (*c)(const char * const *, const char * const *))
{
STACK *ret;
int i;
@@ -218,13 +219,24 @@ int sk_find(STACK *st, char *data)
}
sk_sort(st);
if (data == NULL) return(-1);
- comp_func=st->comp;
+ /* This (and the "qsort" below) are the two places in OpenSSL
+ * where we need to convert from our standard (type **,type **)
+ * compare callback type to the (void *,void *) type required by
+ * bsearch. However, the "data" it is being called(back) with are
+ * not (type *) pointers, but the *pointers* to (type *) pointers,
+ * so we get our extra level of pointer dereferencing that way. */
+ comp_func=(int (*)(const void *,const void *))(st->comp);
r=(char **)bsearch(&data,(char *)st->data,
st->num,sizeof(char *), comp_func);
if (r == NULL) return(-1);
i=(int)(r-st->data);
for ( ; i>0; i--)
- if ((*st->comp)(&(st->data[i-1]),&data) < 0)
+ /* This needs a cast because the type being pointed to from
+ * the "&" expressions are (char *) rather than (const char *).
+ * For an explanation, read:
+ * http://www.eskimo.com/~scs/C-faq/q11.10.html :-) */
+ if ((*st->comp)((const char * const *)&(st->data[i-1]),
+ (const char * const *)&data) < 0)
break;
return(i);
}
@@ -303,7 +315,12 @@ void sk_sort(STACK *st)
{
int (*comp_func)(const void *,const void *);
- comp_func=st->comp;
+ /* same comment as in sk_find ... previously st->comp was declared
+ * as a (void*,void*) callback type, but this made the population
+ * of the callback pointer illogical - our callbacks compare
+ * type** with type**, so we leave the casting until absolutely
+ * necessary (ie. "now"). */
+ comp_func=(int (*)(const void *,const void *))(st->comp);
qsort(st->data,st->num,sizeof(char *), comp_func);
st->sorted=1;
}