Feature #2145

array_get_unused_element returns correct data_type or NULL

Added by liming almost 5 years ago. Updated about 4 years ago.

Status:FixedStart date:2010-01-06
Priority:NormalDue date:
Assignee:-% Done:

100%

Category:core
Target version:1.5.0
Missing in 1.5.x:No

Description

I developped a lighty module. In this module, I mixed up data_string, data_array within one array. Lighty sometimes crashed becasuse array_get_unused_element may return a node of wrong type. The parameter t is not used at all.

Before return, it should checks the data_type.

131 data_unset *array_get_unused_element(array *a, data_type_t t) {
132 data_unset *ds = NULL;
133
134 UNUSED;
135
136 if (a->size 0) return NULL;
137
138 if (a->used a->size) return NULL;
139
140 if (a->data[a->used]) {
141 ds = a->data[a->used];
142
143 a->data[a->used] = NULL;
144 }
145
+ if (ds && ds->type != t) {
+ ds->free(ds);
+ ds = NULL;
+ }
+
151 return ds;
152 }

array.c.patch Magnifier (260 Bytes) liming, 2010-01-06 08:18

Associated revisions

Revision 2750
Added by stbuehler about 4 years ago

array.c: improve array_get_unused_element to check data type; fix mem leak if unused_element didn't find a matching entry (fixes #2145)

- the "mem leak" could only be triggered if you use different entry
types in the same array (this wasn't supported by
array_get_unused_element) or didn't call array_get_unused_element
before creating new entries.

History

#1 Updated by Tomte about 4 years ago

We solved this problem by not returning NULL if the current unused item does not have a matching type, but by searching the remaining unused elements for one with a matching type, switching positions of these two items and returning the found item now on the current position:

@@ -131,25 +133,44 @@
 data_unset *array_get_unused_element(array *a, data_type_t t) {
        data_unset *ds = NULL;

-       UNUSED(t);
-
        if (a->size == 0) return NULL;

        if (a->used == a->size) return NULL;

        if (a->data[a->used]) {
-               ds = a->data[a->used];
+             ds = a->data[a->used];

-               a->data[a->used] = NULL;
+             if(ds->type != t) {
+                 //The type does not match...?
+                 for (unsigned int i=(a->used + 1);i < a->size;i++) {
+                     //We try to find the next matching element..
+                     if(a->data[i] && a->data[i]->type == t) {
+                         //make a copy....
+                         data_unset *tmp = a->data[i];
+                         //move the unmatching on it's postion
+                         a->data[i] = ds;
+                         //free the old position...
+                         a->data[a->used] = NULL;
+                         //and return the found..
+                         return tmp;
+                     }
+                 }
+                 //We didn't find any matching element... we return null!!!
+                 return NULL;
+             } else {
+                 a->data[a->used] = NULL;
+             }
        }

+       UNUSED(t);
+
        return ds;
 }

#2 Updated by stbuehler about 4 years ago

  • Status changed from Patch Pending to Fixed
  • % Done changed from 0 to 100

Applied in changeset r2750.

Also available in: Atom