From a24b7a4b5220b1cd3f3b5da2f6eddec692aff1a8 Mon Sep 17 00:00:00 2001 From: rfm Date: Sat, 6 Jul 2013 05:27:59 +0000 Subject: [PATCH] memory management fix git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@36842 72102866-910b-0410-8b05-ffd578937521 --- ChangeLog | 5 ++++ Source/cifframe.m | 70 +++++++++++++++++++++++++++++++++-------------- 2 files changed, 55 insertions(+), 20 deletions(-) diff --git a/ChangeLog b/ChangeLog index edecebca9..40e267b95 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2013-07-06 Richard Frith-Macdonald + + * Source/cifframe.m: Fix possible incorrect free of non-malloc'ed + memory. + 2013-07-05 Richard Frith-Macdonald * Source/NSObject.m: Fix error creating instasnce when using the diff --git a/Source/cifframe.m b/Source/cifframe.m index 11c3a48aa..5aac4bb26 100644 --- a/Source/cifframe.m +++ b/Source/cifframe.m @@ -259,8 +259,12 @@ cifframe_arg_addr(cifframe_t *cframe, int index) ffi_type * cifframe_type(const char *typePtr, const char **advance) { + static ffi_type stypeNSPoint = { 0 }; + static ffi_type stypeNSRange = { 0 }; + static ffi_type stypeNSRect = { 0 }; + static ffi_type stypeNSSize = { 0 }; const char *type; - ffi_type *ftype; + ffi_type *ftype = 0; typePtr = objc_skip_type_qualifiers (typePtr); type = typePtr; @@ -353,9 +357,9 @@ cifframe_type(const char *typePtr, const char **advance) if (GSSelectorTypesMatch(typePtr - 1, @encode(NSRange))) { static ffi_type *elems[3]; - static ffi_type stype = { 0 }; + static ffi_type *ftype = &stypeNSRange; - if (stype.type == 0) + if (ftype->type == 0) { const char *t = @encode(NSUInteger); @@ -375,19 +379,18 @@ cifframe_type(const char *typePtr, const char **advance) } elems[1] = elems[0]; elems[2] = 0; - stype.elements = elems; - stype.type = FFI_TYPE_STRUCT; + ftype->elements = elems; + ftype->type = FFI_TYPE_STRUCT; } - ftype = &stype; typePtr = objc_skip_typespec (typePtr - 1); break; } - else if (GSSelectorTypesMatch(typePtr - 1, @encode(NSSize))) + else if (GSSelectorTypesMatch(typePtr - 1, @encode(NSPoint))) { static ffi_type *elems[3]; - static ffi_type stype = { 0 }; + static ffi_type *ftype = &stypeNSPoint; - if (stype.type == 0) + if (ftype->type == 0) { if (*@encode(CGFloat) == _C_DBL) { @@ -399,30 +402,51 @@ cifframe_type(const char *typePtr, const char **advance) } elems[1] = elems[0]; elems[2] = 0; - stype.elements = elems; - stype.type = FFI_TYPE_STRUCT; + ftype->elements = elems; + ftype->type = FFI_TYPE_STRUCT; + } + typePtr = objc_skip_typespec (typePtr - 1); + break; + } + else if (GSSelectorTypesMatch(typePtr - 1, @encode(NSSize))) + { + static ffi_type *elems[3]; + static ffi_type *ftype = &stypeNSSize; + + if (ftype->type == 0) + { + if (*@encode(CGFloat) == _C_DBL) + { + elems[0] = &ffi_type_double; + } + else + { + elems[0] = &ffi_type_float; + } + elems[1] = elems[0]; + elems[2] = 0; + ftype->elements = elems; + ftype->type = FFI_TYPE_STRUCT; } - ftype = &stype; typePtr = objc_skip_typespec (typePtr - 1); break; } else if (GSSelectorTypesMatch(typePtr - 1, @encode(NSRect))) { static ffi_type *elems[3]; - static ffi_type stype = { 0 }; + static ffi_type *ftype = &stypeNSRect; - if (stype.type == 0) + if (ftype->type == 0) { /* An NSRect is an NSPoint and an NSSize, but those * two structures are actually identical. */ elems[0] = cifframe_type(@encode(NSSize), NULL); - elems[1] = elems[0]; + elems[1] = cifframe_type(@encode(NSPoint), NULL); elems[2] = 0; - stype.elements = elems; - stype.type = FFI_TYPE_STRUCT; + ftype->elements = elems; + ftype->type = FFI_TYPE_STRUCT; } - ftype = &stype; typePtr = objc_skip_typespec (typePtr - 1); break; } @@ -497,8 +521,14 @@ cifframe_type(const char *typePtr, const char **advance) NSCAssert(typePtr, @"End of signature while parsing"); if (align > max_align) { - if (ftype && ftype->type == FFI_TYPE_STRUCT) - free(ftype); + if (ftype && ftype->type == FFI_TYPE_STRUCT + && ftype != &stypeNSPoint + && ftype != &stypeNSRange + && ftype != &stypeNSRect + && ftype != &stypeNSSize) + { + free(ftype); + } ftype = local; max_align = align; }