Package: cgilib Version: 0.5-4 Severity: normal
Cgi variable names as well as variable values need to have escape sequences decoded. cglib currently does not do this, however, it should. I've attached a patch to correct this. I've tested it and it appears to work. Thanks, Neal -- System Information: Debian Release: 3.1 Architecture: i386 (i686) Kernel: Linux 2.6.8-2-686-smp Locale: LANG=en_US, LC_CTYPE=en_US (charmap=ISO-8859-1) (ignored: LC_ALL set to en_US) -- no debconf information
--- cgi.c.orig 1999-08-20 22:14:07.000000000 +0100 +++ cgi.c 2005-10-30 22:17:10.699996428 +0000 @@ -248,38 +250,58 @@ s_var **cgiReadVariables () i=0; while (*cp) { if ((ip = (char *)strchr(cp, '&')) != NULL) { + /* Replace the & with a NUL to make parsing easier. */ *ip = '\0'; }else + /* This is the last variable set IP to the real trailing + NUL. */ ip = cp + strlen(cp); if ((esp=(char *)strchr(cp, '=')) == NULL) { + /* The value of the variable is the empty string. */ cp = ++ip; continue; } if (!strlen(esp)) { + /* Variable has no value. */ cp = ++ip; continue; } + /* Squash the = as well. */ + *esp = '\0'; + esp ++; + + /* CP names the start of variable name; ESP names the value; + and IP points to the final NUL. */ + if (i<numargs) { + char *name; + char *value; + + name = strdup (cp); + if (! name) + return NULL; + cgiDecodeString (name); + + value = strdup (esp); + if (! value) { + free (name); + return NULL; + } + cgiDecodeString (value); /* try to find out if there's already such a variable */ - for (k=0; k<i && (strncmp (result[k]->name,cp, esp-cp) || !(strlen (result[k]->name) == esp-cp)); k++); + for (k=0; k<i && strcmp (result[k]->name, name); k++) + ; if (k == i) { /* No such variable yet */ if ((result[i] = (s_var *)malloc(sizeof(s_var))) == NULL) return NULL; - if ((result[i]->name = (char *)malloc((esp-cp+1) * sizeof(char))) == NULL) - return NULL; - memset (result[i]->name, 0, esp-cp+1); - strncpy(result[i]->name, cp, esp-cp); - cp = ++esp; - if ((result[i]->value = (char *)malloc((ip-esp+1) * sizeof(char))) == NULL) - return NULL; - memset (result[i]->value, 0, ip-esp+1); - strncpy(result[i]->value, cp, ip-esp); - result[i]->value = cgiDecodeString(result[i]->value); + result[i]->name = name; + result[i]->value = value; + if (cgiDebugLevel) { if (cgiDebugStderr) fprintf (stderr, "%s: %s\n", result[i]->name, result[i]->value); @@ -288,15 +310,14 @@ s_var **cgiReadVariables () } i++; } else { /* There is already such a name, suppose a mutiple field */ - cp = ++esp; - len = (strlen(result[k]->value)+(ip-esp)+2) * sizeof (char); - if ((sptr = (char *)malloc(len)) == NULL) + int len = strlen (result[k]->value); + if ((sptr = realloc (result[k]->value, + len + 1 + strlen (value) + 1)) == NULL) return NULL; - memset (sptr, 0, len); - sprintf (sptr, "%s\n", result[k]->value); - strncat(sptr, cp, ip-esp); - free(result[k]->value); - result[k]->value = cgiDecodeString (sptr); + + result[k]->value[len] = '\n'; + memcpy (result[k]->value + len + 1, value, strlen (value) + 1); + free (value); } } cp = ++ip;