|
@@ -10669,19 +10669,25 @@ static void addenv(struct cgi_environment *env,
|
|
static void
|
|
static void
|
|
addenv(struct cgi_environment *env, const char *fmt, ...)
|
|
addenv(struct cgi_environment *env, const char *fmt, ...)
|
|
{
|
|
{
|
|
- size_t n, space;
|
|
|
|
|
|
+ size_t i, n, space;
|
|
int truncated = 0;
|
|
int truncated = 0;
|
|
char *added;
|
|
char *added;
|
|
va_list ap;
|
|
va_list ap;
|
|
|
|
|
|
|
|
+ if ((env->varlen - env->varused) < 2) {
|
|
|
|
+ mg_cry_internal(env->conn,
|
|
|
|
+ "%s: Cannot register CGI variable [%s]",
|
|
|
|
+ __func__,
|
|
|
|
+ fmt);
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+
|
|
/* Calculate how much space is left in the buffer */
|
|
/* Calculate how much space is left in the buffer */
|
|
space = (env->buflen - env->bufused);
|
|
space = (env->buflen - env->bufused);
|
|
|
|
|
|
- /* Calculate an estimate for the required space */
|
|
|
|
- n = strlen(fmt) + 2 + 128;
|
|
|
|
-
|
|
|
|
do {
|
|
do {
|
|
- if (space <= n) {
|
|
|
|
|
|
+ /* Space for "\0\0" is always needed. */
|
|
|
|
+ if (space <= 2) {
|
|
/* Allocate new buffer */
|
|
/* Allocate new buffer */
|
|
n = env->buflen + CGI_ENVIRONMENT_SIZE;
|
|
n = env->buflen + CGI_ENVIRONMENT_SIZE;
|
|
added = (char *)mg_realloc_ctx(env->buf, n, env->conn->phys_ctx);
|
|
added = (char *)mg_realloc_ctx(env->buf, n, env->conn->phys_ctx);
|
|
@@ -10694,8 +10700,13 @@ addenv(struct cgi_environment *env, const char *fmt, ...)
|
|
fmt);
|
|
fmt);
|
|
return;
|
|
return;
|
|
}
|
|
}
|
|
|
|
+ /* Retarget pointers */
|
|
env->buf = added;
|
|
env->buf = added;
|
|
env->buflen = n;
|
|
env->buflen = n;
|
|
|
|
+ for (i = 0, n = 0; i < env->varused; i++) {
|
|
|
|
+ env->var[i] = added + n;
|
|
|
|
+ n += strlen(added + n) + 1;
|
|
|
|
+ }
|
|
space = (env->buflen - env->bufused);
|
|
space = (env->buflen - env->bufused);
|
|
}
|
|
}
|
|
|
|
|
|
@@ -10704,14 +10715,13 @@ addenv(struct cgi_environment *env, const char *fmt, ...)
|
|
|
|
|
|
/* Copy VARIABLE=VALUE\0 string into the free space */
|
|
/* Copy VARIABLE=VALUE\0 string into the free space */
|
|
va_start(ap, fmt);
|
|
va_start(ap, fmt);
|
|
- mg_vsnprintf(env->conn, &truncated, added, (size_t)space, fmt, ap);
|
|
|
|
|
|
+ mg_vsnprintf(env->conn, &truncated, added, space - 1, fmt, ap);
|
|
va_end(ap);
|
|
va_end(ap);
|
|
|
|
|
|
/* Do not add truncated strings to the environment */
|
|
/* Do not add truncated strings to the environment */
|
|
if (truncated) {
|
|
if (truncated) {
|
|
/* Reallocate the buffer */
|
|
/* Reallocate the buffer */
|
|
space = 0;
|
|
space = 0;
|
|
- n = 1;
|
|
|
|
}
|
|
}
|
|
} while (truncated);
|
|
} while (truncated);
|
|
|
|
|
|
@@ -10719,16 +10729,6 @@ addenv(struct cgi_environment *env, const char *fmt, ...)
|
|
n = strlen(added) + 1;
|
|
n = strlen(added) + 1;
|
|
env->bufused += n;
|
|
env->bufused += n;
|
|
|
|
|
|
- /* Now update the variable index */
|
|
|
|
- space = (env->varlen - env->varused);
|
|
|
|
- if (space < 2) {
|
|
|
|
- mg_cry_internal(env->conn,
|
|
|
|
- "%s: Cannot register CGI variable [%s]",
|
|
|
|
- __func__,
|
|
|
|
- fmt);
|
|
|
|
- return;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
/* Append a pointer to the added string into the envp array */
|
|
/* Append a pointer to the added string into the envp array */
|
|
env->var[env->varused] = added;
|
|
env->var[env->varused] = added;
|
|
env->varused++;
|
|
env->varused++;
|
|
@@ -10763,7 +10763,7 @@ prepare_cgi_environment(struct mg_connection *conn,
|
|
env->varlen = MAX_CGI_ENVIR_VARS;
|
|
env->varlen = MAX_CGI_ENVIR_VARS;
|
|
env->varused = 0;
|
|
env->varused = 0;
|
|
env->var =
|
|
env->var =
|
|
- (char **)mg_malloc_ctx(env->buflen * sizeof(char *), conn->phys_ctx);
|
|
|
|
|
|
+ (char **)mg_malloc_ctx(env->varlen * sizeof(char *), conn->phys_ctx);
|
|
if (env->var == NULL) {
|
|
if (env->var == NULL) {
|
|
mg_cry_internal(conn,
|
|
mg_cry_internal(conn,
|
|
"%s: Not enough memory for environmental variables",
|
|
"%s: Not enough memory for environmental variables",
|