[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#185014: cdebconf mangles strings with consecutive spaces



On Sun, Mar 16, 2003 at 03:27:06PM +0100, Martin Sjögren wrote:
> Package: cdebconf
> Version: 0.33
> Severity: important
> 
> When I try to e.g. subst a string with several consecutive spaces (for
> alignment for example), cdebconf wrecks the spacing in its argument
> parsing. cdebconf does piece together the strings again, but only with a
> single space, so the multiple spaces are forgotten.

Hi Martin,
here is a patch.  I did not commit it because library splitting must
be performed first, and I do not know how to do it right.

Denis
Index: commands.c
===================================================================
RCS file: /cvs/debian-boot/debian-installer/tools/cdebconf/src/commands.c,v
retrieving revision 1.43
diff -u -r1.43 commands.c
--- commands.c	13 Apr 2003 09:04:24 -0000	1.43
+++ commands.c	22 Apr 2003 21:00:41 -0000
@@ -10,6 +10,25 @@
 	if (_command_checkargc(argc pred, out, outsize) == DC_NOTOK) \
 		return DC_OK
 
+#define SKIPARG(a)                              \
+    do {                                        \
+        for (; *(a) != ' ' && *(a) != '\0'; (a)++)\
+            ;                                   \
+        if (*(a) == '\0')                       \
+            return DC_NOTOK;                    \
+        for (; *(a) == ' '; (a)++)              \
+            ;                                   \
+    } while(0)
+
+#define SKIPARGSINGLESPACE(a)                   \
+    do {                                        \
+        for (; *(a) != ' ' && *(a) != '\0'; (a)++)\
+            ;                                   \
+        if (*(a) == '\0')                       \
+            return DC_NOTOK;                    \
+        (a)++;                                  \
+    } while(0)
+
 
 /**
  * @brief Checks to see if a given predicate is true; and if not
@@ -36,7 +55,7 @@
 }
 
 int command_input(struct confmodule *mod, int argc, char **argv, 
-	char *out, size_t outsize)
+	char *litteral, char *out, size_t outsize)
 {
     int visible = 1;
     struct question *q = 0;
@@ -74,7 +93,7 @@
 }
 
 int command_clear(struct confmodule *mod, int argc, char **argv, 
-	char *out, size_t outsize)
+	char *litteral, char *out, size_t outsize)
 {
 	CHECKARGC(== 0);
 
@@ -84,7 +103,7 @@
 }
 
 int command_version(struct confmodule *mod, int argc, char **argv, 
-	char *out, size_t outsize)
+	char *litteral, char *out, size_t outsize)
 {
 	int ver;
 
@@ -105,7 +124,7 @@
 }
 
 int command_capb(struct confmodule *mod, int argc, char **argv, 
-	char *out, size_t outsize)
+	char *litteral, char *out, size_t outsize)
 {
 	int i;
 
@@ -121,48 +140,30 @@
 }
 
 int command_title(struct confmodule *mod, int argc, char **argv, 
-	char *out, size_t outsize)
+	char *litteral, char *out, size_t outsize)
 {
-    char *buf;
-    size_t bufsize = 1024;
-    int i;
-
-    buf = malloc(bufsize);
-    if (!buf)
-        return DC_NOTOK;
-    memset(buf, 0, bufsize);
-    for (i = 1; i <= argc; i++) {
-        while ((strlen(buf) + strlen(argv[i]) + 1) > bufsize) 
-        {
-            bufsize += 1024;
-            buf = realloc(buf, bufsize);
-            if (!buf)
-                return DC_NOTOK;
-        }
-        strvacat(buf, bufsize, argv[i], " ", 0);
-    }
-
-    mod->frontend->methods.set_title(mod->frontend, buf);
+    SKIPARGSINGLESPACE(litteral);
+    mod->frontend->methods.set_title(mod->frontend, litteral);
     snprintf(out, outsize, "%u", CMDSTATUS_SUCCESS);
     return DC_OK;
 }
 
 int command_beginblock(struct confmodule *mod, int argc, char **argv, 
-	char *out, size_t outsize)
+	char *litteral, char *out, size_t outsize)
 {
 	snprintf(out, outsize, "%u", CMDSTATUS_SUCCESS);
 	return DC_OK;
 }
 
 int command_endblock(struct confmodule *mod, int argc, char **argv, 
-	char *out, size_t outsize)
+	char *litteral, char *out, size_t outsize)
 {
 	snprintf(out, outsize, "%u", CMDSTATUS_SUCCESS);
 	return DC_OK;
 }
 
 int command_go(struct confmodule *mod, int argc, char **argv, 
-	char *out, size_t outsize)
+	char *litteral, char *out, size_t outsize)
 {
 	CHECKARGC(== 0);
 	if (mod->frontend->methods.go(mod->frontend) == CMDSTATUS_GOBACK)
@@ -181,7 +182,7 @@
 }
 
 int command_get(struct confmodule *mod, int argc, char **argv, 
-	char *out, size_t outsize)
+	char *litteral, char *out, size_t outsize)
 {
 	struct question *q;
 	CHECKARGC(== 1);
@@ -202,19 +203,13 @@
 }
 
 int command_set(struct confmodule *mod, int argc, char **argv, 
-	char *out, size_t outsize)
+	char *litteral, char *out, size_t outsize)
 {
     struct question *q;
-    int i;
-    char *buf;
-    size_t bufsize = 1024;
 
     CHECKARGC(>= 2);
-
-    buf = malloc(bufsize);
-    if (!buf)
-        return DC_NOTOK;
-    memset(buf, 0, bufsize);
+    SKIPARG(litteral);
+    SKIPARGSINGLESPACE(litteral);
 
     q = mod->questions->methods.get(mod->questions, argv[1]);
     if (q == NULL)
@@ -222,21 +217,7 @@
                 CMDSTATUS_BADQUESTION, argv[1]);
     else
     {
-        for (i = 2; i <= argc; i++) {
-            while ((strlen(buf) + strlen(argv[i]) + 1) > bufsize) {
-                bufsize += 1024;
-                buf = realloc(buf, bufsize);
-                if (!buf)
-                    return DC_NOTOK;
-            }
-            strvacat(buf, bufsize, argv[i], " ", 0);
-        }
-
-        /* remove the last space added */
-        if (buf[0] != 0)
-            buf[strlen(buf)-1] = 0;
-
-        question_setvalue(q, buf);
+        question_setvalue(q, litteral);
 
         if (mod->questions->methods.set(mod->questions, q) != 0)
         {
@@ -244,7 +225,7 @@
                     CMDSTATUS_SUCCESS);
             if (0 == strcmp("debconf/language", argv[1]))
 	    { /* Pass the value on to getlanguage() in templates.c */
-                setenv("LANGUAGE", buf, 1);
+                setenv("LANGUAGE", litteral, 1);
 	    }
         }
         else
@@ -257,7 +238,7 @@
 }
 
 int command_reset(struct confmodule *mod, int argc, char **argv, 
-	char *out, size_t outsize)
+	char *litteral, char *out, size_t outsize)
 {
 	struct question *q;
 
@@ -284,21 +265,16 @@
 }
 
 int command_subst(struct confmodule *mod, int argc, char **argv, 
-	char *out, size_t outsize)
+	char *litteral, char *out, size_t outsize)
 {
     struct question *q;
     struct questionvariable;
     char *variable;
-    int i;
-    char *buf;
-    size_t bufsize = 1024;
 
     CHECKARGC(>= 3);
-
-    buf = malloc(bufsize);
-    if (!buf)
-        return DC_NOTOK;
-    memset(buf, 0, bufsize);
+    SKIPARG(litteral);
+    SKIPARG(litteral);
+    SKIPARGSINGLESPACE(litteral);
 
     variable = argv[2];
     q = mod->questions->methods.get(mod->questions, argv[1]);
@@ -308,19 +284,7 @@
                 CMDSTATUS_BADQUESTION, argv[1]);
     else
     {
-        strvacat(buf, bufsize, argv[3], 0);	
-        for (i = 4; i <= argc; i++) {
-            while ((strlen(buf) + strlen(argv[i])) + 1 > bufsize)
-            {
-                bufsize += 1024;
-                buf = realloc(buf, bufsize);
-                if (!buf)
-                    return DC_NOTOK;
-            }
-
-            strvacat(buf, bufsize, " ", argv[i], 0);	
-        }
-        question_variable_add(q, variable, buf);
+        question_variable_add(q, variable, litteral);
 
         if (mod->questions->methods.set(mod->questions, q) != 0)
             snprintf(out, outsize, "%u", CMDSTATUS_SUCCESS);
@@ -334,7 +298,7 @@
 }
 
 int command_register(struct confmodule *mod, int argc, char **argv, 
-	char *out, size_t outsize)
+	char *litteral, char *out, size_t outsize)
 {
     struct question *q;
     struct template *t;
@@ -363,7 +327,7 @@
 }
 
 int command_unregister(struct confmodule *mod, int argc, char **argv, 
-	char *out, size_t outsize)
+	char *litteral, char *out, size_t outsize)
 {
     struct question *q;
     CHECKARGC(== 1);
@@ -381,7 +345,7 @@
 }
 
 int command_purge(struct confmodule *mod, int argc, char **argv, 
-	char *out, size_t outsize)
+	char *litteral, char *out, size_t outsize)
 {
 	mod->questions->methods.disownall(mod->questions, mod->owner);
 	snprintf(out, outsize, "%u", CMDSTATUS_SUCCESS);
@@ -389,7 +353,7 @@
 }
 
 int command_metaget(struct confmodule *mod, int argc, char **argv, 
-	char *out, size_t outsize)
+	char *litteral, char *out, size_t outsize)
 {
     struct question *q;
     const char *value;
@@ -414,7 +378,7 @@
 }
 
 int command_fget(struct confmodule *mod, int argc, char **argv, 
-	char *out, size_t outsize)
+	char *litteral, char *out, size_t outsize)
 {
     struct question *q;
     char *field;
@@ -444,7 +408,7 @@
 }
 
 int command_fset(struct confmodule *mod, int argc, char **argv, 
-	char *out, size_t outsize)
+	char *litteral, char *out, size_t outsize)
 {
     struct question *q;
     char *field;
@@ -478,7 +442,7 @@
 }
 
 int command_exist(struct confmodule *mod, int argc, char **argv, 
-	char *out, size_t outsize)
+	char *litteral, char *out, size_t outsize)
 {
     struct question *q;
     CHECKARGC(== 1);
@@ -497,14 +461,14 @@
 }
 
 int command_stop(struct confmodule *mod, int argc, char **argv,
-	char *out, size_t outsize)
+	char *litteral, char *out, size_t outsize)
 {
 	CHECKARGC(== 0);
 	return DC_OK;
 }
 
 int command_x_loadtemplatefile(struct confmodule *mod, int argc, char **argv, 
-                               char *out, size_t outsize)
+                               char *litteral, char *out, size_t outsize)
 {
     struct template *t = NULL;
     struct question *q = NULL;
@@ -528,7 +492,7 @@
 }
 
 int command_progress(struct confmodule *mod, int argc, char **argv, 
-                     char *out, size_t outsize)
+                     char *litteral, char *out, size_t outsize)
 {
     int min, max;
     struct question *q = NULL;
Index: commands.h
===================================================================
RCS file: /cvs/debian-boot/debian-installer/tools/cdebconf/src/commands.h,v
retrieving revision 1.6
diff -u -r1.6 commands.h
--- commands.h	8 Dec 2002 00:38:07 -0000	1.6
+++ commands.h	22 Apr 2003 21:00:41 -0000
@@ -27,7 +27,7 @@
  * @param size_t outsize - output buffer size
  * @return int - DC_NOTOK if error, DC_OK otherwise
  */
-typedef int (*command_function_t)(struct confmodule *mod, int argc, char **argv, char *out, size_t outsize);
+typedef int (*command_function_t)(struct confmodule *mod, int argc, char **argv, char *litteral, char *out, size_t outsize);
 
 
 /**
@@ -43,14 +43,14 @@
  *
  * Adds a question to the list of questions to be asked if appropriate.
  */
-int command_input(struct confmodule *, int, char **, char *, size_t);
+int command_input(struct confmodule *, int, char **, char *, char *, size_t);
 
 /**
  * @brief Handler for the CLEAR debconf command
  *
  * Removes any questions currently in the queue
  */
-int command_clear(struct confmodule *, int, char **, char *, size_t);
+int command_clear(struct confmodule *, int, char **, char *, char *, size_t);
 
 /**
  * @brief handler for the VERSION debconf command
@@ -58,7 +58,7 @@
  * Checks to see if the version required by a confmodule script
  * is compatible with the debconf version we recognize
  */
-int command_version(struct confmodule *, int, char **, char *, size_t);
+int command_version(struct confmodule *, int, char **, char *, char *, size_t);
 
 /**
  * @brief handler for the CAPB debconf command
@@ -66,26 +66,26 @@
  * Exchanges capability information between the confmodule and
  * the frontend
  */
-int command_capb(struct confmodule *, int, char **, char *, size_t);
+int command_capb(struct confmodule *, int, char **, char *, char *, size_t);
 
 /**
  * @brief handler for the TITLE debconf command
  *
  * Sets the title in the frontend
  */
-int command_title(struct confmodule *, int, char **, char *, size_t);
+int command_title(struct confmodule *, int, char **, char *, char *, size_t);
 
 /**
  * @brief handler for the BEGINBLOCK debconf command
  * @warning Not yet implemented
  */
-int command_beginblock(struct confmodule *, int, char **, char *, size_t);
+int command_beginblock(struct confmodule *, int, char **, char *, char *, size_t);
 
 /**
  * @brief handler for the ENDBLOCK debconf command
  * @warning Not yet implemented
  */
-int command_endblock(struct confmodule *, int, char **, char *, size_t);
+int command_endblock(struct confmodule *, int, char **, char *, char *, size_t);
 
 /**
  * @brief handler for the GO debconf command
@@ -96,87 +96,87 @@
  * Frontend should return CMDSTATUS_GOBACK only if the confmodule
  * supports backing up
  */
-int command_go(struct confmodule *, int, char **, char *, size_t);
+int command_go(struct confmodule *, int, char **, char *, char *, size_t);
 
 /**
  * @brief handler for the GET debconf command
  *
  * Retrieves the value of a given template
  */
-int command_get(struct confmodule *, int, char **, char *, size_t);
+int command_get(struct confmodule *, int, char **, char *, char *, size_t);
 
 /**
  * @brief handler for the SET debconf command
  *
  * Sets the value of a given template
  */
-int command_set(struct confmodule *, int, char **, char *, size_t);
+int command_set(struct confmodule *, int, char **, char *, char *, size_t);
 
 /**
  * @brief handler for the RESET debconf command
  *
  * Resets the value of a given template to the default
  */
-int command_reset(struct confmodule *, int, char **, char *, size_t);
+int command_reset(struct confmodule *, int, char **, char *, char *, size_t);
 
 /**
  * @brief handler for the SUBST debconf command
  *
  * Registers a substitution variable/value for a template
  */
-int command_subst(struct confmodule *, int, char **, char *, size_t);
+int command_subst(struct confmodule *, int, char **, char *, char *, size_t);
 
 /**
  * @brief handler for the REGISTER debconf command
  */
-int command_register(struct confmodule *, int, char **, char *, size_t);
+int command_register(struct confmodule *, int, char **, char *, char *, size_t);
 
 /**
  * @brief handler for the UNREGISTER debconf command
  */
-int command_unregister(struct confmodule *, int, char **, char *, size_t);
+int command_unregister(struct confmodule *, int, char **, char *, char *, size_t);
 
 /**
  * @brief handler for the PURGE debconf command
  *
  * Removes all questions owned by a given owner
  */
-int command_purge(struct confmodule *, int, char **, char *, size_t);
+int command_purge(struct confmodule *, int, char **, char *, char *, size_t);
 
 /**
  * @brief handler for the METAGET debconf command
  *
  * Retrieves a given attribute for a template
  */
-int command_metaget(struct confmodule *, int, char **, char *, size_t);
+int command_metaget(struct confmodule *, int, char **, char *, char *, size_t);
 
 /**
  * @brief handler for the FGET debconf command
  * 
  * Retrieves a given flag value for a template
  */
-int command_fget(struct confmodule *, int, char **, char *, size_t);
+int command_fget(struct confmodule *, int, char **, char *, char *, size_t);
 
 /**
  * @brief handler for the FSET debconf command
  * 
  * Sets a given flag value for a template
  */
-int command_fset(struct confmodule *, int, char **, char *, size_t);
+int command_fset(struct confmodule *, int, char **, char *, char *, size_t);
 
 /**
  * @brief handler for the EXISTS debconf command
  *
  * Checks to see if a template exists
  */
-int command_exist(struct confmodule *, int, char **, char *, size_t);
+int command_exist(struct confmodule *, int, char **, char *, char *, size_t);
 
 /**
  * @brief handler for the STOP debconf command
  *
  * Finishes the debconf session
  */
-int command_stop(struct confmodule *, int, char **, char *, size_t);
+int command_stop(struct confmodule *, int, char **, char *, char *, size_t);
 
 /**
  * @brief handler for the PROGRESS debconf command
@@ -185,7 +185,7 @@
  *
  * @warning This is not yet in the debconf spec
  */
-int command_progress(struct confmodule *, int, char **, char *, size_t);
+int command_progress(struct confmodule *, int, char **, char *, char *, size_t);
 
 /**
  * @brief handler for the X_LOADTEMPLATE debconf command
@@ -194,6 +194,6 @@
  *
  * @warning This is not in the debconf spec
  */
-int command_x_loadtemplatefile(struct confmodule *, int, char **, char *, size_t);
+int command_x_loadtemplatefile(struct confmodule *, int, char **, char *, char *, size_t);
 
 #endif
Index: confmodule.c
===================================================================
RCS file: /cvs/debian-boot/debian-installer/tools/cdebconf/src/confmodule.c,v
retrieving revision 1.24
diff -u -r1.24 confmodule.c
--- confmodule.c	19 Dec 2002 00:38:44 -0000	1.24
+++ confmodule.c	22 Apr 2003 21:00:41 -0000
@@ -52,20 +52,28 @@
 {
 	int i = 0, argc;
 	char *argv[10];
+	char *litteral;
+	int rc;
 
 	out[0] = 0;
 	if (*in == '#') return 1;
 
 	memset(argv, 0, sizeof(char *) * DIM(argv));
+	litteral = strdup(in);
+	if (litteral == NULL)
+		return DC_NOTOK;
 	argc = strcmdsplit(in, argv, DIM(argv) - 1);
 
 	for (; commands[i].command != 0; i++)
 	{
 		if (strcasecmp(argv[0], commands[i].command) == 0) {
-			return (*commands[i].handler)(mod, argc - 1, argv, 
-							out, outsize);
+			rc = (*commands[i].handler)(mod, argc - 1, argv, 
+							litteral, out, outsize);
+			free(litteral);
+			return rc;
 		}
 	}
+	free(litteral);
 	return DC_NOTOK;
 }
 
Index: modules/db/rfc822db/rfc822db.c
===================================================================
RCS file: /cvs/debian-boot/debian-installer/tools/cdebconf/src/modules/db/rfc822db/rfc822db.c,v
retrieving revision 1.17
diff -u -r1.17 rfc822db.c
--- modules/db/rfc822db/rfc822db.c	23 Dec 2002 09:40:12 -0000	1.17
+++ modules/db/rfc822db/rfc822db.c	22 Apr 2003 21:00:42 -0000
@@ -76,7 +76,7 @@
             finished = 1;
         *delim = '\0';
 
-        striptmp_val = strdup(strstrip(wc));
+        striptmp_val = strdup(wc);
         question_variable_add(q,striptmp_var, striptmp_val);
 
         free(striptmp_val);

Reply to: