Prechádzať zdrojové kódy

Merge pull request #471 from tzimmofsecure/master

Fix some compiler warnings. Fix some issues reported by Coverity.
bel2125 8 rokov pred
rodič
commit
674c1eb71a
1 zmenil súbory, kde vykonal 82 pridanie a 22 odobranie
  1. 82 22
      src/civetweb.c

+ 82 - 22
src/civetweb.c

@@ -1257,7 +1257,7 @@ mg_current_thread_id(void)
 
 
 
 
 static uint64_t
 static uint64_t
-mg_get_current_time_ns()
+mg_get_current_time_ns(void)
 {
 {
 	struct timespec tsnow;
 	struct timespec tsnow;
 	clock_gettime(CLOCK_REALTIME, &tsnow);
 	clock_gettime(CLOCK_REALTIME, &tsnow);
@@ -2688,6 +2688,9 @@ mg_vsnprintf(const struct mg_connection *conn,
 	int n, ok;
 	int n, ok;
 
 
 	if (buflen == 0) {
 	if (buflen == 0) {
+		if (truncated) {
+			*truncated = 1;
+		}
 		return;
 		return;
 	}
 	}
 
 
@@ -6350,7 +6353,6 @@ interpret_uri(struct mg_connection *conn,    /* in: request (must be valid) */
 
 
 					if (truncated) {
 					if (truncated) {
 						mg_free(tmp_str);
 						mg_free(tmp_str);
-						tmp_str = NULL;
 						goto interpret_cleanup;
 						goto interpret_cleanup;
 					}
 					}
 					sep_pos = strlen(tmp_str);
 					sep_pos = strlen(tmp_str);
@@ -6657,6 +6659,9 @@ get_mime_type(struct mg_context *ctx, const char *path, struct vec *vec)
 	path_len = strlen(path);
 	path_len = strlen(path);
 
 
 	if (ctx == NULL || vec == NULL) {
 	if (ctx == NULL || vec == NULL) {
+		if (vec != NULL) {
+			memset(vec, '\0', sizeof(struct vec));
+		}
 		return;
 		return;
 	}
 	}
 
 
@@ -7587,13 +7592,21 @@ mg_url_encode(const char *src, char *dst, size_t dst_len)
 	return (*src == '\0') ? (int)(pos - dst) : -1;
 	return (*src == '\0') ? (int)(pos - dst) : -1;
 }
 }
 
 
+/* Return 0 on success, non-zero if an error occurs. */
 
 
-static void
+static int
 print_dir_entry(struct de *de)
 print_dir_entry(struct de *de)
 {
 {
-	char size[64], mod[64], href[PATH_MAX * 3 /* worst case */];
+	size_t hrefsize;
+	char *href;
+	char size[64], mod[64];
 	struct tm *tm;
 	struct tm *tm;
 
 
+	hrefsize = PATH_MAX * 3; /* worst case */
+	href = mg_malloc(hrefsize);
+	if (href == NULL) {
+		return -1;
+	}
 	if (de->file.is_directory) {
 	if (de->file.is_directory) {
 		mg_snprintf(de->conn,
 		mg_snprintf(de->conn,
 		            NULL, /* Buffer is big enough */
 		            NULL, /* Buffer is big enough */
@@ -7645,7 +7658,7 @@ print_dir_entry(struct de *de)
 		mg_strlcpy(mod, "01-Jan-1970 00:00", sizeof(mod));
 		mg_strlcpy(mod, "01-Jan-1970 00:00", sizeof(mod));
 		mod[sizeof(mod) - 1] = '\0';
 		mod[sizeof(mod) - 1] = '\0';
 	}
 	}
-	mg_url_encode(de->file_name, href, sizeof(href));
+	mg_url_encode(de->file_name, href, hrefsize);
 	mg_printf(de->conn,
 	mg_printf(de->conn,
 	          "<tr><td><a href=\"%s%s%s\">%s%s</a></td>"
 	          "<tr><td><a href=\"%s%s%s\">%s%s</a></td>"
 	          "<td>&nbsp;%s</td><td>&nbsp;&nbsp;%s</td></tr>\n",
 	          "<td>&nbsp;%s</td><td>&nbsp;&nbsp;%s</td></tr>\n",
@@ -7656,6 +7669,8 @@ print_dir_entry(struct de *de)
 	          de->file.is_directory ? "/" : "",
 	          de->file.is_directory ? "/" : "",
 	          mod,
 	          mod,
 	          size);
 	          size);
+	mg_free(href);
+	return 0;
 }
 }
 
 
 
 
@@ -7717,7 +7732,7 @@ static int
 scan_directory(struct mg_connection *conn,
 scan_directory(struct mg_connection *conn,
                const char *dir,
                const char *dir,
                void *data,
                void *data,
-               void (*cb)(struct de *, void *))
+               int (*cb)(struct de *, void *))
 {
 {
 	char path[PATH_MAX];
 	char path[PATH_MAX];
 	struct dirent *dp;
 	struct dirent *dp;
@@ -7856,7 +7871,7 @@ realloc2(void *ptr, size_t size)
 }
 }
 
 
 
 
-static void
+static int
 dir_scan_callback(struct de *de, void *data)
 dir_scan_callback(struct de *de, void *data)
 {
 {
 	struct dir_scan_data *dsd = (struct dir_scan_data *)data;
 	struct dir_scan_data *dsd = (struct dir_scan_data *)data;
@@ -7876,6 +7891,8 @@ dir_scan_callback(struct de *de, void *data)
 		dsd->entries[dsd->num_entries].conn = de->conn;
 		dsd->entries[dsd->num_entries].conn = de->conn;
 		dsd->num_entries++;
 		dsd->num_entries++;
 	}
 	}
+
+        return 0;
 }
 }
 
 
 
 
@@ -8917,8 +8934,9 @@ addenv(struct cgi_environment *env, const char *fmt, ...)
 	env->varused++;
 	env->varused++;
 }
 }
 
 
+/* Return 0 on success, non-zero if an error occurs. */
 
 
-static void
+static int
 prepare_cgi_environment(struct mg_connection *conn,
 prepare_cgi_environment(struct mg_connection *conn,
                         const char *prog,
                         const char *prog,
                         struct cgi_environment *env)
                         struct cgi_environment *env)
@@ -8929,16 +8947,28 @@ prepare_cgi_environment(struct mg_connection *conn,
 	int i, truncated, uri_len;
 	int i, truncated, uri_len;
 
 
 	if (conn == NULL || prog == NULL || env == NULL) {
 	if (conn == NULL || prog == NULL || env == NULL) {
-		return;
+		return -1;
 	}
 	}
 
 
 	env->conn = conn;
 	env->conn = conn;
 	env->buflen = CGI_ENVIRONMENT_SIZE;
 	env->buflen = CGI_ENVIRONMENT_SIZE;
 	env->bufused = 0;
 	env->bufused = 0;
 	env->buf = (char *)mg_malloc_ctx(env->buflen, conn->ctx);
 	env->buf = (char *)mg_malloc_ctx(env->buflen, conn->ctx);
+	if (env->buf == NULL) {
+		mg_cry(conn, "%s: Not enough memory for environmental buffer",
+		       __func__);
+		return -1;
+	}
 	env->varlen = MAX_CGI_ENVIR_VARS;
 	env->varlen = MAX_CGI_ENVIR_VARS;
 	env->varused = 0;
 	env->varused = 0;
 	env->var = (char **)mg_malloc_ctx(env->buflen * sizeof(char *), conn->ctx);
 	env->var = (char **)mg_malloc_ctx(env->buflen * sizeof(char *), conn->ctx);
+	if (env->var == NULL) {
+		mg_cry(conn,
+		       "%s: Not enough memory for environmental variables",
+		       __func__);
+		mg_free(env->buf);
+		return -1;
+	}
 
 
 	addenv(env, "SERVER_NAME=%s", conn->ctx->config[AUTHENTICATION_DOMAIN]);
 	addenv(env, "SERVER_NAME=%s", conn->ctx->config[AUTHENTICATION_DOMAIN]);
 	addenv(env, "SERVER_ROOT=%s", conn->ctx->config[DOCUMENT_ROOT]);
 	addenv(env, "SERVER_ROOT=%s", conn->ctx->config[DOCUMENT_ROOT]);
@@ -9096,6 +9126,8 @@ prepare_cgi_environment(struct mg_connection *conn,
 
 
 	env->var[env->varused] = NULL;
 	env->var[env->varused] = NULL;
 	env->buf[env->bufused] = '\0';
 	env->buf[env->bufused] = '\0';
+
+	return 0;
 }
 }
 
 
 
 
@@ -9120,7 +9152,12 @@ handle_cgi_request(struct mg_connection *conn, const char *prog)
 
 
 	buf = NULL;
 	buf = NULL;
 	buflen = 16384;
 	buflen = 16384;
-	prepare_cgi_environment(conn, prog, &blk);
+	i = prepare_cgi_environment(conn, prog, &blk);
+	if (i != 0) {
+		blk.buf = NULL;
+		blk.var = NULL;
+		goto done;
+	}
 
 
 	/* CGI must be executed in its own directory. 'dir' must point to the
 	/* CGI must be executed in its own directory. 'dir' must point to the
 	 * directory containing executable program, 'p' must point to the
 	 * directory containing executable program, 'p' must point to the
@@ -9996,16 +10033,15 @@ print_props(struct mg_connection *conn,
 }
 }
 
 
 
 
-static void
+static int
 print_dav_dir_entry(struct de *de, void *data)
 print_dav_dir_entry(struct de *de, void *data)
 {
 {
 	char href[PATH_MAX];
 	char href[PATH_MAX];
-	char href_encoded[PATH_MAX * 3 /* worst case */];
 	int truncated;
 	int truncated;
 
 
 	struct mg_connection *conn = (struct mg_connection *)data;
 	struct mg_connection *conn = (struct mg_connection *)data;
 	if (!de || !conn) {
 	if (!de || !conn) {
-		return;
+		return -1;
 	}
 	}
 	mg_snprintf(conn,
 	mg_snprintf(conn,
 	            &truncated,
 	            &truncated,
@@ -10016,9 +10052,20 @@ print_dav_dir_entry(struct de *de, void *data)
 	            de->file_name);
 	            de->file_name);
 
 
 	if (!truncated) {
 	if (!truncated) {
-		mg_url_encode(href, href_encoded, PATH_MAX * 3);
+		size_t href_encoded_size;
+		char *href_encoded;
+
+		href_encoded_size = PATH_MAX * 3; /* worst case */
+		href_encoded = mg_malloc(href_encoded_size);
+		if (href_encoded == NULL) {
+			return -1;
+		}
+		mg_url_encode(href, href_encoded, href_encoded_size);
 		print_props(conn, href_encoded, &de->file);
 		print_props(conn, href_encoded, &de->file);
+		mg_free(href_encoded);
 	}
 	}
+
+	return 0;
 }
 }
 
 
 
 
@@ -11396,6 +11443,7 @@ handle_request(struct mg_connection *conn)
 	void *callback_data = NULL;
 	void *callback_data = NULL;
 	mg_authorization_handler auth_handler = NULL;
 	mg_authorization_handler auth_handler = NULL;
 	void *auth_callback_data = NULL;
 	void *auth_callback_data = NULL;
+	int handler_type;
 	time_t curtime = time(NULL);
 	time_t curtime = time(NULL);
 	char date[64];
 	char date[64];
 
 
@@ -11536,11 +11584,15 @@ handle_request(struct mg_connection *conn)
 	 * protocol namespace or the websocket ws(s):// protocol namespace.
 	 * protocol namespace or the websocket ws(s):// protocol namespace.
 	 */
 	 */
 	is_websocket_request = is_websocket_protocol(conn);
 	is_websocket_request = is_websocket_protocol(conn);
-
+#if defined(USE_WEBSOCKET)
+	handler_type = is_websocket_request ? WEBSOCKET_HANDLER
+	                                    : REQUEST_HANDLER;
+#else
+	handler_type = REQUEST_HANDLER;
+#endif /* defined(USE_WEBSOCKET) */
 	/* 5.2. check if the request will be handled by a callback */
 	/* 5.2. check if the request will be handled by a callback */
 	if (get_request_handler(conn,
 	if (get_request_handler(conn,
-	                        is_websocket_request ? WEBSOCKET_HANDLER
-	                                             : REQUEST_HANDLER,
+	                        handler_type,
 	                        &callback_handler,
 	                        &callback_handler,
 	                        &subprotocols,
 	                        &subprotocols,
 	                        &ws_connect_handler,
 	                        &ws_connect_handler,
@@ -12257,6 +12309,8 @@ set_ports_option(struct mg_context *ctx)
 			mg_cry(fc(ctx),
 			mg_cry(fc(ctx),
 			       "cannot bind: address family not supported (entry %i)",
 			       "cannot bind: address family not supported (entry %i)",
 			       portsTotal);
 			       portsTotal);
+			closesocket(so.sock);
+			so.sock = INVALID_SOCKET;
 			continue;
 			continue;
 		}
 		}
 
 
@@ -13614,7 +13668,9 @@ close_connection(struct mg_connection *conn)
 void
 void
 mg_close_connection(struct mg_connection *conn)
 mg_close_connection(struct mg_connection *conn)
 {
 {
+#if defined(USE_WEBSOCKET)
 	struct mg_context *client_ctx = NULL;
 	struct mg_context *client_ctx = NULL;
+#endif /* defined(USE_WEBSOCKET) */
 
 
 	if (conn == NULL) {
 	if (conn == NULL) {
 		return;
 		return;
@@ -13641,9 +13697,7 @@ mg_close_connection(struct mg_connection *conn)
 			}
 			}
 		}
 		}
 	}
 	}
-#else
-	(void)client_ctx;
-#endif
+#endif /* defined(USE_WEBSOCKET) */
 
 
 	close_connection(conn);
 	close_connection(conn);
 
 
@@ -13653,15 +13707,21 @@ mg_close_connection(struct mg_connection *conn)
 	}
 	}
 #endif
 #endif
 
 
+#if defined(USE_WEBSOCKET)
 	if (client_ctx != NULL) {
 	if (client_ctx != NULL) {
 		/* free context */
 		/* free context */
 		mg_free(client_ctx->worker_threadids);
 		mg_free(client_ctx->worker_threadids);
 		mg_free(client_ctx);
 		mg_free(client_ctx);
 		(void)pthread_mutex_destroy(&conn->mutex);
 		(void)pthread_mutex_destroy(&conn->mutex);
 		mg_free(conn);
 		mg_free(conn);
-	} else if (conn->ctx->context_type == 0) { // Client
+	} else if (conn->ctx->context_type == 0) { /* Client */
+		mg_free(conn);
+	}
+#else
+	if (conn->ctx->context_type == 0) { /* Client */
 		mg_free(conn);
 		mg_free(conn);
 	}
 	}
+#endif /* defined(USE_WEBSOCKET) */
 }
 }
 
 
 
 
@@ -14943,7 +15003,6 @@ accept_new_connection(const struct socket *listener, struct mg_context *ctx)
 		sockaddr_to_string(src_addr, sizeof(src_addr), &so.rsa);
 		sockaddr_to_string(src_addr, sizeof(src_addr), &so.rsa);
 		mg_cry(fc(ctx), "%s: %s is not allowed to connect", __func__, src_addr);
 		mg_cry(fc(ctx), "%s: %s is not allowed to connect", __func__, src_addr);
 		closesocket(so.sock);
 		closesocket(so.sock);
-		so.sock = INVALID_SOCKET;
 	} else {
 	} else {
 		/* Put so socket structure into the queue */
 		/* Put so socket structure into the queue */
 		DEBUG_TRACE("Accepted socket %d", (int)so.sock);
 		DEBUG_TRACE("Accepted socket %d", (int)so.sock);
@@ -14998,6 +15057,7 @@ accept_new_connection(const struct socket *listener, struct mg_context *ctx)
 
 
 		set_blocking_mode(so.sock, 0);
 		set_blocking_mode(so.sock, 0);
 
 
+		so.in_use = 0;
 		produce_socket(ctx, &so);
 		produce_socket(ctx, &so);
 	}
 	}
 }
 }