source: lib/ini.c @ a18cf1b

Last change on this file since a18cf1b was ea39049, checked in by dequis <dx@…>, at 2015-12-17T16:56:25Z

ini: Null check file parameter before passing it to open()

The test suite does this. It's harmless in practice but open() is
declared as nonnull. Thanks to clang's ubsan.

  • Property mode set to 100644
File size: 3.1 KB
RevLine 
[5ebff60]1/********************************************************************\
[b7d3cc34]2  * BitlBee -- An IRC to other IM-networks gateway                     *
3  *                                                                    *
[72b6783e]4  * Copyright 2002-2008 Wilmer van der Gaast and others                *
[b7d3cc34]5  \********************************************************************/
6
7/* INI file reading code                                                */
8
9/*
10  This program is free software; you can redistribute it and/or modify
11  it under the terms of the GNU General Public License as published by
12  the Free Software Foundation; either version 2 of the License, or
13  (at your option) any later version.
14
15  This program is distributed in the hope that it will be useful,
16  but WITHOUT ANY WARRANTY; without even the implied warranty of
17  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  GNU General Public License for more details.
19
20  You should have received a copy of the GNU General Public License with
21  the Debian GNU/Linux distribution in /usr/share/common-licenses/GPL;
[6f10697]22  if not, write to the Free Software Foundation, Inc., 51 Franklin St.,
23  Fifth Floor, Boston, MA  02110-1301  USA
[b7d3cc34]24*/
25#define BITLBEE_CORE
26#include "bitlbee.h"
27
[5ebff60]28ini_t *ini_open(char *file)
[b7d3cc34]29{
[ea39049]30        int fd = -1;
[72b6783e]31        ini_t *ini = NULL;
32        struct stat fi;
[5ebff60]33
[ea39049]34        if (file && (fd = open(file, O_RDONLY)) != -1 &&
[5ebff60]35            fstat(fd, &fi) == 0 &&
[72b6783e]36            fi.st_size <= 16384 &&
[5ebff60]37            (ini = g_malloc(sizeof(ini_t) + fi.st_size + 1)) &&
38            read(fd, ini->file, fi.st_size) == fi.st_size) {
39                memset(ini, 0, sizeof(ini_t));
[72b6783e]40                ini->size = fi.st_size;
41                ini->file[ini->size] = 0;
42                ini->cur = ini->file;
43                ini->c_section = "";
[5ebff60]44
45                close(fd);
46
[72b6783e]47                return ini;
[b7d3cc34]48        }
[0182773]49
[5ebff60]50        if (fd >= 0) {
51                close(fd);
52        }
53
54        ini_close(ini);
[72b6783e]55
56        return NULL;
[b7d3cc34]57}
58
[489f996]59/* Strips leading and trailing whitespace and returns a pointer to the first
60   non-ws character of the given string. */
[5ebff60]61static char *ini_strip_whitespace(char *in)
[489f996]62{
63        char *e;
64
[5ebff60]65        while (g_ascii_isspace(*in)) {
[489f996]66                in++;
[5ebff60]67        }
[489f996]68
[5ebff60]69        e = in + strlen(in) - 1;
70        while (e > in && g_ascii_isspace(*e)) {
[489f996]71                e--;
[5ebff60]72        }
[489f996]73        e[1] = 0;
[5ebff60]74
[489f996]75        return in;
76}
77
[5ebff60]78int ini_read(ini_t *file)
[b7d3cc34]79{
[72b6783e]80        char *s;
[5ebff60]81
82        while (file->cur && file->cur < file->file + file->size) {
[72b6783e]83                char *e, *next;
[5ebff60]84
[72b6783e]85                file->line++;
86
87                /* Find the end of line */
[5ebff60]88                if ((e = strchr(file->cur, '\n')) != NULL) {
[489f996]89                        *e = 0;
[72b6783e]90                        next = e + 1;
[5ebff60]91                } else {
[72b6783e]92                        /* No more lines. */
[5ebff60]93                        e = file->cur + strlen(file->cur);
[72b6783e]94                        next = NULL;
95                }
[5ebff60]96
[72b6783e]97                /* Comment? */
[5ebff60]98                if ((s = strchr(file->cur, '#')) != NULL) {
[489f996]99                        *s = 0;
[5ebff60]100                }
101
102                file->cur = ini_strip_whitespace(file->cur);
103
104                if (*file->cur == '[') {
[72b6783e]105                        file->cur++;
[5ebff60]106                        if ((s = strchr(file->cur, ']')) != NULL) {
[72b6783e]107                                *s = 0;
108                                file->c_section = file->cur;
109                        }
[5ebff60]110                } else if ((s = strchr(file->cur, '=')) != NULL) {
[72b6783e]111                        *s = 0;
[5ebff60]112                        file->key = ini_strip_whitespace(file->cur);
113                        file->value = ini_strip_whitespace(s + 1);
114
115                        if ((s = strchr(file->key, '.')) != NULL) {
[72b6783e]116                                *s = 0;
117                                file->section = file->key;
118                                file->key = s + 1;
[5ebff60]119                        } else {
[72b6783e]120                                file->section = file->c_section;
[b7d3cc34]121                        }
[5ebff60]122
[72b6783e]123                        file->cur = next;
124                        return 1;
[b7d3cc34]125                }
[489f996]126                /* else: noise/comment/etc, let's just ignore it. */
[72b6783e]127
128                file->cur = next;
[b7d3cc34]129        }
[5ebff60]130
[72b6783e]131        return 0;
[b7d3cc34]132}
133
[5ebff60]134void ini_close(ini_t *file)
[b7d3cc34]135{
[5ebff60]136        g_free(file);
[b7d3cc34]137}
Note: See TracBrowser for help on using the repository browser.