Bug Summary

File:lwan/main.c
Location:line 133, column 16
Description:Potential leak of memory pointed to by 'c.listener'

Annotated Source Code

1/*
2 * lwan - simple web server
3 * Copyright (c) 2012 Leandro A. F. Pereira <leandro@hardinfo.org>
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * as published by the Free Software Foundation; either version 2
8 * of the License, or any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 */
19
20#define _GNU_SOURCE
21#include <getopt.h>
22#include <stdlib.h>
23#include <unistd.h>
24#include <limits.h>
25
26#include "lwan.h"
27#include "lwan-serve-files.h"
28
29enum args {
30 ARGS_FAILED,
31 ARGS_USE_CONFIG,
32 ARGS_SERVE_FILES
33};
34
35static enum args
36parse_args(int argc, char *argv[], lwan_config_t *config, char *root)
37{
38 static const struct option opts[] = {
39 { .name = "root", .has_arg = 1, .val = 'r' },
40 { .name = "listen", .has_arg = 1, .val = 'l' },
41 { .name = "help", .val = 'h' },
42 { .name = "config", .has_arg = 1, .val = 'c' },
43 { }
44 };
45 int c, optidx = 0;
46 enum args result = ARGS_USE_CONFIG;
47
48 while ((c = getopt_long(argc, argv, "hr:l:c:", opts, &optidx)) != -1) {
3
Loop condition is true. Entering loop body
7
Loop condition is true. Entering loop body
49 switch (c) {
4
Control jumps to 'case 108:' at line 56
8
Control jumps to the 'default' case at line 93
50 case 'c':
51 free(config->config_file_path);
52 config->config_file_path = strdup(optarg);
53 result = ARGS_USE_CONFIG;
54 break;
55
56 case 'l':
57 free(config->listener);
58 config->listener = strdup(optarg);
5
Memory is allocated
59 result = ARGS_SERVE_FILES;
60 break;
6
Execution continues on line 48
61
62 case 'r': {
63 size_t len = strlen(optarg);
64
65 if (len >= PATH_MAX4096) {
66 fprintf(stderrstderr, "Root path length exeeds %d characters\n", PATH_MAX4096);
67 return ARGS_FAILED;
68 }
69
70 memcpy(root, optarg, len + 1);
71 result = ARGS_SERVE_FILES;
72 break;
73 }
74
75 case 'h':
76 printf("Usage: %s [--root /path/to/root/dir] [--listener addr:port]\n", argv[0]);
77 printf("\t[--config]\n");
78 printf("Serve files through HTTP.\n\n");
79 printf("Defaults to listening on %s, serving from ./wwwroot.\n\n", config->listener);
80 printf("Options:\n");
81 printf("\t-r, --root Path to serve files from (default: ./wwwroot).\n");
82 printf("\t-l, --listener Listener (default: %s).\n", config->listener);
83 printf("\t-c, --config Path to config file path.\n");
84 printf("\t-h, --help This.\n");
85 printf("\n");
86 printf("Examples:\n");
87 printf(" Serve system-wide documentation: %s -r /usr/share/doc\n", argv[0]);
88 printf(" Serve on a different port: %s -l '*:1337'\n", argv[0]);
89 printf("\n");
90 printf("Report bugs at <https://github.com/lpereira/lwan>.\n");
91 return ARGS_FAILED;
92
93 default:
94 printf("Run %s --help for usage information.\n", argv[0]);
95 return ARGS_FAILED;
96 }
97 }
98
99 return result;
100}
101
102int
103main(int argc, char *argv[])
104{
105 lwan_t l;
106 lwan_config_t c;
107 char root[PATH_MAX4096];
108
109 if (!getcwd(root, PATH_MAX4096))
1
Taking false branch
110 return 1;
111
112 c = *lwan_get_default_config();
113 c.listener = strdup("*:8080");
114
115 switch (parse_args(argc, argv, &c, root)) {
2
Calling 'parse_args'
9
Returned allocated memory
10
Control jumps to 'case ARGS_FAILED:' at line 132
116 case ARGS_SERVE_FILES:
117 lwan_status_info("Serving files from %s", root)lwan_status_info_debug("/home/buildbot/lwan-slave/clang-analyze/build/lwan/main.c"
, 117, __FUNCTION__, "Serving files from %s", root)
;
118 lwan_init_with_config(&l, &c);
119
120 const lwan_url_map_t map[] = {
121 { .prefix = "/", SERVE_FILES(root).module = lwan_module_serve_files(), .args = ((struct lwan_serve_files_settings_t
[]) {{ .root_path = root, .index_html = ((void*)0), .serve_precompressed_files
= 1, .directory_list_template = ((void*)0), .auto_index = 1 }
}), .flags = (lwan_handler_flags_t)0
},
122 { }
123 };
124 lwan_set_url_map(&l, map);
125 break;
126 case ARGS_USE_CONFIG:
127 if (c.config_file_path)
128 lwan_init_with_config(&l, &c);
129 else
130 lwan_init(&l);
131 break;
132 case ARGS_FAILED:
133 return EXIT_FAILURE1;
11
Within the expansion of the macro 'EXIT_FAILURE':
a
Potential leak of memory pointed to by 'c.listener'
134 }
135
136 lwan_main_loop(&l);
137 lwan_shutdown(&l);
138
139 return EXIT_SUCCESS0;
140}