File: | db.c |
Location: | line 127, column 3 |
Description: | Potential leak of memory pointed to by 'tabs' |
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 | ||||
46 | static struct harddrive_entry *supported_drives = NULL((void*)0); | |||
47 | struct harddrive_entry **last_entry = &supported_drives; | |||
48 | ||||
49 | struct 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 | ||||
70 | static 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 | ||||
94 | void 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) { | |||
| ||||
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); | |||
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) { | |||
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 | ||||
131 | static 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 | ||||
208 | void 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 | ||||
228 | void 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 |