In origin code, double quote is only allowed at the begin or end "complicated argument" --some_opt="complicated string" (we split this argument into 2 parts, option and data, the data is "complicated string"). This patch makes it allow double quote at any position of an argument: complicated" argument" complicated" "argument --"some opt=complicated string" This patch is also needed for the following patches, the following patches will not split option argument into 2 parts, so we have to allow double quote at any position of an argument. Signed-off-by: Lai Jiangshan <laijs@xxxxxxxxxxxxxx> --- diff --git a/tools/virsh.c b/tools/virsh.c index 57ea618..7b6f2b6 100644 --- a/tools/virsh.c +++ b/tools/virsh.c @@ -10172,9 +10172,9 @@ static int vshCommandGetToken(vshControl *ctl, char *str, char **end, char **res) { int tk = VSH_TK_NONE; - int quote = FALSE; + bool double_quote = false; int sz = 0; - char *p = str; + char *p = str, *q; char *tkstr = NULL; *end = NULL; @@ -10188,9 +10188,13 @@ vshCommandGetToken(vshControl *ctl, char *str, char **end, char **res) *end = ++p; /* = \0 or begin of next command */ return VSH_TK_END; } + + q = p; + *res = NULL; +copy: while (*p) { /* end of token is blank space or ';' */ - if ((quote == FALSE && (*p == ' ' || *p == '\t')) || *p == ';') + if (!double_quote && (*p == ' ' || *p == '\t' || *p == ';')) break; /* end of option name could be '=' */ @@ -10206,23 +10210,22 @@ vshCommandGetToken(vshControl *ctl, char *str, char **end, char **res) p += 2; } else { tk = VSH_TK_DATA; - if (*p == '"') { - quote = TRUE; - p++; - } else { - quote = FALSE; - } } tkstr = p; /* begin of token */ - } else if (quote && *p == '"') { - quote = FALSE; + } + + if (*p == '"') { + double_quote = !double_quote; p++; - break; /* end of "..." token */ + continue; } + + if (*res) + (*res)[sz] = *p; p++; sz++; } - if (quote) { + if (double_quote) { vshError(ctl, "%s", _("missing \"")); return VSH_TK_ERROR; } @@ -10231,8 +10234,12 @@ vshCommandGetToken(vshControl *ctl, char *str, char **end, char **res) if (sz == 0) return VSH_TK_END; - *res = vshMalloc(ctl, sz + 1); - memcpy(*res, tkstr, sz); + if (!*res) { + *res = vshMalloc(ctl, sz + 1); + sz = 0; + p = q; + goto copy; + } *(*res + sz) = '\0'; *end = p; -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list