| File: | db.c | 
| Location: | line 119, column 9 | 
| Description: | Potential leak of memory pointed to by 'line' | 
| 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 |