Projects
Eulaceura:Factory
grubby
_service:obs_scm:grubby-properly-handle-mixed-a...
Sign Up
Log In
Username
Password
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File _service:obs_scm:grubby-properly-handle-mixed-and-and-nested-quotes.patch of Package grubby
From 03433c27cbbeee9f8c83f5365b5ba1ef8c285d8b Mon Sep 17 00:00:00 2001 From: Nishanth Aravamudan <nacc@linux.vnet.ibm.com> Date: Tue, 16 Jun 2015 10:43:21 -0700 Subject: [PATCH 04/60] grubby: properly handle mixed ' and " and nested quotes The SLES12 grub2.cfg file on ppc64le by default contains a line like: submenu "Bootable snapshot #$snapshot_num" { menuentry "If OK, run 'snapper rollback $snapshot_num' reboot." { true; } } On any grubby (tested with 8.40) invocation that updates the config file, the combination of nested quotes and mixed quotes leads to a generated file content like: submenu "Bootable snapshot #$snapshot_num" { menuentry 'If OK, run snapper rollback $snapshot_num' rollback $snapshot_num' and reboot." { true; } } which includes both a change from " to ', but also improperly quoted strings and trailing characters relative to the string. This actually leads to a failure to boot from the disk by default when using grubby (e.g., Autotest) on SLES12 ppc64le. Whether SLES12 should be adding an entry like this by default or not is probably open to debate, but grubby should be able to hand this input file. To fix the issue, three changes were necessary: 1) grub2ExtractTitle needs to check that if the second element starts with a quote, that the matching element found ends with the same quote-type (' vs. ") 2) lineWrite needs to output the right kind of quote based upon if the string to be outputted itself contains quotes. This is not currently possible in the code, because quotes are stripped out normally by readConfig, but with the change in 3), that only happens now for the quotes that actually delineate a string. 3) readConfig needs to check that when it is extracting titles and determining extras, it uses matching quotes. With these changes, a simple grubby --set-default=SLES12 (for example), now produces: submenu "Bootable snapshot #$snapshot_num" { menuentry "If OK, run 'snapper rollback $snapshot_num' and reboot." { true; } } as expected. Signed-off-by: Nishanth Aravamudan <nacc@linux.vnet.ibm.com> --- grubby.c | 42 +++++++++++++++++++++++++++++++++--------- 1 file changed, 33 insertions(+), 9 deletions(-) diff --git a/grubby.c b/grubby.c index 53fe925..440c627 100644 --- a/grubby.c +++ b/grubby.c @@ -451,6 +451,8 @@ char *grub2ExtractTitle(struct singleLine * line) { * whose last character is also quote (assuming it's the closing one) */ int resultMaxSize; char * result; + /* need to ensure that ' does not match " as we search */ + char quote_char = *current; resultMaxSize = sizeOfSingleLine(line); result = malloc(resultMaxSize); @@ -464,7 +466,7 @@ char *grub2ExtractTitle(struct singleLine * line) { current_indent_len = strlen(current_indent); strncat(result, current_indent, current_indent_len); - if (!isquote(current[current_len-1])) { + if (current[current_len-1] != quote_char) { strncat(result, current, current_len); } else { strncat(result, current, current_len - 1); @@ -928,10 +930,23 @@ static int lineWrite(FILE * out, struct singleLine * line, /* Need to handle this, because we strip the quotes from * menuentry when read it. */ if (line->type == LT_MENUENTRY && i == 1) { - if(!isquote(*line->elements[i].item)) - fprintf(out, "\'%s\'", line->elements[i].item); - else + if(!isquote(*line->elements[i].item)) { + int substring = 0; + /* If the line contains nested quotes, we did not strip + * the "interna" quotes and we must use the right quotes + * again when writing the updated file. */ + for (int j = i; j < line->numElements; j++) { + if (strchr(line->elements[i].item, '\'') != NULL) { + substring = 1; + fprintf(out, "\"%s\"", line->elements[i].item); + break; + } + } + if (!substring) + fprintf(out, "\'%s\'", line->elements[i].item); + } else { fprintf(out, "%s", line->elements[i].item); + } fprintf(out, "%s", line->elements[i].indent); continue; @@ -1267,6 +1282,8 @@ static struct grubConfig * readConfig(const char * inName, len = 0; char *extras; char *title; + /* initially unseen value */ + char quote_char = '\0'; for (int i = 1; i < line->numElements; i++) { len += strlen(line->elements[i].item); @@ -1283,13 +1300,16 @@ static struct grubConfig * readConfig(const char * inName, for (int i = 0; i < line->numElements; i++) { if (!strcmp(line->elements[i].item, "menuentry")) continue; - if (isquote(*line->elements[i].item)) + if (isquote(*line->elements[i].item) && quote_char == '\0') { + /* ensure we properly pair off quotes */ + quote_char = *line->elements[i].item; title = line->elements[i].item + 1; - else + } else { title = line->elements[i].item; + } len = strlen(title); - if (isquote(title[len-1])) { + if (title[len-1] == quote_char) { strncat(buf, title,len-1); break; } else { @@ -1300,6 +1320,7 @@ static struct grubConfig * readConfig(const char * inName, /* get extras */ int count = 0; + quote_char = '\0'; for (int i = 0; i < line->numElements; i++) { if (count >= 2) { strcat(extras, line->elements[i].item); @@ -1310,12 +1331,15 @@ static struct grubConfig * readConfig(const char * inName, continue; /* count ' or ", there should be two in menuentry line. */ - if (isquote(*line->elements[i].item)) + if (isquote(*line->elements[i].item) && quote_char == '\0') { + /* ensure we properly pair off quotes */ + quote_char = *line->elements[i].item; count++; + } len = strlen(line->elements[i].item); - if (isquote(line->elements[i].item[len -1])) + if (line->elements[i].item[len -1] == quote_char) count++; /* ok, we get the final ' or ", others are extras. */ -- 1.8.3.1
Locations
Projects
Search
Status Monitor
Help
Open Build Service
OBS Manuals
API Documentation
OBS Portal
Reporting a Bug
Contact
Mailing List
Forums
Chat (IRC)
Twitter
Open Build Service (OBS)
is an
openSUSE project
.
浙ICP备2022010568号-2