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: