diff --git a/ChangeLog b/ChangeLog index ec5a8ffca..079490fda 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,14 @@ +2012-03-11 Vladimir Serbinenko + + Fix handling of leading spaces in scripts. + + * grub-core/normal/cmdline.c (grub_cmdline_get): Don't strip leading + spaces. + * grub-core/normal/main.c (grub_file_getline): Remove all preprocessing + other than skipping \r. All users updated. + * tests/grub_script_echo1.in: Add space-related tests. + * util/grub-menulst2cfg.c (main): Remove useless space skipping. + 2012-03-11 Vladimir Serbinenko * grub-core/commands/cat.c (grub_cmd_cat): Fix termination key check. diff --git a/grub-core/commands/hashsum.c b/grub-core/commands/hashsum.c index d8fd4cde5..44d7cbe17 100644 --- a/grub-core/commands/hashsum.c +++ b/grub-core/commands/hashsum.c @@ -103,6 +103,8 @@ check_list (const gcry_md_spec_t *hash, const char *hashfilename, while (grub_free (buf), (buf = grub_file_getline (hashlist))) { const char *p = buf; + while (grub_isspace (p[0])) + p++; for (i = 0; i < hash->mdlen; i++) { int high, low; @@ -112,8 +114,9 @@ check_list (const gcry_md_spec_t *hash, const char *hashfilename, return grub_error (GRUB_ERR_BAD_FILE_TYPE, "invalid hash list"); expected[i] = (high << 4) | low; } - if (*p++ != ' ' || *p++ != ' ') + if ((p[0] != ' ' && p[0] != '\t') || (p[1] != ' ' && p[1] != '\t')) return grub_error (GRUB_ERR_BAD_FILE_TYPE, "invalid hash list"); + p += 2; if (prefix) { char *filename; diff --git a/grub-core/commands/parttool.c b/grub-core/commands/parttool.c index 033a91871..fadf87327 100644 --- a/grub-core/commands/parttool.c +++ b/grub-core/commands/parttool.c @@ -205,6 +205,8 @@ grub_cmd_parttool (grub_command_t cmd __attribute__ ((unused)), break; name = buf; + while (grub_isspace (name[0])) + name++; if (! grub_isgraph (name[0])) continue; @@ -214,8 +216,9 @@ grub_cmd_parttool (grub_command_t cmd __attribute__ ((unused)), continue; *p = '\0'; - while (*++p == ' ') - ; + p++; + while (*p == ' ' || *p == '\t') + p++; if (! grub_isgraph (*p)) continue; diff --git a/grub-core/normal/cmdline.c b/grub-core/normal/cmdline.c index 0e8a1adbf..14ac1d7bb 100644 --- a/grub-core/normal/cmdline.c +++ b/grub-core/normal/cmdline.c @@ -630,11 +630,6 @@ grub_cmdline_get (const char *prompt_translated) grub_xputs ("\n"); grub_refresh (); - /* Remove leading spaces. */ - lpos = 0; - while (buf[lpos] == ' ') - lpos++; - histpos = 0; if (strlen_ucs4 (buf) > 0) { @@ -643,7 +638,7 @@ grub_cmdline_get (const char *prompt_translated) grub_history_add (empty, 0); } - ret = grub_ucs4_to_utf8_alloc (buf + lpos, llen - lpos + 1); + ret = grub_ucs4_to_utf8_alloc (buf, llen + 1); grub_free (buf); grub_free (cl_terms); return ret; diff --git a/grub-core/normal/crypto.c b/grub-core/normal/crypto.c index c87a55109..e753dd799 100644 --- a/grub-core/normal/crypto.c +++ b/grub-core/normal/crypto.c @@ -116,14 +116,17 @@ read_crypto_list (const char *prefix) break; name = buf; - + while (grub_isspace (name[0])) + name++; + p = grub_strchr (name, ':'); if (! p) continue; *p = '\0'; - while (*++p == ' ') - ; + p++; + while (*p == ' ' || *p == '\t') + p++; cur = grub_malloc (sizeof (*cur)); if (!cur) diff --git a/grub-core/normal/dyncmd.c b/grub-core/normal/dyncmd.c index de45b58d6..2e473b9ea 100644 --- a/grub-core/normal/dyncmd.c +++ b/grub-core/normal/dyncmd.c @@ -141,6 +141,9 @@ read_command_list (const char *prefix) break; name = buf; + while (grub_isspace (name[0])) + name++; + if (*name == '*') { name++; @@ -155,8 +158,9 @@ read_command_list (const char *prefix) continue; *p = '\0'; - while (*++p == ' ') - ; + p++; + while (*p == ' ' || *p == '\t') + p++; if (! grub_isgraph (*p)) continue; diff --git a/grub-core/normal/main.c b/grub-core/normal/main.c index 0fd7c8c3e..1963fe485 100644 --- a/grub-core/normal/main.c +++ b/grub-core/normal/main.c @@ -45,10 +45,10 @@ char * grub_file_getline (grub_file_t file) { char c; - int pos = 0; - int literal = 0; + grub_size_t pos = 0; char *cmdline; - int max_len = 64; + int have_newline = 0; + grub_size_t max_len = 64; /* Initially locate some space. */ cmdline = grub_malloc (max_len); @@ -64,59 +64,32 @@ grub_file_getline (grub_file_t file) if (c == '\r') continue; - /* Replace tabs with spaces. */ - if (c == '\t') - c = ' '; - /* The previous is a backslash, then... */ - if (literal) + if (pos >= max_len) { - /* If it is a newline, replace it with a space and continue. */ - if (c == '\n') + char *old_cmdline = cmdline; + max_len = max_len * 2; + cmdline = grub_realloc (cmdline, max_len); + if (! cmdline) { - c = ' '; - - /* Go back to overwrite the backslash. */ - if (pos > 0) - pos--; + grub_free (old_cmdline); + return 0; } - - literal = 0; } - if (c == '\\') - literal = 1; - - if (pos == 0) + if (c == '\n') { - if (! grub_isspace (c)) - cmdline[pos++] = c; + have_newline = 1; + break; } - else - { - if (pos >= max_len) - { - char *old_cmdline = cmdline; - max_len = max_len * 2; - cmdline = grub_realloc (cmdline, max_len); - if (! cmdline) - { - grub_free (old_cmdline); - return 0; - } - } - if (c == '\n') - break; - - cmdline[pos++] = c; - } + cmdline[pos++] = c; } cmdline[pos] = '\0'; /* If the buffer is empty, don't return anything at all. */ - if (pos == 0) + if (pos == 0 && !have_newline) { grub_free (cmdline); cmdline = 0; diff --git a/grub-core/normal/term.c b/grub-core/normal/term.c index d47bf3567..cb5dd8297 100644 --- a/grub-core/normal/term.c +++ b/grub-core/normal/term.c @@ -338,7 +338,11 @@ read_terminal_list (const char *prefix) if (! buf) break; - switch (buf[0]) + p = buf; + while (grub_isspace (p[0])) + p++; + + switch (p[0]) { case 'i': target = &grub_term_input_autoload; @@ -351,15 +355,15 @@ read_terminal_list (const char *prefix) if (!target) continue; - name = buf + 1; + name = p + 1; p = grub_strchr (name, ':'); if (! p) continue; - - *p = '\0'; - while (*++p == ' ') - ; + + p++; + while (*p == ' ' || *p == '\t') + p++; cur = grub_malloc (sizeof (*cur)); if (!cur) diff --git a/tests/grub_script_echo1.in b/tests/grub_script_echo1.in index 54395774f..82a1198c9 100644 --- a/tests/grub_script_echo1.in +++ b/tests/grub_script_echo1.in @@ -20,6 +20,9 @@ echo one two three echo "one two three" echo 'one two three' + echo "one two three" + echo "one two three" + echo "one two three" # empty arguments echo a "" b @@ -87,6 +90,13 @@ echo one'two echo one'two \'three +echo "one\ +" +echo "one\ +\"" +echo "one\ +two" + # echo "one\ # two" # echo 'one\ @@ -99,5 +109,40 @@ echo one'two # # two" +echo "one + " +echo "one + \"" +echo "one + two" + +echo one"two + "three +echo one"two + \""three +echo one"two +\"three\" + four" + +echo 'one + ' +echo 'one + \' +echo 'one + two' +echo one'two + ' +echo one'two + \' +echo one'two + \'three + +echo "one\ + " +echo "one\ + \"" +echo "one\ + two" + if test x$grubshell = xyes; then insmod regexp; fi echo /boot/grub/i386-pc/normal.mod diff --git a/util/grub-menulst2cfg.c b/util/grub-menulst2cfg.c index 1f41ee8f5..77441570a 100644 --- a/util/grub-menulst2cfg.c +++ b/util/grub-menulst2cfg.c @@ -80,12 +80,9 @@ main (int argc, char **argv) { char *oldname = NULL; char *newsuffix; - char *ptr; - - for (ptr = buf; *ptr && grub_isspace (*ptr); ptr++); oldname = entryname; - parsed = grub_legacy_parse (ptr, &entryname, &newsuffix); + parsed = grub_legacy_parse (buf, &entryname, &newsuffix); if (newsuffix) { suffixlen += strlen (newsuffix);