Back to success stories

Sample of Defect

Project Name CID Checker Category Developer Description
ssurface 45162 RESOURCE_LEAK Resource leaks it was leading to a crash
File: /home/cardinot/subsurface/src/subsurface/load-git.c
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
        degrees_t longitude = parse_degrees(line, &line);
        struct dive *dive = _dive;
        struct dive_site *ds = get_dive_site_for_dive(dive);
        if (!ds) {
                uuid = get_dive_site_uuid_by_gps(latitude, longitude, NULL);
                if (!uuid)
                        uuid = create_dive_site_with_gps("", latitude, longitude);
                dive->dive_site_uuid = uuid;
        } else {
                if (dive_site_has_gps_location(ds) &&
                    (ds->latitude.udeg != latitude.udeg || ds->longitude.udeg != longitude.udeg)) {
                        // we have a dive site that already has GPS coordinates
                        ds->notes = add_to_string(ds->notes, translate("gettextFromC", "multiple gps locations for this dive site; also %s\n"),
                                                  printGPSCoords(latitude.udeg, longitude.udeg));
                }
                ds->latitude = latitude;
                ds->longitude = longitude;
        }

}

static void parse_dive_location(char *line, struct membuffer *str, void *_dive)
{
        uint32_t uuid;
 << 1. Storage is returned from allocation function "get_utf8".
 << 2. Assigning: "name" = storage returned from "get_utf8(str)".
174
175
176
        char *name = get_utf8(str);
        struct dive *dive = _dive;
        struct dive_site *ds = get_dive_site_for_dive(dive);
 << 3. Resource "name" is not freed or pointed-to in "fprintf".
177
        fprintf(stderr, "looking for a site named {%s} ", name);
 < 4. Condition "!ds", taking true branch
178
        if (!ds) {
 << 5. Resource "name" is not freed or pointed-to in "get_dive_site_uuid_by_name".
179
                uuid = get_dive_site_uuid_by_name(name, NULL);
 < 6. Condition "!uuid", taking true branch
180
                if (!uuid) { fprintf(stderr, "found none, creating\n");
 << 7. Resource "name" is not freed or pointed-to in "create_dive_site".
181
                        uuid = create_dive_site(name);
 < 8. Falling through to end of if statement
182
183
                } else { fprintf(stderr, "found one with uuid %8x\n", uuid); }
                dive->dive_site_uuid = uuid;
 < 9. Falling through to end of if statement
184
185
186
187
188
189
190
191
192
193
194
        } else {
                // we already had a dive site linked to the dive
                fprintf(stderr, "dive had site with uuid %8x and name {%s}\n", ds->uuid, ds->name);
                if (same_string(ds->name, "")) {
                        ds->name = name;
                } else {
                        // and that dive site had a name. that's weird - if our name is different, add it to the notes
                        if (!same_string(ds->name, name))
                                ds->notes = add_to_string(ds->notes, translate("gettextFromC", "additional name for site: %s\n"), name);
                }
        }
 <<< CID 45162: Resource leaks RESOURCE_LEAK
 <<< 10. Variable "name" going out of scope leaks the storage it points to.
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
}

static void parse_dive_divemaster(char *line, struct membuffer *str, void *_dive)
{ struct dive *dive = _dive; dive->divemaster = get_utf8(str); }

static void parse_dive_buddy(char *line, struct membuffer *str, void *_dive)
{ struct dive *dive = _dive; dive->buddy = get_utf8(str); }

static void parse_dive_suit(char *line, struct membuffer *str, void *_dive)
{ struct dive *dive = _dive; dive->suit = get_utf8(str); }

static void parse_dive_notes(char *line, struct membuffer *str, void *_dive)
{ struct dive *dive = _dive; dive->notes = get_utf8(str); }

static void parse_dive_divesiteid(char *line, struct membuffer *str, void *_dive)
{ struct dive *dive = _dive; dive->dive_site_uuid = get_hex(line); }

/*
 * We can have multiple tags in the membuffer. They are separated by
 * NUL bytes.
 */
static void parse_dive_tags(char *line, struct membuffer *str, void *_dive)
{
        struct dive *dive = _dive;
        const char *tag;
        int len = str->len;
Events:
1. alloc_fn load-git.c:174
2. var_assign load-git.c:174
3. noescape load-git.c:177
5. noescape load-git.c:179
7. noescape load-git.c:181
10. leaked_storage load-git.c:195