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.
This commit is contained in:
Vladimir 'phcoder' Serbinenko 2012-03-11 14:43:18 +01:00
parent 1a1ac4f6cb
commit 9fdb2d7b11
10 changed files with 104 additions and 66 deletions

View file

@ -1,3 +1,14 @@
2012-03-11 Vladimir Serbinenko <phcoder@gmail.com>
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 <phcoder@gmail.com> 2012-03-11 Vladimir Serbinenko <phcoder@gmail.com>
* grub-core/commands/cat.c (grub_cmd_cat): Fix termination key check. * grub-core/commands/cat.c (grub_cmd_cat): Fix termination key check.

View file

@ -103,6 +103,8 @@ check_list (const gcry_md_spec_t *hash, const char *hashfilename,
while (grub_free (buf), (buf = grub_file_getline (hashlist))) while (grub_free (buf), (buf = grub_file_getline (hashlist)))
{ {
const char *p = buf; const char *p = buf;
while (grub_isspace (p[0]))
p++;
for (i = 0; i < hash->mdlen; i++) for (i = 0; i < hash->mdlen; i++)
{ {
int high, low; 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"); return grub_error (GRUB_ERR_BAD_FILE_TYPE, "invalid hash list");
expected[i] = (high << 4) | low; 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"); return grub_error (GRUB_ERR_BAD_FILE_TYPE, "invalid hash list");
p += 2;
if (prefix) if (prefix)
{ {
char *filename; char *filename;

View file

@ -205,6 +205,8 @@ grub_cmd_parttool (grub_command_t cmd __attribute__ ((unused)),
break; break;
name = buf; name = buf;
while (grub_isspace (name[0]))
name++;
if (! grub_isgraph (name[0])) if (! grub_isgraph (name[0]))
continue; continue;
@ -214,8 +216,9 @@ grub_cmd_parttool (grub_command_t cmd __attribute__ ((unused)),
continue; continue;
*p = '\0'; *p = '\0';
while (*++p == ' ') p++;
; while (*p == ' ' || *p == '\t')
p++;
if (! grub_isgraph (*p)) if (! grub_isgraph (*p))
continue; continue;

View file

@ -630,11 +630,6 @@ grub_cmdline_get (const char *prompt_translated)
grub_xputs ("\n"); grub_xputs ("\n");
grub_refresh (); grub_refresh ();
/* Remove leading spaces. */
lpos = 0;
while (buf[lpos] == ' ')
lpos++;
histpos = 0; histpos = 0;
if (strlen_ucs4 (buf) > 0) if (strlen_ucs4 (buf) > 0)
{ {
@ -643,7 +638,7 @@ grub_cmdline_get (const char *prompt_translated)
grub_history_add (empty, 0); 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 (buf);
grub_free (cl_terms); grub_free (cl_terms);
return ret; return ret;

View file

@ -116,14 +116,17 @@ read_crypto_list (const char *prefix)
break; break;
name = buf; name = buf;
while (grub_isspace (name[0]))
name++;
p = grub_strchr (name, ':'); p = grub_strchr (name, ':');
if (! p) if (! p)
continue; continue;
*p = '\0'; *p = '\0';
while (*++p == ' ') p++;
; while (*p == ' ' || *p == '\t')
p++;
cur = grub_malloc (sizeof (*cur)); cur = grub_malloc (sizeof (*cur));
if (!cur) if (!cur)

View file

@ -141,6 +141,9 @@ read_command_list (const char *prefix)
break; break;
name = buf; name = buf;
while (grub_isspace (name[0]))
name++;
if (*name == '*') if (*name == '*')
{ {
name++; name++;
@ -155,8 +158,9 @@ read_command_list (const char *prefix)
continue; continue;
*p = '\0'; *p = '\0';
while (*++p == ' ') p++;
; while (*p == ' ' || *p == '\t')
p++;
if (! grub_isgraph (*p)) if (! grub_isgraph (*p))
continue; continue;

View file

@ -45,10 +45,10 @@ char *
grub_file_getline (grub_file_t file) grub_file_getline (grub_file_t file)
{ {
char c; char c;
int pos = 0; grub_size_t pos = 0;
int literal = 0;
char *cmdline; char *cmdline;
int max_len = 64; int have_newline = 0;
grub_size_t max_len = 64;
/* Initially locate some space. */ /* Initially locate some space. */
cmdline = grub_malloc (max_len); cmdline = grub_malloc (max_len);
@ -64,59 +64,32 @@ grub_file_getline (grub_file_t file)
if (c == '\r') if (c == '\r')
continue; continue;
/* Replace tabs with spaces. */
if (c == '\t')
c = ' ';
/* The previous is a backslash, then... */ if (pos >= max_len)
if (literal)
{ {
/* If it is a newline, replace it with a space and continue. */ char *old_cmdline = cmdline;
if (c == '\n') max_len = max_len * 2;
cmdline = grub_realloc (cmdline, max_len);
if (! cmdline)
{ {
c = ' '; grub_free (old_cmdline);
return 0;
/* Go back to overwrite the backslash. */
if (pos > 0)
pos--;
} }
literal = 0;
} }
if (c == '\\') if (c == '\n')
literal = 1;
if (pos == 0)
{ {
if (! grub_isspace (c)) have_newline = 1;
cmdline[pos++] = c; 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') cmdline[pos++] = c;
break;
cmdline[pos++] = c;
}
} }
cmdline[pos] = '\0'; cmdline[pos] = '\0';
/* If the buffer is empty, don't return anything at all. */ /* If the buffer is empty, don't return anything at all. */
if (pos == 0) if (pos == 0 && !have_newline)
{ {
grub_free (cmdline); grub_free (cmdline);
cmdline = 0; cmdline = 0;

View file

@ -338,7 +338,11 @@ read_terminal_list (const char *prefix)
if (! buf) if (! buf)
break; break;
switch (buf[0]) p = buf;
while (grub_isspace (p[0]))
p++;
switch (p[0])
{ {
case 'i': case 'i':
target = &grub_term_input_autoload; target = &grub_term_input_autoload;
@ -351,15 +355,15 @@ read_terminal_list (const char *prefix)
if (!target) if (!target)
continue; continue;
name = buf + 1; name = p + 1;
p = grub_strchr (name, ':'); p = grub_strchr (name, ':');
if (! p) if (! p)
continue; continue;
*p = '\0'; p++;
while (*++p == ' ') while (*p == ' ' || *p == '\t')
; p++;
cur = grub_malloc (sizeof (*cur)); cur = grub_malloc (sizeof (*cur));
if (!cur) if (!cur)

View file

@ -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'
echo "one two three"
echo "one two three"
echo "one two three"
# empty arguments # empty arguments
echo a "" b echo a "" b
@ -87,6 +90,13 @@ echo one'two
echo one'two echo one'two
\'three \'three
echo "one\
"
echo "one\
\""
echo "one\
two"
# echo "one\ # echo "one\
# two" # two"
# echo 'one\ # echo 'one\
@ -99,5 +109,40 @@ echo one'two
# #
# 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 if test x$grubshell = xyes; then insmod regexp; fi
echo /boot/grub/i386-pc/normal.mod echo /boot/grub/i386-pc/normal.mod

View file

@ -80,12 +80,9 @@ main (int argc, char **argv)
{ {
char *oldname = NULL; char *oldname = NULL;
char *newsuffix; char *newsuffix;
char *ptr;
for (ptr = buf; *ptr && grub_isspace (*ptr); ptr++);
oldname = entryname; oldname = entryname;
parsed = grub_legacy_parse (ptr, &entryname, &newsuffix); parsed = grub_legacy_parse (buf, &entryname, &newsuffix);
if (newsuffix) if (newsuffix)
{ {
suffixlen += strlen (newsuffix); suffixlen += strlen (newsuffix);