Przeglądaj źródła

Rewrite string handling (Step 5/?)

bel 10 lat temu
rodzic
commit
fb48aaa354
2 zmienionych plików z 173 dodań i 63 usunięć
  1. 172 63
      src/civetweb.c
  2. 1 0
      src/mod_lua.inl

+ 172 - 63
src/civetweb.c

@@ -681,12 +681,14 @@ static __inline void mg_free(void *a) { free(a); }
 
 
 static void mg_vsnprintf(const struct mg_connection *conn,
+                         int *truncated,
                          char *buf,
                          size_t buflen,
                          const char *fmt,
                          va_list ap);
 
 static void mg_snprintf(const struct mg_connection *conn,
+                        int *truncated,
                         char *buf,
                         size_t buflen,
                         PRINTF_FORMAT_STRING(const char *fmt),
@@ -1079,11 +1081,11 @@ struct mg_connection {
 	char *buf;                /* Buffer for received data */
 	char *path_info;          /* PATH_INFO part of the URL */
 
-	int must_close;           /* 1 if connection must be closed */
-	int in_error_handler;     /* 1 if in handler for user defined error
-	                           * pages */
-	int internal_error;       /* 1 if an error occured while processing the
-	                           * request */
+	int must_close;       /* 1 if connection must be closed */
+	int in_error_handler; /* 1 if in handler for user defined error
+	                       * pages */
+	int internal_error;   /* 1 if an error occured while processing the
+	                       * request */
 
 	int buf_size;                /* Buffer size */
 	int request_len;             /* Size of the request + headers in a buffer */
@@ -1096,7 +1098,7 @@ struct mg_connection {
 	pthread_mutex_t mutex;       /* Used by mg_(un)lock_connection to ensure
 	                              * atomic transmissions for websockets */
 #if defined(USE_LUA) && defined(USE_WEBSOCKET)
-	void *lua_websocket_state;   /* Lua_State for a websocket connection */
+	void *lua_websocket_state; /* Lua_State for a websocket connection */
 #endif
 };
 
@@ -1177,8 +1179,8 @@ static void mg_set_thread_name(const char *name)
 {
 	char threadName[16 + 1]; /* 16 = Max. thread length in Linux/OSX/.. */
 
-	mg_snprintf(NULL, threadName, sizeof(threadName), "civetweb-%s", name);
-	threadName[sizeof(threadName) - 1] = 0;
+	mg_snprintf(
+	    NULL, NULL, threadName, sizeof(threadName), "civetweb-%s", name);
 
 #if defined(_WIN32)
 #if defined(_MSC_VER)
@@ -1359,6 +1361,7 @@ static const char *mg_strcasestr(const char *big_str, const char *small_str)
 /* Return null terminated string of given maximum length.
  * Report errors if length is exceeded. */
 static void mg_vsnprintf(const struct mg_connection *conn,
+                         int *truncated,
                          char *buf,
                          size_t buflen,
                          const char *fmt,
@@ -1384,9 +1387,13 @@ static void mg_vsnprintf(const struct mg_connection *conn,
 #pragma clang diagnostic pop
 #endif
 
-	if (!ok) {
-		if (conn) {
-			conn->internal_error = 1;
+	if (ok) {
+		if (truncated) {
+			*truncated = 0;
+		}
+	} else {
+		if (truncated) {
+			*truncated = 1;
 		}
 		mg_cry(conn,
 		       "truncating vsnprintf buffer: [%.*s]",
@@ -1398,6 +1405,7 @@ static void mg_vsnprintf(const struct mg_connection *conn,
 }
 
 static void mg_snprintf(const struct mg_connection *conn,
+                        int *truncated,
                         char *buf,
                         size_t buflen,
                         const char *fmt,
@@ -1406,7 +1414,7 @@ static void mg_snprintf(const struct mg_connection *conn,
 	va_list ap;
 
 	va_start(ap, fmt);
-	mg_vsnprintf(conn, buf, buflen, fmt, ap);
+	mg_vsnprintf(conn, truncated, buf, buflen, fmt, ap);
 	va_end(ap);
 }
 
@@ -1769,7 +1777,7 @@ static int should_keep_alive(const struct mg_connection *conn)
 		const char *http_version = conn->request_info.http_version;
 		const char *header = mg_get_header(conn, "Connection");
 		if (conn->must_close || conn->internal_error ||
-            conn->status_code == 401 ||
+		    conn->status_code == 401 ||
 		    mg_strcasecmp(conn->ctx->config[ENABLE_KEEP_ALIVE], "yes") != 0 ||
 		    (header != NULL && mg_strcasecmp(header, "keep-alive") != 0) ||
 		    (header == NULL && http_version &&
@@ -1988,7 +1996,7 @@ send_http_error(struct mg_connection *conn, int status, const char *fmt, ...)
 {
 	char buf[MG_BUF_LEN];
 	va_list ap;
-	int len, i, page_handler_found, scope;
+	int len, i, page_handler_found, scope, truncated;
 	char date[64];
 	time_t curtime = time(NULL);
 	const char *error_handler = NULL;
@@ -2014,6 +2022,7 @@ send_http_error(struct mg_connection *conn, int status, const char *fmt, ...)
 					switch (scope) {
 					case 1: /* Handler for specific error, e.g. 404 error */
 						mg_snprintf(conn,
+						            &truncated,
 						            buf,
 						            sizeof(buf) - 32,
 						            "%serror%03u.",
@@ -2023,6 +2032,7 @@ send_http_error(struct mg_connection *conn, int status, const char *fmt, ...)
 					case 2: /* Handler for error group, e.g., 5xx error handler
 					         * for all server errors (500-599) */
 						mg_snprintf(conn,
+						            &truncated,
 						            buf,
 						            sizeof(buf) - 32,
 						            "%serror%01uxx.",
@@ -2031,6 +2041,7 @@ send_http_error(struct mg_connection *conn, int status, const char *fmt, ...)
 						break;
 					default: /* Handler for all errors */
 						mg_snprintf(conn,
+						            &truncated,
 						            buf,
 						            sizeof(buf) - 32,
 						            "%serror.",
@@ -2041,6 +2052,8 @@ send_http_error(struct mg_connection *conn, int status, const char *fmt, ...)
 					/* String truncation in buf may only occur if error_handler
 					 * is too long. This string is from the config, not from a
 					 * client. */
+					(void)truncated;
+
 					len = (int)strlen(buf);
 
 					tstr = strchr(error_page_file_ext, '.');
@@ -2084,7 +2097,7 @@ send_http_error(struct mg_connection *conn, int status, const char *fmt, ...)
 
 			if (fmt != NULL) {
 				va_start(ap, fmt);
-				mg_vsnprintf(conn, buf, sizeof(buf), fmt, ap);
+				mg_vsnprintf(conn, NULL, buf, sizeof(buf), fmt, ap);
 				va_end(ap);
 				mg_write(conn, buf, strlen(buf));
 				DEBUG_TRACE("Error %i - [%s]", status, buf);
@@ -2676,6 +2689,7 @@ static pid_t spawn_process(struct mg_connection *conn,
 	HANDLE me;
 	char *p, *interp, full_interp[PATH_MAX], full_dir[PATH_MAX],
 	    cmdline[PATH_MAX], buf[PATH_MAX];
+	int truncated;
 	struct file file = STRUCT_FILE_INITIALIZER;
 	STARTUPINFOA si;
 	PROCESS_INFORMATION pi = {0};
@@ -2711,9 +2725,13 @@ static pid_t spawn_process(struct mg_connection *conn,
 		buf[0] = buf[1] = '\0';
 
 		/* Read the first line of the script into the buffer */
-		mg_snprintf(conn, cmdline, sizeof(cmdline), "%s%c%s", dir, '/', prog);
+		mg_snprintf(
+		    conn, &truncated, cmdline, sizeof(cmdline), "%s/%s", dir, prog);
 
-		/* TODO(high): kick client on buffer overflow */
+		if (truncated) {
+			pi.hProcess = (pid_t)-1;
+			goto spawn_cleanup;
+		}
 
 		if (mg_fopen(conn, cmdline, "r", &file)) {
 			p = (char *)file.membuf;
@@ -2738,6 +2756,7 @@ static pid_t spawn_process(struct mg_connection *conn,
 
 	if (interp[0] != '\0') {
 		mg_snprintf(conn,
+		            &truncated,
 		            cmdline,
 		            sizeof(cmdline),
 		            "\"%s\" \"%s\\%s\"",
@@ -2745,15 +2764,19 @@ static pid_t spawn_process(struct mg_connection *conn,
 		            full_dir,
 		            prog);
 	} else {
-		mg_snprintf(
-		    conn, cmdline, sizeof(cmdline), "\"%s\\%s\"", full_dir, prog);
+		mg_snprintf(conn,
+		            &truncated,
+		            cmdline,
+		            sizeof(cmdline),
+		            "\"%s\\%s\"",
+		            full_dir,
+		            prog);
 	}
 
-	/* TODO(high): kick client on buffer overflow */
-    /* if (conn->internal_error) { */
-    /* pi.hProcess = (pid_t)-1; */
-	/* goto spawn_cleanup; */
-    /* } */
+	if (truncated) {
+		pi.hProcess = (pid_t)-1;
+		goto spawn_cleanup;
+	}
 
 	DEBUG_TRACE("Running [%s]", cmdline);
 	if (CreateProcessA(NULL,
@@ -3783,6 +3806,7 @@ interpret_uri(struct mg_connection *conn,   /* in: request */
 		int match_len;
 		char gz_path[PATH_MAX];
 		char const *accept_encoding;
+		int truncated;
 #endif
 
 		memset(filep, 0, sizeof(*filep));
@@ -3813,14 +3837,23 @@ interpret_uri(struct mg_connection *conn,   /* in: request */
 		/* Using buf_len - 1 because memmove() for PATH_INFO may shift part
 		 * of the path one byte on the right.
 		 * If document_root is NULL, leave the file empty. */
-		mg_snprintf(conn, filename, filename_buf_len - 1, "%s%s", root, uri);
+		mg_snprintf(conn,
+		            &truncated,
+		            filename,
+		            filename_buf_len - 1,
+		            "%s%s",
+		            root,
+		            uri);
 
-		/* TODO(high): kick client on buffer overflow */
+		if (truncated) {
+			goto interpret_cleanup;
+		}
 
 		rewrite = conn->ctx->config[REWRITE];
 		while ((rewrite = next_option(rewrite, &a, &b)) != NULL) {
 			if ((match_len = match_prefix(a.ptr, a.len, uri)) > 0) {
 				mg_snprintf(conn,
+				            &truncated,
 				            filename,
 				            filename_buf_len - 1,
 				            "%.*s%s",
@@ -3831,7 +3864,9 @@ interpret_uri(struct mg_connection *conn,   /* in: request */
 			}
 		}
 
-		/* TODO(high): kick client on buffer overflow */
+		if (truncated) {
+			goto interpret_cleanup;
+		}
 
 		/* Local file path and name, corresponding to requested URI
 		 * is now stored in "filename" variable. */
@@ -3876,9 +3911,16 @@ interpret_uri(struct mg_connection *conn,   /* in: request */
 		if ((accept_encoding = mg_get_header(conn, "Accept-Encoding")) !=
 		    NULL) {
 			if (strstr(accept_encoding, "gzip") != NULL) {
-				mg_snprintf(conn, gz_path, sizeof(gz_path), "%s.gz", filename);
-
-				/* TODO(high): kick client on buffer overflow */
+				mg_snprintf(conn,
+				            &truncated,
+				            gz_path,
+				            sizeof(gz_path),
+				            "%s.gz",
+				            filename);
+
+				if (truncated) {
+					goto interpret_cleanup;
+				}
 
 				if (mg_stat(conn, gz_path, filep)) {
 					if (filep) {
@@ -3928,6 +3970,14 @@ interpret_uri(struct mg_connection *conn,   /* in: request */
 		}
 #endif
 	}
+	return;
+
+/* Reset all outputs */
+interpret_cleanup:
+	memset(filep, 0, sizeof(*filep));
+	*filename = 0;
+	*is_found = 0;
+	*is_script_ressource = 0;
 }
 
 /* Check whether full request is buffered. Return:
@@ -4282,6 +4332,7 @@ open_auth_file(struct mg_connection *conn, const char *path, struct file *filep)
 		char name[PATH_MAX];
 		const char *p, *e, *gpass = conn->ctx->config[GLOBAL_PASSWORDS_FILE];
 		struct file file = STRUCT_FILE_INITIALIZER;
+		int truncated;
 
 		if (gpass != NULL) {
 			/* Use global passwords file */
@@ -4291,21 +4342,18 @@ open_auth_file(struct mg_connection *conn, const char *path, struct file *filep)
 #endif
 			}
 			/* Important: using local struct file to test path for is_directory
-			 * flag.
-			 * If filep is used, mg_stat() makes it appear as if auth file was
-			 * opened. */
+			 * flag. If filep is used, mg_stat() makes it appear as if auth file
+			 * was opened. */
 		} else if (mg_stat(conn, path, &file) && file.is_directory) {
 			mg_snprintf(conn,
+			            &truncated,
 			            name,
 			            sizeof(name),
-			            "%s%c%s",
+			            "%s/%s",
 			            path,
-			            '/',
 			            PASSWORDS_FILE_NAME);
 
-			/* TODO(high): kick client on buffer overflow */
-
-			if (!mg_fopen(conn, name, "r", filep)) {
+			if (truncated || !mg_fopen(conn, name, "r", filep)) {
 #ifdef DEBUG
 				mg_cry(conn, "fopen(%s): %s", name, strerror(ERRNO));
 #endif
@@ -4318,6 +4366,7 @@ open_auth_file(struct mg_connection *conn, const char *path, struct file *filep)
 				}
 			}
 			mg_snprintf(conn,
+			            &truncated,
 			            name,
 			            sizeof(name),
 			            "%.*s%c%s",
@@ -4326,9 +4375,7 @@ open_auth_file(struct mg_connection *conn, const char *path, struct file *filep)
 			            '/',
 			            PASSWORDS_FILE_NAME);
 
-			/* TODO(high): kick client on buffer overflow */
-
-			if (!mg_fopen(conn, name, "r", filep)) {
+			if (truncated || !mg_fopen(conn, name, "r", filep)) {
 #ifdef DEBUG
 				mg_cry(conn, "fopen(%s): %s", name, strerror(ERRNO));
 #endif
@@ -4605,7 +4652,7 @@ static int check_authorization(struct mg_connection *conn, const char *path)
 	struct vec uri_vec, filename_vec;
 	const char *list;
 	struct file file = STRUCT_FILE_INITIALIZER;
-	int authorized = 1;
+	int authorized = 1, truncated;
 
 	if (!conn || !conn->ctx) {
 		return 0;
@@ -4615,15 +4662,14 @@ static int check_authorization(struct mg_connection *conn, const char *path)
 	while ((list = next_option(list, &uri_vec, &filename_vec)) != NULL) {
 		if (!memcmp(conn->request_info.uri, uri_vec.ptr, uri_vec.len)) {
 			mg_snprintf(conn,
+			            &truncated,
 			            fname,
 			            sizeof(fname),
 			            "%.*s",
 			            (int)filename_vec.len,
 			            filename_vec.ptr);
 
-			/* TODO(high): kick client on buffer overflow */
-
-			if (!mg_fopen(conn, fname, "r", &file)) {
+			if (truncated || !mg_fopen(conn, fname, "r", &file)) {
 				mg_cry(conn,
 				       "%s: cannot open %s: %s",
 				       __func__,
@@ -4942,18 +4988,21 @@ static void print_dir_entry(struct de *de)
 			mg_snprintf(de->conn, size, sizeof(size), "%d", (int)de->file.size);
 		} else if (de->file.size < 0x100000) {
 			mg_snprintf(de->conn,
+			            NULL,
 			            size,
 			            sizeof(size),
 			            "%.1fk",
 			            (double)de->file.size / 1024.0);
 		} else if (de->file.size < 0x40000000) {
 			mg_snprintf(de->conn,
+			            NULL,
 			            size,
 			            sizeof(size),
 			            "%.1fM",
 			            (double)de->file.size / 1048576);
 		} else {
 			mg_snprintf(de->conn,
+			            NULL,
 			            size,
 			            sizeof(size),
 			            "%.1fG",
@@ -4961,7 +5010,8 @@ static void print_dir_entry(struct de *de)
 		}
 	}
 
-	/* Note: mg_snprintf will not cause a buffer overflow above. */
+	/* Note: mg_snprintf will not cause a buffer overflow above.
+	 * So, string truncation checks are not required here. */
 
 	tm = localtime(&de->file.last_modified);
 	if (tm != NULL) {
@@ -5846,6 +5896,7 @@ static char *addenv(struct cgi_env_block *block,
 static char *addenv(struct cgi_env_block *block, const char *fmt, ...)
 {
 	unsigned int n, space;
+	int truncated;
 	char *added;
 	va_list ap;
 
@@ -5864,10 +5915,14 @@ static char *addenv(struct cgi_env_block *block, const char *fmt, ...)
 
 	/* Copy VARIABLE=VALUE\0 string into the free space */
 	va_start(ap, fmt);
-	mg_vsnprintf(block->conn, added, (size_t)space, fmt, ap);
+	mg_vsnprintf(block->conn, &truncated, added, (size_t)space, fmt, ap);
 	va_end(ap);
 
-	/* TODO(high): don't add partial environment variables */
+	/* Do not add truncated strings to the environment */
+	if (truncated) {
+		added[0] = 0;
+		return NULL;
+	}
 
 	/* Number of bytes added to the environment */
 	n = strlen(added) + 1;
@@ -8784,6 +8839,7 @@ static void log_access(const struct mg_connection *conn)
 	user_agent = header_val(conn, "User-Agent");
 
 	mg_snprintf(conn,
+	            NULL, /* Ignore truncation in access log */
 	            buf,
 	            sizeof(buf),
 	            "%s - %s [%s] \"%s %s HTTP/%s\" %d %" INT64_FMT " %s %s",
@@ -9314,13 +9370,22 @@ struct mg_connection *mg_connect_client(
 	    INVALID_SOCKET) {
 	} else if ((conn = (struct mg_connection *)mg_calloc(
 	                1, sizeof(*conn) + MAX_REQUEST_SIZE)) == NULL) {
-		mg_snprintf(NULL, ebuf, ebuf_len, "calloc(): %s", strerror(ERRNO));
+		mg_snprintf(NULL,
+		            NULL, /* No truncation check for ebuf */
+		            ebuf,
+		            ebuf_len,
+		            "calloc(): %s",
+		            strerror(ERRNO));
 		closesocket(sock);
 #ifndef NO_SSL
 	} else if (use_ssl &&
 	           (conn->client_ssl_ctx = SSL_CTX_new(SSLv23_client_method())) ==
 	               NULL) {
-		mg_snprintf(NULL, ebuf, ebuf_len, "SSL_CTX_new error");
+		mg_snprintf(NULL,
+		            NULL, /* No truncation check for ebuf */
+		            ebuf,
+		            ebuf_len,
+		            "SSL_CTX_new error");
 		closesocket(sock);
 		mg_free(conn);
 		conn = NULL;
@@ -9374,7 +9439,12 @@ getreq(struct mg_connection *conn, char *ebuf, size_t ebuf_len, int *err)
 	reset_per_request_attributes(conn);
 
 	if (!conn) {
-		mg_snprintf(conn, ebuf, ebuf_len, "%s", "Internal error");
+		mg_snprintf(conn,
+		            NULL, /* No truncation check for ebuf */
+		            ebuf,
+		            ebuf_len,
+		            "%s",
+		            "Internal error");
 		*err = 500;
 		return 0;
 	}
@@ -9386,31 +9456,54 @@ getreq(struct mg_connection *conn, char *ebuf, size_t ebuf_len, int *err)
 	    read_request(NULL, conn, conn->buf, conn->buf_size, &conn->data_len);
 	/* assert(conn->request_len < 0 || conn->data_len >= conn->request_len); */
 	if (conn->request_len >= 0 && conn->data_len < conn->request_len) {
-		mg_snprintf(conn, ebuf, ebuf_len, "%s", "Invalid request size");
+		mg_snprintf(conn,
+		            NULL, /* No truncation check for ebuf */
+		            ebuf,
+		            ebuf_len,
+		            "%s",
+		            "Invalid request size");
 		*err = 500;
 		return 0;
 	}
 
 	if (conn->request_len == 0 && conn->data_len == conn->buf_size) {
-		mg_snprintf(conn, ebuf, ebuf_len, "%s", "Request Too Large");
+		mg_snprintf(conn,
+		            NULL, /* No truncation check for ebuf */
+		            ebuf,
+		            ebuf_len,
+		            "%s",
+		            "Request Too Large");
 		*err = 413;
 		return 0;
 	} else if (conn->request_len <= 0) {
 		if (conn->data_len > 0) {
-			mg_snprintf(
-			    conn, ebuf, ebuf_len, "%s", "Client sent malformed request");
+			mg_snprintf(conn,
+			            NULL, /* No truncation check for ebuf */
+			            ebuf,
+			            ebuf_len,
+			            "%s",
+			            "Client sent malformed request");
 			*err = 400;
 		} else {
 			/* Server did not send anything -> just close the connection */
 			conn->must_close = 1;
-			mg_snprintf(
-			    conn, ebuf, ebuf_len, "%s", "Client did not send a request");
+			mg_snprintf(conn,
+			            NULL, /* No truncation check for ebuf */
+			            ebuf,
+			            ebuf_len,
+			            "%s",
+			            "Client did not send a request");
 			*err = 0;
 		}
 		return 0;
 	} else if (parse_http_message(
 	               conn->buf, conn->buf_size, &conn->request_info) <= 0) {
-		mg_snprintf(conn, ebuf, ebuf_len, "%s", "Bad Request");
+		mg_snprintf(conn,
+		            NULL, /* No truncation check for ebuf */
+		            ebuf,
+		            ebuf_len,
+		            "%s",
+		            "Bad Request");
 		*err = 400;
 		return 0;
 	} else {
@@ -9420,7 +9513,12 @@ getreq(struct mg_connection *conn, char *ebuf, size_t ebuf_len, int *err)
 			char *endptr = NULL;
 			conn->content_len = strtoll(cl, &endptr, 10);
 			if (endptr == cl) {
-				mg_snprintf(conn, ebuf, ebuf_len, "%s", "Bad Request");
+				mg_snprintf(conn,
+				            NULL, /* No truncation check for ebuf */
+				            ebuf,
+				            ebuf_len,
+				            "%s",
+				            "Bad Request");
 				*err = 411;
 				return 0;
 			}
@@ -9459,7 +9557,7 @@ int mg_get_response(struct mg_connection *conn,
 		char txt[32]; /* will not overflow */
 
 		if (timeout >= 0) {
-			mg_snprintf(conn, txt, sizeof(txt), "%i", timeout);
+			mg_snprintf(conn, NULL, txt, sizeof(txt), "%i", timeout);
 			rctx.config[REQUEST_TIMEOUT] = txt;
 			set_sock_timeout(conn->client.sock, timeout);
 		} else {
@@ -9499,7 +9597,12 @@ struct mg_connection *mg_download(const char *host,
 	if (conn != NULL) {
 		i = mg_vprintf(conn, fmt, ap);
 		if (i <= 0) {
-			mg_snprintf(conn, ebuf, ebuf_len, "%s", "Error sending request");
+			mg_snprintf(conn,
+			            NULL, /* No truncation check for ebuf */
+			            ebuf,
+			            ebuf_len,
+			            "%s",
+			            "Error sending request");
 		} else {
 			getreq(conn, ebuf, ebuf_len, &reqerr);
 		}
@@ -9606,6 +9709,7 @@ mg_connect_websocket_client(const char *host,
 			/* if there is a connection, but it did not return 101,
 			 * error_buffer is not yet set */
 			mg_snprintf(conn,
+			            NULL, /* No truncation check for ebuf */
 			            error_buffer,
 			            error_buffer_size,
 			            "Unexpected server reply");
@@ -9690,12 +9794,17 @@ static void process_new_connection(struct mg_connection *conn)
 					send_http_error(conn, reqerr, "%s", ebuf);
 				}
 			} else if (!is_valid_uri(conn->request_info.uri)) {
-				mg_snprintf(
-				    conn, ebuf, sizeof(ebuf), "Invalid URI: [%s]", ri->uri);
+				mg_snprintf(conn,
+				            NULL, /* No truncation check for ebuf */
+				            ebuf,
+				            sizeof(ebuf),
+				            "Invalid URI: [%s]",
+				            ri->uri);
 				send_http_error(conn, 400, "%s", ebuf);
 			} else if (strcmp(ri->http_version, "1.0") &&
 			           strcmp(ri->http_version, "1.1")) {
 				mg_snprintf(conn,
+				            NULL, /* No truncation check for ebuf */
 				            ebuf,
 				            sizeof(ebuf),
 				            "Bad HTTP version: [%s]",

+ 1 - 0
src/mod_lua.inl

@@ -325,6 +325,7 @@ static int lsp(struct mg_connection *conn,
 					mg_write(conn, p + pos, i - pos);
 
 					mg_snprintf(conn,
+					            NULL, /* name only used for debugging */
 					            chunkname,
 					            sizeof(chunkname),
 					            "@%s+%i",