浏览代码

Fixes warnings from static source code analysis

bel2125 3 年之前
父节点
当前提交
4cbb278dcf
共有 4 个文件被更改,包括 73 次插入32 次删除
  1. 2 0
      include/civetweb.h
  2. 37 18
      src/civetweb.c
  3. 15 8
      src/http2.inl
  4. 19 6
      src/response.inl

+ 2 - 0
include/civetweb.h

@@ -1521,6 +1521,7 @@ CIVETWEB_API int mg_get_response(struct mg_connection *conn,
  *  -1:    parameter error
  *  -2:    invalid connection type
  *  -3:    invalid connection status
+ *  -4:    network error (only if built with NO_RESPONSE_BUFFERING)
  */
 CIVETWEB_API int mg_response_header_start(struct mg_connection *conn,
                                           int status);
@@ -1573,6 +1574,7 @@ CIVETWEB_API int mg_response_header_add_lines(struct mg_connection *conn,
  *  -1:    parameter error
  *  -2:    invalid connection type
  *  -3:    invalid connection status
+ *  -4:    sending failed (network error)
  */
 CIVETWEB_API int mg_response_header_send(struct mg_connection *conn);
 

+ 37 - 18
src/civetweb.c

@@ -10771,6 +10771,10 @@ static const struct mg_http_method_info http_methods[] = {
 };
 
 
+/* All method names */
+static char *all_methods = NULL; /* Built by mg_init_library */
+
+
 static const struct mg_http_method_info *
 get_http_method_info(const char *method)
 {
@@ -12528,10 +12532,7 @@ handle_ssi_file_request(struct mg_connection *conn,
 static void
 send_options(struct mg_connection *conn)
 {
-	int i;
-	char methods[256] = {0};
-
-	if (!conn) {
+	if (!conn || !all_methods) {
 		return;
 	}
 
@@ -12542,18 +12543,9 @@ send_options(struct mg_connection *conn)
 	mg_response_header_start(conn, 200);
 	mg_response_header_add(conn, "Content-Type", "text/html", -1);
 
-	for (i = 0; http_methods[i].name != NULL; i++) {
-		if (i > 0) {
-			strcat(methods, ", ");
-			strcat(methods, http_methods[i].name);
-		} else {
-			strcpy(methods, http_methods[i].name);
-		}
-	}
-
 	if (conn->protocol_type == PROTOCOL_TYPE_HTTP1) {
 		/* Use the same as before */
-		mg_response_header_add(conn, "Allow", methods, -1);
+		mg_response_header_add(conn, "Allow", all_methods, -1);
 		mg_response_header_add(conn, "DAV", "1", -1);
 	} else {
 		/* TODO: Check this later for HTTP/2 */
@@ -12710,6 +12702,7 @@ handle_propfind(struct mg_connection *conn,
 static void
 dav_lock_file(struct mg_connection *conn, const char *path)
 {
+	/* internal function - therefore conn is assumed to be valid */
 	char link_buf[UTF8_PATH_MAX * 2]; /* Path + server root */
 	uint64_t new_locktime;
 	int lock_index = -1;
@@ -12718,7 +12711,7 @@ dav_lock_file(struct mg_connection *conn, const char *path)
 	    (uint64_t)(LOCK_DURATION_S) * (uint64_t)1000000000;
 	struct twebdav_lock *dav_lock = conn->phys_ctx->webdav_lock;
 
-	if (!conn || !path || !conn->dom_ctx || !conn->request_info.remote_user) {
+	if (!path || !conn->dom_ctx || !conn->request_info.remote_user) {
 		return;
 	}
 	mg_get_request_link(conn, link_buf, sizeof(link_buf));
@@ -22095,6 +22088,8 @@ mg_init_library(unsigned features)
 	mg_global_lock();
 
 	if (mg_init_library_called <= 0) {
+		int i, len;
+
 #if defined(_WIN32)
 		int file_mutex_init = 1;
 		int wsa = 1;
@@ -22147,13 +22142,35 @@ mg_init_library(unsigned features)
 #if defined(USE_LUA)
 		lua_init_optional_libraries();
 #endif
-	}
 
-	mg_global_unlock();
+		len = 1;
+		for (i = 0; http_methods[i].name != NULL; i++) {
+			size_t sl = strlen(http_methods[i].name);
+			len += (int)sl;
+			if (i > 0) {
+				len += 2;
+			}
+		}
+		all_methods = mg_malloc(len);
+		if (!all_methods) {
+			/* Must never happen */
+			return 0;
+		}
+		all_methods[0] = 0;
+		for (i = 0; http_methods[i].name != NULL; i++) {
+			if (i > 0) {
+				strcat(all_methods, ", ");
+				strcat(all_methods, http_methods[i].name);
+			} else {
+				strcpy(all_methods, http_methods[i].name);
+			}
+		}
+	}
 
 #if (defined(OPENSSL_API_1_0) || defined(OPENSSL_API_1_1)                      \
      || defined(OPENSSL_API_3_0))                                              \
     && !defined(NO_SSL)
+
 	if (features_to_init & MG_FEATURES_SSL) {
 		if (!mg_openssl_initialized) {
 			char ebuf[128];
@@ -22168,9 +22185,9 @@ mg_init_library(unsigned features)
 			/* ssl already initialized */
 		}
 	}
+
 #endif
 
-	mg_global_lock();
 	if (mg_init_library_called <= 0) {
 		mg_init_library_called = 1;
 	} else {
@@ -22213,6 +22230,8 @@ mg_exit_library(void)
 #if defined(USE_LUA)
 		lua_exit_optional_libraries();
 #endif
+		mg_free(all_methods);
+		all_methods = NULL;
 
 		mg_global_unlock();
 		(void)pthread_mutex_destroy(&global_lock_mutex);

+ 15 - 8
src/http2.inl

@@ -960,7 +960,7 @@ http2_send_response_headers(struct mg_connection *conn)
 	uint16_t header_len = 0;
 	int has_date = 0;
 	int has_connection_header = 0;
-	int i;
+	int i, ok;
 
 	if ((conn->status_code < 100) || (conn->status_code > 999)) {
 		/* Invalid status: Set status to "Internal Server Error" */
@@ -1069,16 +1069,23 @@ http2_send_response_headers(struct mg_connection *conn)
 	http2_header_frame[8] = (conn->http2.stream_id & 0xFFu);
 
 	/* Send header frame */
-	mg_xwrite(conn, http2_header_frame, 9);
-	mg_xwrite(conn, header_bin, header_len);
-
-	DEBUG_TRACE("HTTP2 response header sent: stream %u", conn->http2.stream_id);
-
+	ok = 1;
+	if (mg_xwrite(conn, http2_header_frame, 9) != 9) {
+		ok = 0;
+	} else if (mg_xwrite(conn, header_bin, header_len) != header_len) {
+		ok = 0;
+	}
+	if (ok) {
+		DEBUG_TRACE("HTTP2 response header sent: stream %u",
+		            conn->http2.stream_id);
+	} else {
+		DEBUG_TRACE("HTTP2 response header sending error: stream %u",
+		            conn->http2.stream_id);
+	}
 
 	(void)has_connection_header; /* ignore for the moment */
 
-
-	return 42; /* TODO */
+	return ok;
 }
 
 

+ 19 - 6
src/response.inl

@@ -37,7 +37,7 @@ free_buffered_response_header_list(struct mg_connection *conn)
 
 
 /* Send first line of HTTP/1.x response */
-static void
+static int
 send_http1_response_status_line(struct mg_connection *conn)
 {
 	const char *status_txt;
@@ -55,7 +55,13 @@ send_http1_response_status_line(struct mg_connection *conn)
 	/* mg_get_response_code_text will never return NULL */
 	status_txt = mg_get_response_code_text(conn, conn->status_code);
 
-	mg_printf(conn, "HTTP/%s %i %s\r\n", http_version, status_code, status_txt);
+	if (mg_printf(
+	        conn, "HTTP/%s %i %s\r\n", http_version, status_code, status_txt)
+	    < 10) {
+		/* Network sending failed */
+		return 0;
+	}
+	return 1;
 }
 
 
@@ -68,10 +74,12 @@ send_http1_response_status_line(struct mg_connection *conn)
  *  -1:    parameter error
  *  -2:    invalid connection type
  *  -3:    invalid connection status
+ *  -4:    network error (only if built with NO_RESPONSE_BUFFERING)
  */
 int
 mg_response_header_start(struct mg_connection *conn, int status)
 {
+	int ret = 0;
 	if ((conn == NULL) || (status < 100) || (status > 999)) {
 		/* Parameter error */
 		return -1;
@@ -93,11 +101,13 @@ mg_response_header_start(struct mg_connection *conn, int status)
 #if !defined(NO_RESPONSE_BUFFERING)
 	free_buffered_response_header_list(conn);
 #else
-	send_http1_response_status_line(conn);
+	if (!send_http1_response_status_line(conn)) {
+		ret = -4;
+	};
 	conn->request_state = 1; /* Reset from 10 to 1 */
 #endif
 
-	return 0;
+	return ret;
 }
 
 
@@ -254,6 +264,7 @@ static int http2_send_response_headers(struct mg_connection *conn);
  *  -1:    parameter error
  *  -2:    invalid connection type
  *  -3:    invalid connection status
+ *  -4:    network send failed
  */
 int
 mg_response_header_send(struct mg_connection *conn)
@@ -285,12 +296,14 @@ mg_response_header_send(struct mg_connection *conn)
 #if defined(USE_HTTP2)
 	if (conn->protocol_type == PROTOCOL_TYPE_HTTP2) {
 		int ret = http2_send_response_headers(conn);
-		return ret ? 0 : 0; /* todo */
+		return (ret ? 0 : -4);
 	}
 #endif
 
 	/* Send */
-	send_http1_response_status_line(conn);
+	if (!send_http1_response_status_line(conn)) {
+		return -4;
+	};
 	for (i = 0; i < conn->response_info.num_headers; i++) {
 		mg_printf(conn,
 		          "%s: %s\r\n",