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;

Reply via email to