Kaynağa Gözat

Fix mg_get_{system|context|connection}_info()

xtne6f 6 yıl önce
ebeveyn
işleme
63e59714ba
1 değiştirilmiş dosya ile 82 ekleme ve 245 silme
  1. 82 245
      src/civetweb.c

+ 82 - 245
src/civetweb.c

@@ -18917,22 +18917,30 @@ mg_check_feature(unsigned feature)
 }
 
 
-/* strcat with additional NULL check to avoid clang scan-build warning. */
-#define strcat0(a, b)                                                          \
-	{                                                                          \
-		if ((a != NULL) && (b != NULL)) {                                      \
-			strcat(a, b);                                                      \
-		}                                                                      \
+static size_t
+mg_str_append(char **dst, char *end, const char *src)
+{
+	size_t len = strlen(src);
+	if (*dst != end) {
+		/* Append src if enough space, or close dst. */
+		if ((size_t)(end - *dst) > len) {
+			strcpy(*dst, src);
+			*dst += len;
+		} else {
+			*dst = end;
+		}
 	}
+	return len;
+}
 
 
 /* Get system information. It can be printed or stored by the caller.
  * Return the size of available information. */
-static int
-mg_get_system_info_impl(char *buffer, int buflen)
+int
+mg_get_system_info(char *buffer, int buflen)
 {
-	char block[256];
-	int system_info_length = 0;
+	char *end, block[256];
+	size_t system_info_length = 0;
 
 #if defined(_WIN32)
 	const char *eol = "\r\n";
@@ -18940,20 +18948,15 @@ mg_get_system_info_impl(char *buffer, int buflen)
 	const char *eol = "\n";
 #endif
 
-	const char *eoobj = "}";
-	int reserved_len = (int)strlen(eoobj) + (int)strlen(eol);
-
 	if ((buffer == NULL) || (buflen < 1)) {
 		buflen = 0;
 	} else {
 		*buffer = 0;
 	}
+	end = buffer + buflen;
 
 	mg_snprintf(NULL, NULL, block, sizeof(block), "{%s", eol);
-	system_info_length += (int)strlen(block);
-	if (system_info_length < buflen) {
-		strcat0(buffer, block);
-	}
+	system_info_length += mg_str_append(&buffer, end, block);
 
 	/* Server version */
 	{
@@ -18965,10 +18968,7 @@ mg_get_system_info_impl(char *buffer, int buflen)
 		            "\"version\" : \"%s\",%s",
 		            version,
 		            eol);
-		system_info_length += (int)strlen(block);
-		if (system_info_length < buflen) {
-			strcat0(buffer, block);
-		}
+		system_info_length += mg_str_append(&buffer, end, block);
 	}
 
 	/* System info */
@@ -19002,10 +19002,7 @@ mg_get_system_info_impl(char *buffer, int buflen)
 		            (unsigned)dwMajorVersion,
 		            (unsigned)dwMinorVersion,
 		            eol);
-		system_info_length += (int)strlen(block);
-		if (system_info_length < buflen) {
-			strcat0(buffer, block);
-		}
+		system_info_length += mg_str_append(&buffer, end, block);
 
 		mg_snprintf(NULL,
 		            NULL,
@@ -19016,10 +19013,7 @@ mg_get_system_info_impl(char *buffer, int buflen)
 		            (unsigned)si.dwNumberOfProcessors,
 		            (unsigned)si.dwActiveProcessorMask,
 		            eol);
-		system_info_length += (int)strlen(block);
-		if (system_info_length < buflen) {
-			strcat0(buffer, block);
-		}
+		system_info_length += mg_str_append(&buffer, end, block);
 #else
 		struct utsname name;
 		memset(&name, 0, sizeof(name));
@@ -19035,10 +19029,7 @@ mg_get_system_info_impl(char *buffer, int buflen)
 		            name.release,
 		            name.machine,
 		            eol);
-		system_info_length += (int)strlen(block);
-		if (system_info_length < buflen) {
-			strcat0(buffer, block);
-		}
+		system_info_length += mg_str_append(&buffer, end, block);
 #endif
 	}
 
@@ -19063,10 +19054,7 @@ mg_get_system_info_impl(char *buffer, int buflen)
 		            mg_check_feature(MG_FEATURES_CACHE) ? " Cache" : "",
 		            mg_check_feature(MG_FEATURES_STATS) ? " Stats" : "",
 		            eol);
-		system_info_length += (int)strlen(block);
-		if (system_info_length < buflen) {
-			strcat0(buffer, block);
-		}
+		system_info_length += mg_str_append(&buffer, end, block);
 
 #if defined(USE_LUA)
 		mg_snprintf(NULL,
@@ -19077,10 +19065,7 @@ mg_get_system_info_impl(char *buffer, int buflen)
 		            (unsigned)LUA_VERSION_NUM,
 		            LUA_RELEASE,
 		            eol);
-		system_info_length += (int)strlen(block);
-		if (system_info_length < buflen) {
-			strcat0(buffer, block);
-		}
+		system_info_length += mg_str_append(&buffer, end, block);
 #endif
 #if defined(USE_DUKTAPE)
 		mg_snprintf(NULL,
@@ -19092,10 +19077,7 @@ mg_get_system_info_impl(char *buffer, int buflen)
 		            ((unsigned)DUK_VERSION / 100) % 100,
 		            (unsigned)DUK_VERSION % 100,
 		            eol);
-		system_info_length += (int)strlen(block);
-		if (system_info_length < buflen) {
-			strcat0(buffer, block);
-		}
+		system_info_length += mg_str_append(&buffer, end, block);
 #endif
 	}
 
@@ -19122,10 +19104,7 @@ mg_get_system_info_impl(char *buffer, int buflen)
 #endif
 #endif
 
-		system_info_length += (int)strlen(block);
-		if (system_info_length < buflen) {
-			strcat0(buffer, block);
-		}
+		system_info_length += mg_str_append(&buffer, end, block);
 	}
 
 
@@ -19141,10 +19120,7 @@ mg_get_system_info_impl(char *buffer, int buflen)
 		            (unsigned)_MSC_VER,
 		            (unsigned)_MSC_FULL_VER,
 		            eol);
-		system_info_length += (int)strlen(block);
-		if (system_info_length < buflen) {
-			strcat0(buffer, block);
-		}
+		system_info_length += mg_str_append(&buffer, end, block);
 #elif defined(__MINGW64__)
 		mg_snprintf(NULL,
 		            NULL,
@@ -19154,10 +19130,7 @@ mg_get_system_info_impl(char *buffer, int buflen)
 		            (unsigned)__MINGW64_VERSION_MAJOR,
 		            (unsigned)__MINGW64_VERSION_MINOR,
 		            eol);
-		system_info_length += (int)strlen(block);
-		if (system_info_length < buflen) {
-			strcat0(buffer, block);
-		}
+		system_info_length += mg_str_append(&buffer, end, block);
 		mg_snprintf(NULL,
 		            NULL,
 		            block,
@@ -19166,10 +19139,7 @@ mg_get_system_info_impl(char *buffer, int buflen)
 		            (unsigned)__MINGW32_MAJOR_VERSION,
 		            (unsigned)__MINGW32_MINOR_VERSION,
 		            eol);
-		system_info_length += (int)strlen(block);
-		if (system_info_length < buflen) {
-			strcat0(buffer, block);
-		}
+		system_info_length += mg_str_append(&buffer, end, block);
 #elif defined(__MINGW32__)
 		mg_snprintf(NULL,
 		            NULL,
@@ -19179,10 +19149,7 @@ mg_get_system_info_impl(char *buffer, int buflen)
 		            (unsigned)__MINGW32_MAJOR_VERSION,
 		            (unsigned)__MINGW32_MINOR_VERSION,
 		            eol);
-		system_info_length += (int)strlen(block);
-		if (system_info_length < buflen) {
-			strcat0(buffer, block);
-		}
+		system_info_length += mg_str_append(&buffer, end, block);
 #elif defined(__clang__)
 		mg_snprintf(NULL,
 		            NULL,
@@ -19194,10 +19161,7 @@ mg_get_system_info_impl(char *buffer, int buflen)
 		            __clang_patchlevel__,
 		            __clang_version__,
 		            eol);
-		system_info_length += (int)strlen(block);
-		if (system_info_length < buflen) {
-			strcat0(buffer, block);
-		}
+		system_info_length += mg_str_append(&buffer, end, block);
 #elif defined(__GNUC__)
 		mg_snprintf(NULL,
 		            NULL,
@@ -19208,10 +19172,7 @@ mg_get_system_info_impl(char *buffer, int buflen)
 		            (unsigned)__GNUC_MINOR__,
 		            (unsigned)__GNUC_PATCHLEVEL__,
 		            eol);
-		system_info_length += (int)strlen(block);
-		if (system_info_length < buflen) {
-			strcat0(buffer, block);
-		}
+		system_info_length += mg_str_append(&buffer, end, block);
 #elif defined(__INTEL_COMPILER)
 		mg_snprintf(NULL,
 		            NULL,
@@ -19220,10 +19181,7 @@ mg_get_system_info_impl(char *buffer, int buflen)
 		            "\"compiler\" : \"Intel C/C++: %u\",%s",
 		            (unsigned)__INTEL_COMPILER,
 		            eol);
-		system_info_length += (int)strlen(block);
-		if (system_info_length < buflen) {
-			strcat0(buffer, block);
-		}
+		system_info_length += mg_str_append(&buffer, end, block);
 #elif defined(__BORLANDC__)
 		mg_snprintf(NULL,
 		            NULL,
@@ -19232,10 +19190,7 @@ mg_get_system_info_impl(char *buffer, int buflen)
 		            "\"compiler\" : \"Borland C: 0x%x\",%s",
 		            (unsigned)__BORLANDC__,
 		            eol);
-		system_info_length += (int)strlen(block);
-		if (system_info_length < buflen) {
-			strcat0(buffer, block);
-		}
+		system_info_length += mg_str_append(&buffer, end, block);
 #elif defined(__SUNPRO_C)
 		mg_snprintf(NULL,
 		            NULL,
@@ -19244,10 +19199,7 @@ mg_get_system_info_impl(char *buffer, int buflen)
 		            "\"compiler\" : \"Solaris: 0x%x\",%s",
 		            (unsigned)__SUNPRO_C,
 		            eol);
-		system_info_length += (int)strlen(block);
-		if (system_info_length < buflen) {
-			strcat0(buffer, block);
-		}
+		system_info_length += mg_str_append(&buffer, end, block);
 #else
 		mg_snprintf(NULL,
 		            NULL,
@@ -19255,10 +19207,7 @@ mg_get_system_info_impl(char *buffer, int buflen)
 		            sizeof(block),
 		            "\"compiler\" : \"other\",%s",
 		            eol);
-		system_info_length += (int)strlen(block);
-		if (system_info_length < buflen) {
-			strcat0(buffer, block);
-		}
+		system_info_length += mg_str_append(&buffer, end, block);
 #endif
 	}
 
@@ -19285,34 +19234,25 @@ mg_get_system_info_impl(char *buffer, int buflen)
 		            (unsigned)sizeof(size_t),
 		            (unsigned)sizeof(time_t),
 		            eol);
-		system_info_length += (int)strlen(block);
-		if (system_info_length < buflen) {
-			strcat0(buffer, block);
-		}
+		system_info_length += mg_str_append(&buffer, end, block);
 	}
 
 	/* Terminate string */
-	if ((buflen > 0) && buffer && buffer[0]) {
-		if (system_info_length < buflen) {
-			strcat0(buffer, eoobj);
-			strcat0(buffer, eol);
-		}
-	}
-	system_info_length += reserved_len;
+	mg_snprintf(NULL, NULL, block, sizeof(block), "}%s", eol);
+	system_info_length += mg_str_append(&buffer, end, block);
 
-	return system_info_length;
+	return (int)system_info_length;
 }
 
 
-#if defined(USE_SERVER_STATS)
 /* Get context information. It can be printed or stored by the caller.
  * Return the size of available information. */
-static int
-mg_get_context_info_impl(const struct mg_context *ctx, char *buffer, int buflen)
-
+int
+mg_get_context_info(const struct mg_context *ctx, char *buffer, int buflen)
 {
-	char block[256];
-	int context_info_length = 0;
+#if defined(USE_SERVER_STATS)
+	char *end, block[256];
+	size_t context_info_length = 0;
 
 #if defined(_WIN32)
 	const char *eol = "\r\n";
@@ -19321,20 +19261,15 @@ mg_get_context_info_impl(const struct mg_context *ctx, char *buffer, int buflen)
 #endif
 	struct mg_memory_stat *ms = get_memory_stat((struct mg_context *)ctx);
 
-	const char *eoobj = "}";
-	int reserved_len = (int)strlen(eoobj) + (int)strlen(eol);
-
 	if ((buffer == NULL) || (buflen < 1)) {
 		buflen = 0;
 	} else {
 		*buffer = 0;
 	}
+	end = buffer + buflen;
 
 	mg_snprintf(NULL, NULL, block, sizeof(block), "{%s", eol);
-	context_info_length += (int)strlen(block);
-	if (context_info_length < buflen) {
-		strcat0(buffer, block);
-	}
+	context_info_length += mg_str_append(&buffer, end, block);
 
 	if (ms) { /* <-- should be always true */
 		/* Memory information */
@@ -19357,10 +19292,7 @@ mg_get_context_info_impl(const struct mg_context *ctx, char *buffer, int buflen)
 		            (ctx ? "," : ""),
 		            eol);
 
-		context_info_length += (int)strlen(block);
-		if (context_info_length + reserved_len < buflen) {
-			strcat0(buffer, block);
-		}
+		context_info_length += mg_str_append(&buffer, end, block);
 	}
 
 	if (ctx) {
@@ -19390,10 +19322,7 @@ mg_get_context_info_impl(const struct mg_context *ctx, char *buffer, int buflen)
 		            eol,
 		            eol);
 
-		context_info_length += (int)strlen(block);
-		if (context_info_length + reserved_len < buflen) {
-			strcat0(buffer, block);
-		}
+		context_info_length += mg_str_append(&buffer, end, block);
 
 		/* Requests information */
 		mg_snprintf(NULL,
@@ -19408,10 +19337,7 @@ mg_get_context_info_impl(const struct mg_context *ctx, char *buffer, int buflen)
 		            eol,
 		            eol);
 
-		context_info_length += (int)strlen(block);
-		if (context_info_length + reserved_len < buflen) {
-			strcat0(buffer, block);
-		}
+		context_info_length += mg_str_append(&buffer, end, block);
 
 		/* Data information */
 		mg_snprintf(NULL,
@@ -19429,10 +19355,7 @@ mg_get_context_info_impl(const struct mg_context *ctx, char *buffer, int buflen)
 		            eol,
 		            eol);
 
-		context_info_length += (int)strlen(block);
-		if (context_info_length + reserved_len < buflen) {
-			strcat0(buffer, block);
-		}
+		context_info_length += mg_str_append(&buffer, end, block);
 
 		/* Execution time information */
 		gmt_time_string(start_time_str,
@@ -19458,39 +19381,37 @@ mg_get_context_info_impl(const struct mg_context *ctx, char *buffer, int buflen)
 		            eol,
 		            eol);
 
-		context_info_length += (int)strlen(block);
-		if (context_info_length + reserved_len < buflen) {
-			strcat0(buffer, block);
-		}
+		context_info_length += mg_str_append(&buffer, end, block);
 	}
 
 	/* Terminate string */
-	if ((buflen > 0) && buffer && buffer[0]) {
-		if (context_info_length < buflen) {
-			strcat0(buffer, eoobj);
-			strcat0(buffer, eol);
-		}
-	}
-	context_info_length += reserved_len;
+	mg_snprintf(NULL, NULL, block, sizeof(block), "}%s", eol);
+	context_info_length += mg_str_append(&buffer, end, block);
 
-	return context_info_length;
-}
+	return (int)context_info_length;
+#else
+	(void)ctx;
+	if ((buffer != NULL) && (buflen > 0)) {
+		*buffer = 0;
+	}
+	return 0;
 #endif
+}
 
 
 #if defined(MG_EXPERIMENTAL_INTERFACES)
 /* Get connection information. It can be printed or stored by the caller.
  * Return the size of available information. */
-static int
-mg_get_connection_info_impl(const struct mg_context *ctx,
-                            int idx,
-                            char *buffer,
-                            int buflen)
+int
+mg_get_connection_info(const struct mg_context *ctx,
+                       int idx,
+                       char *buffer,
+                       int buflen)
 {
 	const struct mg_connection *conn;
 	const struct mg_request_info *ri;
-	char block[256];
-	int connection_info_length = 0;
+	char *end, block[256];
+	size_t connection_info_length = 0;
 	int state = 0;
 	const char *state_str = "unknown";
 
@@ -19500,14 +19421,12 @@ mg_get_connection_info_impl(const struct mg_context *ctx,
 	const char *eol = "\n";
 #endif
 
-	const char *eoobj = "}";
-	int reserved_len = (int)strlen(eoobj) + (int)strlen(eol);
-
 	if ((buffer == NULL) || (buflen < 1)) {
 		buflen = 0;
 	} else {
 		*buffer = 0;
 	}
+	end = buffer + buflen;
 
 	if ((ctx == NULL) || (idx < 0)) {
 		/* Parameter error */
@@ -19525,10 +19444,7 @@ mg_get_connection_info_impl(const struct mg_context *ctx,
 
 	/* Initialize output string */
 	mg_snprintf(NULL, NULL, block, sizeof(block), "{%s", eol);
-	connection_info_length += (int)strlen(block);
-	if (connection_info_length < buflen) {
-		strcat0(buffer, block);
-	}
+	connection_info_length += mg_str_append(&buffer, end, block);
 
 	/* Init variables */
 	ri = &(conn->request_info);
@@ -19598,10 +19514,7 @@ mg_get_connection_info_impl(const struct mg_context *ctx,
 		            eol,
 		            eol);
 
-		connection_info_length += (int)strlen(block);
-		if (connection_info_length + reserved_len < buflen) {
-			strcat0(buffer, block);
-		}
+		connection_info_length += mg_str_append(&buffer, end, block);
 	}
 
 	/* Request info */
@@ -19626,10 +19539,7 @@ mg_get_connection_info_impl(const struct mg_context *ctx,
 		            eol,
 		            eol);
 
-		connection_info_length += (int)strlen(block);
-		if (connection_info_length + reserved_len < buflen) {
-			strcat0(buffer, block);
-		}
+		connection_info_length += mg_str_append(&buffer, end, block);
 	}
 
 	/* Execution time information */
@@ -19662,10 +19572,7 @@ mg_get_connection_info_impl(const struct mg_context *ctx,
 		            eol,
 		            eol);
 
-		connection_info_length += (int)strlen(block);
-		if (connection_info_length + reserved_len < buflen) {
-			strcat0(buffer, block);
-		}
+		connection_info_length += mg_str_append(&buffer, end, block);
 	}
 
 	/* Remote user name */
@@ -19682,10 +19589,7 @@ mg_get_connection_info_impl(const struct mg_context *ctx,
 		            eol,
 		            eol);
 
-		connection_info_length += (int)strlen(block);
-		if (connection_info_length + reserved_len < buflen) {
-			strcat0(buffer, block);
-		}
+		connection_info_length += mg_str_append(&buffer, end, block);
 	}
 
 	/* Data block */
@@ -19705,10 +19609,7 @@ mg_get_connection_info_impl(const struct mg_context *ctx,
 		            eol,
 		            eol);
 
-		connection_info_length += (int)strlen(block);
-		if (connection_info_length + reserved_len < buflen) {
-			strcat0(buffer, block);
-		}
+		connection_info_length += mg_str_append(&buffer, end, block);
 	}
 
 	/* State */
@@ -19720,77 +19621,13 @@ mg_get_connection_info_impl(const struct mg_context *ctx,
 	            state_str,
 	            eol);
 
-	connection_info_length += (int)strlen(block);
-	if (connection_info_length + reserved_len < buflen) {
-		strcat0(buffer, block);
-	}
+	connection_info_length += mg_str_append(&buffer, end, block);
 
 	/* Terminate string */
-	if ((buflen > 0) && buffer && buffer[0]) {
-		if (connection_info_length < buflen) {
-			strcat0(buffer, eoobj);
-			strcat0(buffer, eol);
-		}
-	}
-	connection_info_length += reserved_len;
-
-	return connection_info_length;
-}
-#endif
-
-
-/* Get system information. It can be printed or stored by the caller.
- * Return the size of available information. */
-int
-mg_get_system_info(char *buffer, int buflen)
-{
-	if ((buffer == NULL) || (buflen < 1)) {
-		return mg_get_system_info_impl(NULL, 0);
-	} else {
-		/* Reset buffer, so we can always use strcat. */
-		buffer[0] = 0;
-		return mg_get_system_info_impl(buffer, buflen);
-	}
-}
-
+	mg_snprintf(NULL, NULL, block, sizeof(block), "}%s", eol);
+	connection_info_length += mg_str_append(&buffer, end, block);
 
-/* Get context information. It can be printed or stored by the caller.
- * Return the size of available information. */
-int
-mg_get_context_info(const struct mg_context *ctx, char *buffer, int buflen)
-{
-#if defined(USE_SERVER_STATS)
-	if ((buffer == NULL) || (buflen < 1)) {
-		return mg_get_context_info_impl(ctx, NULL, 0);
-	} else {
-		/* Reset buffer, so we can always use strcat. */
-		buffer[0] = 0;
-		return mg_get_context_info_impl(ctx, buffer, buflen);
-	}
-#else
-	(void)ctx;
-	if ((buffer != NULL) && (buflen > 0)) {
-		buffer[0] = 0;
-	}
-	return 0;
-#endif
-}
-
-
-#if defined(MG_EXPERIMENTAL_INTERFACES)
-int
-mg_get_connection_info(const struct mg_context *ctx,
-                       int idx,
-                       char *buffer,
-                       int buflen)
-{
-	if ((buffer == NULL) || (buflen < 1)) {
-		return mg_get_connection_info_impl(ctx, idx, NULL, 0);
-	} else {
-		/* Reset buffer, so we can always use strcat. */
-		buffer[0] = 0;
-		return mg_get_connection_info_impl(ctx, idx, buffer, buflen);
-	}
+	return (int)connection_info_length;
 }
 #endif