Bug Summary

File:db.c
Location:line 119, column 9
Description:Potential leak of memory pointed to by 'line'

Annotated Source Code

1/*
2 * Copyright (C) 2002 Emmanuel VARAGNAT <hddtemp@guzu.net>
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17 */
18
19// Include file generated by ./configure
20#ifdef HAVE_CONFIG_H1
21#include <config.h>
22#endif
23
24// Gettext includes
25#if ENABLE_NLS1
26#include <libintl.h>
27#define _(String)dcgettext (((void*)0), String, 5) gettext (String)dcgettext (((void*)0), String, 5)
28#else
29#define _(String)dcgettext (((void*)0), String, 5) (String)
30#endif
31
32// Standard includes
33#include <stdlib.h>
34#include <unistd.h>
35#include <stdio.h>
36#include <fcntl.h>
37#include <regex.h>
38#include <string.h>
39#include <errno(*__errno_location ()).h>
40
41// Application specific includes
42#include "db.h"
43
44#define MAX_LINE_LEN1024 1024
45
46static struct harddrive_entry *supported_drives = NULL((void*)0);
47struct harddrive_entry **last_entry = &supported_drives;
48
49struct harddrive_entry *is_a_supported_drive(const char* model) {
50 struct harddrive_entry *p;
51
52 if(model == NULL((void*)0))
53 return NULL((void*)0);
54
55 for(p = supported_drives; p; p = p->next) {
56 regex_t preg;
57 regmatch_t pmatch;
58
59 if(regcomp(&preg, p->regexp, REG_EXTENDED1))
60 exit(-2);
61
62 if(regexec(&preg, model, 1, &pmatch, 0) == 0)
63 return p;
64 }
65
66 return NULL((void*)0);
67}
68
69
70static const char *extract_string(char **string) {
71 char *str;
72
73 if(**string != '"')
74 return NULL((void*)0);
75 else
76 (*string)++;
77
78 str = *string;
79
80 for(; *str; str++) {
81 switch(*str) {
82 case '"':
83 return str;
84 break;
85 case '\\':
86 str++;
87 break;
88 }
89 }
90
91 return NULL((void*)0);
92}
93
94void display_supported_drives() {
95 unsigned char *tabs, *line;
96 struct harddrive_entry *p;
97 int max, len;
98
99 max = 0;
100 for(p = supported_drives; p; p = p->next) {
1
Loop condition is false. Execution continues on line 105
101 len = strlen(p->regexp);
102 if(len > max)
103 max = len;
104 }
105 len = max/8 + 1;
106 tabs = malloc(len+1);
107 memset(tabs, '\t', len);
108 tabs[len] = '\0';
109
110 len = (max/8 + 1) * 8;
111 line = malloc(len+1);
2
Memory is allocated
112 memset(line, '-', len);
113 line[len] = '\0';
114
115 printf(_("\n"dcgettext (((void*)0), "\n" "Regexp%s| Value | Description\n"
"------%s---------------------\n", 5)
116 "Regexp%s| Value | Description\n"dcgettext (((void*)0), "\n" "Regexp%s| Value | Description\n"
"------%s---------------------\n", 5)
117 "------%s---------------------\n")dcgettext (((void*)0), "\n" "Regexp%s| Value | Description\n"
"------%s---------------------\n", 5)
, tabs, line);
118
119 for(p = supported_drives; p; p = p->next) {
3
Potential leak of memory pointed to by 'line'
120 len = strlen(p->regexp);
121 printf(_("%s%s| %5d | %s\n")dcgettext (((void*)0), "%s%s| %5d | %s\n", 5),
122 p->regexp,
123 tabs+(len/8),
124 p->attribute_id,
125 p->description);
126 }
127 printf("\n");
128}
129
130
131static int parse_db_line(char *line) {
132 const char *regexp,
133 *description;
134 struct harddrive_entry *new_entry;
135 unsigned short value;
136 char unit;
137 char *p;
138
139 line += strspn(line, " \t")__extension__ ({ char __a0, __a1, __a2; (__builtin_constant_p
(" \t") && ((size_t)(const void *)((" \t") + 1) - (size_t
)(const void *)(" \t") == 1) ? ((__builtin_constant_p (line) &&
((size_t)(const void *)((line) + 1) - (size_t)(const void *)
(line) == 1)) ? __builtin_strspn (line, " \t") : ((__a0 = ((const
char *) (" \t"))[0], __a0 == '\0') ? ((void) (line), (size_t
) 0) : ((__a1 = ((const char *) (" \t"))[1], __a1 == '\0') ? __strspn_c1
(line, __a0) : ((__a2 = ((const char *) (" \t"))[2], __a2 ==
'\0') ? __strspn_c2 (line, __a0, __a1) : (((const char *) (" \t"
))[3] == '\0' ? __strspn_c3 (line, __a0, __a1, __a2) : __builtin_strspn
(line, " \t")))))) : __builtin_strspn (line, " \t")); })
;
140 if(*line == '#' || *line == '\0')
141 return 0;
142
143 /* extract regexp */
144 p = (char*) extract_string(&line);
145 if(p == NULL((void*)0) || *p == '\0')
146 return 1;
147
148 *p = '\0';
149 regexp = line;
150 line = p + 1;
151
152 /* extract value */
153 line += strspn(line, " \t")__extension__ ({ char __a0, __a1, __a2; (__builtin_constant_p
(" \t") && ((size_t)(const void *)((" \t") + 1) - (size_t
)(const void *)(" \t") == 1) ? ((__builtin_constant_p (line) &&
((size_t)(const void *)((line) + 1) - (size_t)(const void *)
(line) == 1)) ? __builtin_strspn (line, " \t") : ((__a0 = ((const
char *) (" \t"))[0], __a0 == '\0') ? ((void) (line), (size_t
) 0) : ((__a1 = ((const char *) (" \t"))[1], __a1 == '\0') ? __strspn_c1
(line, __a0) : ((__a2 = ((const char *) (" \t"))[2], __a2 ==
'\0') ? __strspn_c2 (line, __a0, __a1) : (((const char *) (" \t"
))[3] == '\0' ? __strspn_c3 (line, __a0, __a1, __a2) : __builtin_strspn
(line, " \t")))))) : __builtin_strspn (line, " \t")); })
;
154 if(! *line)
155 return 1;
156
157 p = line;
158 value = 0;
159 while(*p >= '0' && *p <= '9') {
160 value = 10*value + *p-'0';
161 p++;
162 }
163 if(*p == '\0' || ( *p != ' ' && *p != '\t') )
164 return 1;
165 line = p;
166
167 /* extract temperature units */
168 line += strspn(line, " \t")__extension__ ({ char __a0, __a1, __a2; (__builtin_constant_p
(" \t") && ((size_t)(const void *)((" \t") + 1) - (size_t
)(const void *)(" \t") == 1) ? ((__builtin_constant_p (line) &&
((size_t)(const void *)((line) + 1) - (size_t)(const void *)
(line) == 1)) ? __builtin_strspn (line, " \t") : ((__a0 = ((const
char *) (" \t"))[0], __a0 == '\0') ? ((void) (line), (size_t
) 0) : ((__a1 = ((const char *) (" \t"))[1], __a1 == '\0') ? __strspn_c1
(line, __a0) : ((__a2 = ((const char *) (" \t"))[2], __a2 ==
'\0') ? __strspn_c2 (line, __a0, __a1) : (((const char *) (" \t"
))[3] == '\0' ? __strspn_c3 (line, __a0, __a1, __a2) : __builtin_strspn
(line, " \t")))))) : __builtin_strspn (line, " \t")); })
;
169 if(! *line)
170 return 1;
171
172 if((*line != 'C' && *line != 'F') || ( *(line+1) != ' ' && *(line+1) != '\t' ))
173 return 1;
174
175 unit = *(line++);
176
177 /* extract description */
178 line += strspn(line, " \t")__extension__ ({ char __a0, __a1, __a2; (__builtin_constant_p
(" \t") && ((size_t)(const void *)((" \t") + 1) - (size_t
)(const void *)(" \t") == 1) ? ((__builtin_constant_p (line) &&
((size_t)(const void *)((line) + 1) - (size_t)(const void *)
(line) == 1)) ? __builtin_strspn (line, " \t") : ((__a0 = ((const
char *) (" \t"))[0], __a0 == '\0') ? ((void) (line), (size_t
) 0) : ((__a1 = ((const char *) (" \t"))[1], __a1 == '\0') ? __strspn_c1
(line, __a0) : ((__a2 = ((const char *) (" \t"))[2], __a2 ==
'\0') ? __strspn_c2 (line, __a0, __a1) : (((const char *) (" \t"
))[3] == '\0' ? __strspn_c3 (line, __a0, __a1, __a2) : __builtin_strspn
(line, " \t")))))) : __builtin_strspn (line, " \t")); })
;
179 if(! *line)
180 return 1;
181
182 p = (char*) extract_string(&line);
183 if(p == NULL((void*)0))
184 return 1;
185
186 description = line;
187 *p = '\0';
188
189 /* add new entry to the list */
190 new_entry = (struct harddrive_entry*) malloc(sizeof(struct harddrive_entry));
191 if(new_entry == NULL((void*)0)) {
192 perror("malloc");
193 exit(-1);
194 }
195
196 new_entry->regexp = strdup(regexp)(__extension__ (__builtin_constant_p (regexp) && ((size_t
)(const void *)((regexp) + 1) - (size_t)(const void *)(regexp
) == 1) ? (((const char *) (regexp))[0] == '\0' ? (char *) calloc
((size_t) 1, (size_t) 1) : ({ size_t __len = strlen (regexp)
+ 1; char *__retval = (char *) malloc (__len); if (__retval !=
((void*)0)) __retval = (char *) memcpy (__retval, regexp, __len
); __retval; })) : __strdup (regexp)))
;
197 new_entry->description = strdup(description)(__extension__ (__builtin_constant_p (description) &&
((size_t)(const void *)((description) + 1) - (size_t)(const void
*)(description) == 1) ? (((const char *) (description))[0] ==
'\0' ? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len
= strlen (description) + 1; char *__retval = (char *) malloc
(__len); if (__retval != ((void*)0)) __retval = (char *) memcpy
(__retval, description, __len); __retval; })) : __strdup (description
)))
;
198 new_entry->attribute_id = value;
199 new_entry->attribute_id2 = 0;
200 new_entry->unit = unit;
201 new_entry->next = NULL((void*)0);
202 *last_entry = new_entry;
203 last_entry = &(new_entry->next);
204
205 return 0;
206}
207
208void free_database(void) {
209 struct harddrive_entry *p;
210
211 p = supported_drives;
212
213 while( p ) {
214 struct harddrive_entry *q;
215
216 if(p->regexp)
217 free(p->regexp);
218
219 if(p->description)
220 free(p->description);
221
222 q = p;
223 p = p->next;
224 free(q);
225 }
226}
227
228void load_database(const char* filename) {
229 char buff[MAX_LINE_LEN1024];
230 char *p, *s, *e, *ee;
231 int fd;
232 int n, rest, numline;
233
234 errno(*__errno_location ()) = 0;
235 fd = open(filename, O_RDONLY00);
236 if(fd == -1) {
237 fprintf(stderrstderr, _("hddtemp: can't open %1$s: %2$s\n")dcgettext (((void*)0), "hddtemp: can't open %1$s: %2$s\n", 5), filename, strerror(errno(*__errno_location ())));
238 exit(2);
239 }
240
241 numline = 0;
242 rest = MAX_LINE_LEN1024;
243 p = buff;
244 while((n = read(fd, p, rest)) > 0) {
245 s = buff;
246 ee = p + n;
247 while((e = memchr(s, '\n', ee-s))) {
248 *e = '\0';
249 numline++;
250 if(parse_db_line(s)) {
251 fprintf(stderrstderr, _("ERROR: syntax error at line %1$d in %2$s\n")dcgettext (((void*)0), "ERROR: syntax error at line %1$d in %2$s\n"
, 5)
, numline, filename);
252 exit(2);
253 }
254 s = e+1;
255 }
256
257 if(s == buff) {
258 fprintf(stderrstderr, _(" ERROR: line exceed %1$d characters in %2$s.\n")dcgettext (((void*)0), " ERROR: line exceed %1$d characters in %2$s.\n"
, 5)
, MAX_LINE_LEN1024, filename);
259 close(fd);
260 exit(2);
261 }
262
263 memmove(buff, s, ee-s); /* because memory can overlap */
264
265 rest = MAX_LINE_LEN1024 - (ee-s);
266 p = buff + (ee-s);
267 }
268
269 close(fd);
270}
271