Fix bug in protocol_copyMethodDescriptionList() where we were calling calloc()

with a wrong element size.
main
thebeing 14 years ago
parent e7ab10611f
commit 1684283af0

@ -11,7 +11,7 @@
// Get the functions for string hashing // Get the functions for string hashing
#include "string_hash.h" #include "string_hash.h"
static int protocol_compare(const char *name, static int protocol_compare(const char *name,
const struct objc_protocol2 *protocol) const struct objc_protocol2 *protocol)
{ {
return string_compare(name, protocol->name); return string_compare(name, protocol->name);
@ -31,7 +31,7 @@ static protocol_table *known_protocol_table;
void init_protocol_table(void) void init_protocol_table(void)
{ {
protocol_initialize(&known_protocol_table, 128); protocol_initialize(&known_protocol_table, 128);
} }
static void protocol_table_insert(const struct objc_protocol2 *protocol) static void protocol_table_insert(const struct objc_protocol2 *protocol)
{ {
@ -47,10 +47,10 @@ static id ObjC2ProtocolClass = 0;
static int isEmptyProtocol(struct objc_protocol2 *aProto) static int isEmptyProtocol(struct objc_protocol2 *aProto)
{ {
int isEmpty = int isEmpty =
((aProto->instance_methods == NULL) || ((aProto->instance_methods == NULL) ||
(aProto->instance_methods->count == 0)) && (aProto->instance_methods->count == 0)) &&
((aProto->class_methods == NULL) || ((aProto->class_methods == NULL) ||
(aProto->class_methods->count == 0)) && (aProto->class_methods->count == 0)) &&
((aProto->protocol_list == NULL) || ((aProto->protocol_list == NULL) ||
(aProto->protocol_list->count == 0)); (aProto->protocol_list->count == 0));
@ -67,7 +67,7 @@ static int isEmptyProtocol(struct objc_protocol2 *aProto)
// FIXME: Make p1 adopt all of the stuff in p2 // FIXME: Make p1 adopt all of the stuff in p2
static void makeProtocolEqualToProtocol(struct objc_protocol2 *p1, static void makeProtocolEqualToProtocol(struct objc_protocol2 *p1,
struct objc_protocol2 *p2) struct objc_protocol2 *p2)
{ {
#define COPY(x) p1->x = p2->x #define COPY(x) p1->x = p2->x
COPY(instance_methods); COPY(instance_methods);
@ -90,7 +90,7 @@ static struct objc_protocol2 *unique_protocol(struct objc_protocol2 *aProto)
{ {
ObjC2ProtocolClass = objc_getClass("Protocol2"); ObjC2ProtocolClass = objc_getClass("Protocol2");
} }
struct objc_protocol2 *oldProtocol = struct objc_protocol2 *oldProtocol =
protocol_for_name(aProto->name); protocol_for_name(aProto->name);
if (NULL == oldProtocol) if (NULL == oldProtocol)
{ {
@ -166,7 +166,7 @@ static BOOL init_protocols(struct objc_protocol_list *protocols)
// Protocols in the protocol list have their class pointers set to the // Protocols in the protocol list have their class pointers set to the
// version of the protocol class that they expect. // version of the protocol class that they expect.
enum protocol_version version = enum protocol_version version =
(enum protocol_version)(uintptr_t)aProto->isa; (enum protocol_version)(uintptr_t)aProto->isa;
switch (version) switch (version)
{ {
@ -309,17 +309,16 @@ get_method_list(Protocol *p,
struct objc_method_description *protocol_copyMethodDescriptionList(Protocol *p, struct objc_method_description *protocol_copyMethodDescriptionList(Protocol *p,
BOOL isRequiredMethod, BOOL isInstanceMethod, unsigned int *count) BOOL isRequiredMethod, BOOL isInstanceMethod, unsigned int *count)
{ {
if (NULL == p) { return NULL; } if ((NULL == p) || (NULL == count)){ return NULL; }
struct objc_method_description_list *list = struct objc_method_description_list *list =
get_method_list(p, isRequiredMethod, isInstanceMethod); get_method_list(p, isRequiredMethod, isInstanceMethod);
*count = 0; *count = 0;
if (NULL == list || list->count == 0) { return NULL; } if (NULL == list || list->count == 0) { return NULL; }
*count = list->count; *count = list->count;
struct objc_method_description *out = struct objc_method_description *out =
calloc(sizeof(struct objc_method_description_list), list->count); calloc(sizeof(struct objc_method_description), list->count);
for (int i=0 ; i < (list->count) ; i++)
for (int i=0 ; i<list->count ; i++)
{ {
out[i].name = sel_registerTypedName_np(list->methods[i].name, out[i].name = sel_registerTypedName_np(list->methods[i].name,
list->methods[i].types); list->methods[i].types);
@ -403,7 +402,7 @@ objc_property_t protocol_getProperty(Protocol *protocol,
return NULL; return NULL;
} }
Protocol2 *p = (Protocol2*)protocol; Protocol2 *p = (Protocol2*)protocol;
struct objc_property_list *properties = struct objc_property_list *properties =
isRequiredProperty ? p->properties : p->optional_properties; isRequiredProperty ? p->properties : p->optional_properties;
while (NULL != properties) while (NULL != properties)
{ {
@ -421,20 +420,20 @@ objc_property_t protocol_getProperty(Protocol *protocol,
} }
struct objc_method_description struct objc_method_description
protocol_getMethodDescription(Protocol *p, protocol_getMethodDescription(Protocol *p,
SEL aSel, SEL aSel,
BOOL isRequiredMethod, BOOL isRequiredMethod,
BOOL isInstanceMethod) BOOL isInstanceMethod)
{ {
struct objc_method_description d = {0,0}; struct objc_method_description d = {0,0};
struct objc_method_description_list *list = struct objc_method_description_list *list =
get_method_list(p, isRequiredMethod, isInstanceMethod); get_method_list(p, isRequiredMethod, isInstanceMethod);
if (NULL == list) if (NULL == list)
{ {
return d; return d;
} }
// TODO: We could make this much more efficient if // TODO: We could make this much more efficient if
for (int i=0 ; i<list->count ; i++) for (int i=0 ; i<list->count ; i++)
{ {
SEL s = sel_registerTypedName_np(list->methods[i].name, 0); SEL s = sel_registerTypedName_np(list->methods[i].name, 0);
@ -464,7 +463,7 @@ BOOL protocol_isEqual(Protocol *p, Protocol *other)
{ {
return NO; return NO;
} }
if (p == other || if (p == other ||
p->name == other->name || p->name == other->name ||
0 == strcmp(p->name, other->name)) 0 == strcmp(p->name, other->name))
{ {

Loading…
Cancel
Save