Bug Summary

File:gromacs/gmxlib/readinp.c
Location:line 188, column 37
Description:Dereference of null pointer

Annotated Source Code

1/*
2 * This file is part of the GROMACS molecular simulation package.
3 *
4 * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
5 * Copyright (c) 2001-2004, The GROMACS development team.
6 * Copyright (c) 2013,2014, by the GROMACS development team, led by
7 * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl,
8 * and including many others, as listed in the AUTHORS file in the
9 * top-level source directory and at http://www.gromacs.org.
10 *
11 * GROMACS is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU Lesser General Public License
13 * as published by the Free Software Foundation; either version 2.1
14 * of the License, or (at your option) any later version.
15 *
16 * GROMACS is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * Lesser General Public License for more details.
20 *
21 * You should have received a copy of the GNU Lesser General Public
22 * License along with GROMACS; if not, see
23 * http://www.gnu.org/licenses, or write to the Free Software Foundation,
24 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
25 *
26 * If you want to redistribute modifications to GROMACS, please
27 * consider that scientific software is very special. Version
28 * control is crucial - bugs must be traceable. We will be happy to
29 * consider code for inclusion in the official distribution, but
30 * derived work must not be called official GROMACS. Details are found
31 * in the README & COPYING files - if they are missing, get the
32 * official version at http://www.gromacs.org.
33 *
34 * To help us fund GROMACS development, we humbly ask that you cite
35 * the research papers on the package. Check out http://www.gromacs.org.
36 */
37#ifdef HAVE_CONFIG_H1
38#include <config.h>
39#endif
40
41#include <stdio.h>
42#include <stdlib.h>
43#include "typedefs.h"
44#include "gromacs/utility/cstringutil.h"
45#include "gromacs/utility/futil.h"
46#include "gromacs/utility/smalloc.h"
47#include "readinp.h"
48#include "macros.h"
49#include "gromacs/fileio/gmxfio.h"
50#include "names.h"
51#include "warninp.h"
52#include "gromacs/utility/fatalerror.h"
53
54t_inpfile *read_inpfile(const char *fn, int *ninp,
55 warninp_t wi)
56{
57 FILE *in;
58 char buf[STRLEN4096], lbuf[STRLEN4096], rbuf[STRLEN4096], warn_buf[STRLEN4096];
59 char *ptr, *cptr;
60 t_inpfile *inp = NULL((void*)0);
1
'inp' initialized to a null pointer value
61 int nin, lc, i, j, k;
62 /* setting cppopts from command-line options would be cooler */
63 gmx_bool allow_override = FALSE0;
64
65
66 if (debug)
2
Assuming 'debug' is null
3
Taking false branch
67 {
68 fprintf(debug, "Reading MDP file %s\n", fn);
69 }
70
71 in = gmx_ffopen(fn, "r");
72
73 nin = lc = 0;
74 do
15
Loop condition is true. Execution continues on line 76
27
Loop condition is true. Execution continues on line 76
75 {
76 ptr = fgets2(buf, STRLEN4096-1, in);
77 lc++;
78 set_warning_line(wi, fn, lc);
79 if (ptr)
4
Assuming 'ptr' is non-null
5
Taking true branch
16
Assuming 'ptr' is non-null
17
Taking true branch
28
Assuming 'ptr' is non-null
29
Taking true branch
80 {
81 /* Strip comment */
82 if ((cptr = strchr(buf, COMMENTSIGN)(__extension__ (__builtin_constant_p (';') && !__builtin_constant_p
(buf) && (';') == '\0' ? (char *) __rawmemchr (buf, ';'
) : __builtin_strchr (buf, ';')))
) != NULL((void*)0))
6
Taking false branch
18
Taking false branch
30
Taking false branch
83 {
84 *cptr = '\0';
85 }
86 /* Strip spaces */
87 trim(buf);
88
89 for (j = 0; (buf[j] != '=') && (buf[j] != '\0'); j++)
90 {
91 ;
92 }
93 if (buf[j] == '\0')
7
Taking false branch
19
Taking false branch
31
Taking false branch
94 {
95 if (j > 0)
96 {
97 if (debug)
98 {
99 fprintf(debug, "No = on line %d in file %s, ignored\n", lc, fn);
100 }
101 }
102 }
103 else
104 {
105 for (i = 0; (i < j); i++)
8
Loop condition is false. Execution continues on line 109
20
Loop condition is false. Execution continues on line 109
32
Loop condition is false. Execution continues on line 109
106 {
107 lbuf[i] = buf[i];
108 }
109 lbuf[i] = '\0';
110 trim(lbuf);
111 if (lbuf[0] == '\0')
9
Taking false branch
21
Taking false branch
33
Taking false branch
112 {
113 if (debug)
114 {
115 fprintf(debug, "Empty left hand side on line %d in file %s, ignored\n", lc, fn);
116 }
117 }
118 else
119 {
120 for (i = j+1, k = 0; (buf[i] != '\0'); i++, k++)
10
Loop condition is false. Execution continues on line 124
22
Loop condition is false. Execution continues on line 124
34
Loop condition is false. Execution continues on line 124
121 {
122 rbuf[k] = buf[i];
123 }
124 rbuf[k] = '\0';
125 trim(rbuf);
126 if (rbuf[0] == '\0')
11
Taking false branch
23
Taking false branch
35
Taking false branch
127 {
128 if (debug)
129 {
130 fprintf(debug, "Empty right hand side on line %d in file %s, ignored\n", lc, fn);
131 }
132 }
133 else
134 {
135 /* Now finally something sensible */
136 int found_index;
137
138 /* first check whether we hit the 'multiple_entries' option */
139 if (gmx_strcasecmp_min(eMultentOpt_names[eMultentOptName], lbuf) == 0)
12
Taking false branch
24
Taking true branch
36
Taking false branch
140 {
141 /* we now check whether to allow overrides from here or not */
142 if (gmx_strcasecmp_min(eMultentOpt_names[eMultentOptNo], rbuf) == 0)
25
Taking false branch
143 {
144 allow_override = FALSE0;
145 }
146 else if (gmx_strcasecmp_min(eMultentOpt_names[eMultentOptLast], rbuf) == 0)
26
Taking true branch
147 {
148 allow_override = TRUE1;
149 }
150 else
151 {
152 sprintf(warn_buf,
153 "Parameter \"%s\" should either be %s or %s\n",
154 lbuf,
155 eMultentOpt_names[eMultentOptNo],
156 eMultentOpt_names[eMultentOptLast]);
157 warning_error(wi, warn_buf);
158 }
159 }
160 else
161 {
162 /* it is a regular option; check for duplicates */
163 found_index = search_einp(nin, inp, lbuf);
164
165 if (found_index == -1)
13
Taking false branch
37
Taking false branch
166 {
167 /* add a new item */
168 srenew(inp, ++nin)(inp) = save_realloc("inp", "/home/alexxy/Develop/gromacs/src/gromacs/gmxlib/readinp.c"
, 168, (inp), (++nin), sizeof(*(inp)))
;
169 inp[nin-1].inp_count = 1;
170 inp[nin-1].count = 0;
171 inp[nin-1].bObsolete = FALSE0;
172 inp[nin-1].bSet = FALSE0;
173 inp[nin-1].name = strdup(lbuf)(__extension__ (__builtin_constant_p (lbuf) && ((size_t
)(const void *)((lbuf) + 1) - (size_t)(const void *)(lbuf) ==
1) ? (((const char *) (lbuf))[0] == '\0' ? (char *) calloc (
(size_t) 1, (size_t) 1) : ({ size_t __len = strlen (lbuf) + 1
; char *__retval = (char *) malloc (__len); if (__retval != (
(void*)0)) __retval = (char *) memcpy (__retval, lbuf, __len)
; __retval; })) : __strdup (lbuf)))
;
174 inp[nin-1].value = strdup(rbuf)(__extension__ (__builtin_constant_p (rbuf) && ((size_t
)(const void *)((rbuf) + 1) - (size_t)(const void *)(rbuf) ==
1) ? (((const char *) (rbuf))[0] == '\0' ? (char *) calloc (
(size_t) 1, (size_t) 1) : ({ size_t __len = strlen (rbuf) + 1
; char *__retval = (char *) malloc (__len); if (__retval != (
(void*)0)) __retval = (char *) memcpy (__retval, rbuf, __len)
; __retval; })) : __strdup (rbuf)))
;
175 }
176 else
177 {
178 if (!allow_override)
14
Taking true branch
38
Taking false branch
179 {
180 sprintf(warn_buf,
181 "Parameter \"%s\" doubly defined (and multiple assignments not allowed)\n",
182 lbuf);
183 warning_error(wi, warn_buf);
184 }
185 else
186 {
187 /* override */
188 sfree(inp[found_index].value)save_free("inp[found_index].value", "/home/alexxy/Develop/gromacs/src/gromacs/gmxlib/readinp.c"
, 188, (inp[found_index].value))
;
39
Within the expansion of the macro 'sfree':
a
Dereference of null pointer
189 inp[found_index].value = strdup(rbuf)(__extension__ (__builtin_constant_p (rbuf) && ((size_t
)(const void *)((rbuf) + 1) - (size_t)(const void *)(rbuf) ==
1) ? (((const char *) (rbuf))[0] == '\0' ? (char *) calloc (
(size_t) 1, (size_t) 1) : ({ size_t __len = strlen (rbuf) + 1
; char *__retval = (char *) malloc (__len); if (__retval != (
(void*)0)) __retval = (char *) memcpy (__retval, rbuf, __len)
; __retval; })) : __strdup (rbuf)))
;
190 sprintf(warn_buf,
191 "Overriding existing parameter \"%s\" with value \"%s\"\n",
192 lbuf, rbuf);
193 warning_note(wi, warn_buf);
194 }
195 }
196 }
197 }
198 }
199 }
200 }
201 }
202 while (ptr);
203
204 gmx_ffclose(in);
205
206 if (debug)
207 {
208 fprintf(debug, "Done reading MDP file, there were %d entries in there\n",
209 nin);
210 }
211
212 *ninp = nin;
213
214 return inp;
215}
216
217
218
219
220static int inp_comp(const void *a, const void *b)
221{
222 return ((t_inpfile *)a)->count - ((t_inpfile *)b)->count;
223}
224
225static void sort_inp(int ninp, t_inpfile inp[])
226{
227 int i, mm;
228
229 mm = -1;
230 for (i = 0; (i < ninp); i++)
231 {
232 mm = max(mm, inp[i].count)(((mm) > (inp[i].count)) ? (mm) : (inp[i].count) );
233 }
234 for (i = 0; (i < ninp); i++)
235 {
236 if (inp[i].count == 0)
237 {
238 inp[i].count = mm++;
239 }
240 }
241 qsort(inp, ninp, (size_t)sizeof(inp[0]), inp_comp);
242}
243
244void write_inpfile(const char *fn, int ninp, t_inpfile inp[], gmx_bool bHaltOnUnknown,
245 warninp_t wi)
246{
247 FILE *out;
248 int i;
249 char warn_buf[STRLEN4096];
250
251 sort_inp(ninp, inp);
252 out = gmx_fio_fopen(fn, "w");
253 nice_header(out, fn);
254 for (i = 0; (i < ninp); i++)
255 {
256 if (inp[i].bSet)
257 {
258 if (inp[i].name[0] == ';' || (strlen(inp[i].name) > 2 && inp[i].name[1] == ';'))
259 {
260 fprintf(out, "%-24s\n", inp[i].name);
261 }
262 else
263 {
264 fprintf(out, "%-24s = %s\n", inp[i].name, inp[i].value ? inp[i].value : "");
265 }
266 }
267 else if (!inp[i].bObsolete)
268 {
269 sprintf(warn_buf, "Unknown left-hand '%s' in parameter file\n",
270 inp[i].name);
271 if (bHaltOnUnknown)
272 {
273 warning_error(wi, warn_buf);
274 }
275 else
276 {
277 warning(wi, warn_buf);
278 }
279 }
280 }
281 gmx_fio_fclose(out);
282
283 check_warning_error(wi, FARGS0, "/home/alexxy/Develop/gromacs/src/gromacs/gmxlib/readinp.c"
, 283
);
284}
285
286void replace_inp_entry(int ninp, t_inpfile *inp, const char *old_entry, const char *new_entry)
287{
288 int i;
289
290 for (i = 0; (i < ninp); i++)
291 {
292 if (gmx_strcasecmp_min(old_entry, inp[i].name) == 0)
293 {
294 if (new_entry)
295 {
296 fprintf(stderrstderr, "Replacing old mdp entry '%s' by '%s'\n",
297 inp[i].name, new_entry);
298 sfree(inp[i].name)save_free("inp[i].name", "/home/alexxy/Develop/gromacs/src/gromacs/gmxlib/readinp.c"
, 298, (inp[i].name))
;
299 inp[i].name = strdup(new_entry)(__extension__ (__builtin_constant_p (new_entry) && (
(size_t)(const void *)((new_entry) + 1) - (size_t)(const void
*)(new_entry) == 1) ? (((const char *) (new_entry))[0] == '\0'
? (char *) calloc ((size_t) 1, (size_t) 1) : ({ size_t __len
= strlen (new_entry) + 1; char *__retval = (char *) malloc (
__len); if (__retval != ((void*)0)) __retval = (char *) memcpy
(__retval, new_entry, __len); __retval; })) : __strdup (new_entry
)))
;
300 }
301 else
302 {
303 fprintf(stderrstderr, "Ignoring obsolete mdp entry '%s'\n",
304 inp[i].name);
305 inp[i].bObsolete = TRUE1;
306 }
307 }
308 }
309}
310
311int search_einp(int ninp, const t_inpfile *inp, const char *name)
312{
313 int i;
314
315 if (inp == NULL((void*)0))
316 {
317 return -1;
318 }
319 for (i = 0; i < ninp; i++)
320 {
321 if (gmx_strcasecmp_min(name, inp[i].name) == 0)
322 {
323 return i;
324 }
325 }
326 return -1;
327}
328
329static int get_einp(int *ninp, t_inpfile **inp, const char *name)
330{
331 int i;
332 int notfound = FALSE0;
333 char warn_buf[STRLEN4096];
334
335/* if (inp==NULL)
336 return -1;
337 for(i=0; (i<(*ninp)); i++)
338 if (gmx_strcasecmp_min(name,(*inp)[i].name) == 0)
339 break;
340 if (i == (*ninp)) {*/
341 i = search_einp(*ninp, *inp, name);
342 if (i == -1)
343 {
344 notfound = TRUE1;
345 i = (*ninp)++;
346 srenew(*inp, (*ninp))(*inp) = save_realloc("*inp", "/home/alexxy/Develop/gromacs/src/gromacs/gmxlib/readinp.c"
, 346, (*inp), ((*ninp)), sizeof(*(*inp)))
;
347 (*inp)[i].name = strdup(name)(__extension__ (__builtin_constant_p (name) && ((size_t
)(const void *)((name) + 1) - (size_t)(const void *)(name) ==
1) ? (((const char *) (name))[0] == '\0' ? (char *) calloc (
(size_t) 1, (size_t) 1) : ({ size_t __len = strlen (name) + 1
; char *__retval = (char *) malloc (__len); if (__retval != (
(void*)0)) __retval = (char *) memcpy (__retval, name, __len)
; __retval; })) : __strdup (name)))
;
348 (*inp)[i].bSet = TRUE1;
349 }
350 (*inp)[i].count = (*inp)[0].inp_count++;
351 (*inp)[i].bSet = TRUE1;
352 if (debug)
353 {
354 fprintf(debug, "Inp %d = %s\n", (*inp)[i].count, (*inp)[i].name);
355 }
356
357 /*if (i == (*ninp)-1)*/
358 if (notfound)
359 {
360 return -1;
361 }
362 else
363 {
364 return i;
365 }
366}
367
368int get_eint(int *ninp, t_inpfile **inp, const char *name, int def,
369 warninp_t wi)
370{
371 char buf[32], *ptr, warn_buf[STRLEN4096];
372 int ii;
373 int ret;
374
375 ii = get_einp(ninp, inp, name);
376
377 if (ii == -1)
378 {
379 sprintf(buf, "%d", def);
380 (*inp)[(*ninp)-1].value = strdup(buf)(__extension__ (__builtin_constant_p (buf) && ((size_t
)(const void *)((buf) + 1) - (size_t)(const void *)(buf) == 1
) ? (((const char *) (buf))[0] == '\0' ? (char *) calloc ((size_t
) 1, (size_t) 1) : ({ size_t __len = strlen (buf) + 1; char *
__retval = (char *) malloc (__len); if (__retval != ((void*)0
)) __retval = (char *) memcpy (__retval, buf, __len); __retval
; })) : __strdup (buf)))
;
381
382 return def;
383 }
384 else
385 {
386 ret = strtol((*inp)[ii].value, &ptr, 10);
387 if (ptr == (*inp)[ii].value)
388 {
389 sprintf(warn_buf, "Right hand side '%s' for parameter '%s' in parameter file is not an integer value\n", (*inp)[ii].value, (*inp)[ii].name);
390 warning_error(wi, warn_buf);
391 }
392
393 return ret;
394 }
395}
396
397gmx_int64_t get_eint64(int *ninp, t_inpfile **inp,
398 const char *name, gmx_int64_t def,
399 warninp_t wi)
400{
401 char buf[32], *ptr, warn_buf[STRLEN4096];
402 int ii;
403 gmx_int64_t ret;
404
405 ii = get_einp(ninp, inp, name);
406
407 if (ii == -1)
408 {
409 sprintf(buf, "%"GMX_PRId64"l" "d", def);
410 (*inp)[(*ninp)-1].value = strdup(buf)(__extension__ (__builtin_constant_p (buf) && ((size_t
)(const void *)((buf) + 1) - (size_t)(const void *)(buf) == 1
) ? (((const char *) (buf))[0] == '\0' ? (char *) calloc ((size_t
) 1, (size_t) 1) : ({ size_t __len = strlen (buf) + 1; char *
__retval = (char *) malloc (__len); if (__retval != ((void*)0
)) __retval = (char *) memcpy (__retval, buf, __len); __retval
; })) : __strdup (buf)))
;
411
412 return def;
413 }
414 else
415 {
416 ret = str_to_int64_t((*inp)[ii].value, &ptr);
417 if (ptr == (*inp)[ii].value)
418 {
419 sprintf(warn_buf, "Right hand side '%s' for parameter '%s' in parameter file is not an integer value\n", (*inp)[ii].value, (*inp)[ii].name);
420 warning_error(wi, warn_buf);
421 }
422
423 return ret;
424 }
425}
426
427double get_ereal(int *ninp, t_inpfile **inp, const char *name, double def,
428 warninp_t wi)
429{
430 char buf[32], *ptr, warn_buf[STRLEN4096];
431 int ii;
432 double ret;
433
434 ii = get_einp(ninp, inp, name);
435
436 if (ii == -1)
437 {
438 sprintf(buf, "%g", def);
439 (*inp)[(*ninp)-1].value = strdup(buf)(__extension__ (__builtin_constant_p (buf) && ((size_t
)(const void *)((buf) + 1) - (size_t)(const void *)(buf) == 1
) ? (((const char *) (buf))[0] == '\0' ? (char *) calloc ((size_t
) 1, (size_t) 1) : ({ size_t __len = strlen (buf) + 1; char *
__retval = (char *) malloc (__len); if (__retval != ((void*)0
)) __retval = (char *) memcpy (__retval, buf, __len); __retval
; })) : __strdup (buf)))
;
440
441 return def;
442 }
443 else
444 {
445 ret = strtod((*inp)[ii].value, &ptr);
446 if (ptr == (*inp)[ii].value)
447 {
448 sprintf(warn_buf, "Right hand side '%s' for parameter '%s' in parameter file is not a real value\n", (*inp)[ii].value, (*inp)[ii].name);
449 warning_error(wi, warn_buf);
450 }
451
452 return ret;
453 }
454}
455
456const char *get_estr(int *ninp, t_inpfile **inp, const char *name, const char *def)
457{
458 char buf[32];
459 int ii;
460
461 ii = get_einp(ninp, inp, name);
462
463 if (ii == -1)
464 {
465 if (def)
466 {
467 sprintf(buf, "%s", def);
468 (*inp)[(*ninp)-1].value = strdup(buf)(__extension__ (__builtin_constant_p (buf) && ((size_t
)(const void *)((buf) + 1) - (size_t)(const void *)(buf) == 1
) ? (((const char *) (buf))[0] == '\0' ? (char *) calloc ((size_t
) 1, (size_t) 1) : ({ size_t __len = strlen (buf) + 1; char *
__retval = (char *) malloc (__len); if (__retval != ((void*)0
)) __retval = (char *) memcpy (__retval, buf, __len); __retval
; })) : __strdup (buf)))
;
469 }
470 else
471 {
472 (*inp)[(*ninp)-1].value = NULL((void*)0);
473 }
474
475 return def;
476 }
477 else
478 {
479 return (*inp)[ii].value;
480 }
481}
482
483int get_eeenum(int *ninp, t_inpfile **inp, const char *name, const char **defs,
484 warninp_t wi)
485{
486 int ii, i, j;
487 int n = 0;
488 char buf[STRLEN4096];
489
490 ii = get_einp(ninp, inp, name);
491
492 if (ii == -1)
493 {
494 (*inp)[(*ninp)-1].value = strdup(defs[0])(__extension__ (__builtin_constant_p (defs[0]) && ((size_t
)(const void *)((defs[0]) + 1) - (size_t)(const void *)(defs[
0]) == 1) ? (((const char *) (defs[0]))[0] == '\0' ? (char *)
calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen (
defs[0]) + 1; char *__retval = (char *) malloc (__len); if (__retval
!= ((void*)0)) __retval = (char *) memcpy (__retval, defs[0]
, __len); __retval; })) : __strdup (defs[0])))
;
495
496 return 0;
497 }
498
499 for (i = 0; (defs[i] != NULL((void*)0)); i++)
500 {
501 if (gmx_strcasecmp_min(defs[i], (*inp)[ii].value) == 0)
502 {
503 break;
504 }
505 }
506
507 if (defs[i] == NULL((void*)0))
508 {
509 n += sprintf(buf, "Invalid enum '%s' for variable %s, using '%s'\n",
510 (*inp)[ii].value, name, defs[0]);
511 n += sprintf(buf+n, "Next time use one of:");
512 j = 0;
513 while (defs[j])
514 {
515 n += sprintf(buf+n, " '%s'", defs[j]);
516 j++;
517 }
518 if (wi != NULL((void*)0))
519 {
520 warning_error(wi, buf);
521 }
522 else
523 {
524 fprintf(stderrstderr, "%s\n", buf);
525 }
526
527 (*inp)[ii].value = strdup(defs[0])(__extension__ (__builtin_constant_p (defs[0]) && ((size_t
)(const void *)((defs[0]) + 1) - (size_t)(const void *)(defs[
0]) == 1) ? (((const char *) (defs[0]))[0] == '\0' ? (char *)
calloc ((size_t) 1, (size_t) 1) : ({ size_t __len = strlen (
defs[0]) + 1; char *__retval = (char *) malloc (__len); if (__retval
!= ((void*)0)) __retval = (char *) memcpy (__retval, defs[0]
, __len); __retval; })) : __strdup (defs[0])))
;
528
529 return 0;
530 }
531
532 return i;
533}
534
535int get_eenum(int *ninp, t_inpfile **inp, const char *name, const char **defs)
536{
537 int dum = 0;
538
539 return get_eeenum(ninp, inp, name, defs, NULL((void*)0));
540}