1
0
mirror of git://git.sv.gnu.org/coreutils.git synced 2026-05-31 14:56:58 +02:00

Don't modify argv in dd due to ',' in arguments.

* src/dd.c: Include quotearg.h.
(operand_matches): New function.
(parse_symbols, operand_is): Use it.
(parse_symbols): 1st arg is now const pointer.  Don't modify it.
msgid arg is now just the message, not a format.
(scanargs): Add some 'const's to check for problems like the above.
This commit is contained in:
Paul Eggert
2008-01-31 09:22:49 +01:00
committed by Jim Meyering
parent 62b7b422a2
commit e8bb94a4e3
2 changed files with 48 additions and 32 deletions
+10
View File
@@ -1,3 +1,13 @@
2008-01-30 Paul Eggert <eggert@cs.ucla.edu>
Don't modify argv in dd due to ',' in arguments.
* src/dd.c: Include quotearg.h.
(operand_matches): New function.
(parse_symbols, operand_is): Use it.
(parse_symbols): 1st arg is now const pointer. Don't modify it.
msgid arg is now just the message, not a format.
(scanargs): Add some 'const's to check for problems like the above.
2008-01-30 Jim Meyering <meyering@redhat.com>
* src/c99-to-c89.diff: Adjust remove.c offsets, again.
+38 -32
View File
@@ -1,5 +1,5 @@
/* dd -- convert a file while copying it.
Copyright (C) 85, 90, 91, 1995-2007 Free Software Foundation, Inc.
Copyright (C) 85, 90, 91, 1995-2008 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -31,6 +31,7 @@
#include "human.h"
#include "long-options.h"
#include "quote.h"
#include "quotearg.h"
#include "xstrtol.h"
#include "xtime.h"
@@ -796,41 +797,50 @@ write_output (void)
oc = 0;
}
/* Return true if STR is of the form "PATTERN" or "PATTERNDELIM...". */
static bool
operand_matches (char const *str, char const *pattern, char delim)
{
while (*pattern)
if (*str++ != *pattern++)
return false;
return !*str || *str == delim;
}
/* Interpret one "conv=..." or similar operand STR according to the
symbols in TABLE, returning the flags specified. If the operand
cannot be parsed, use ERROR_MSGID to generate a diagnostic.
As a by product, this function replaces each `,' in STR with a NUL byte. */
cannot be parsed, use ERROR_MSGID to generate a diagnostic. */
static int
parse_symbols (char *str, struct symbol_value const *table,
parse_symbols (char const *str, struct symbol_value const *table,
char const *error_msgid)
{
int value = 0;
do
for (;;)
{
char const *strcomma = strchr (str, ',');
struct symbol_value const *entry;
char *new = strchr (str, ',');
if (new != NULL)
*new++ = '\0';
for (entry = table; ; entry++)
for (entry = table;
! (operand_matches (str, entry->symbol, ',') && entry->value);
entry++)
{
if (! entry->symbol[0])
{
error (0, 0, _(error_msgid), quote (str));
size_t slen = strcomma ? strcomma - str : strlen (str);
error (0, 0, "%s: %s", _(error_msgid),
quotearg_n_style_mem (0, locale_quoting_style, str, slen));
usage (EXIT_FAILURE);
}
if (STREQ (entry->symbol, str))
{
if (! entry->value)
error (EXIT_FAILURE, 0, _(error_msgid), quote (str));
value |= entry->value;
break;
}
}
str = new;
value |= entry->value;
if (!strcomma)
break;
str = strcomma + 1;
}
while (str);
return value;
}
@@ -867,29 +877,25 @@ parse_integer (const char *str, bool *invalid)
return n;
}
/* Return true if OPERAND is of the form "NAME=...". */
/* OPERAND is of the form "X=...". Return true if X is NAME. */
static bool
operand_is (char const *operand, char const *name)
{
while (*name)
if (*name++ != *operand++)
return false;
return *operand == '=';
return operand_matches (operand, name, '=');
}
static void
scanargs (int argc, char **argv)
scanargs (int argc, char *const *argv)
{
int i;
size_t blocksize = 0;
for (i = optind; i < argc; i++)
{
char *name, *val;
char const *name = argv[i];
char const *val = strchr (name, '=');
name = argv[i];
val = strchr (name, '=');
if (val == NULL)
{
error (0, 0, _("unrecognized operand %s"), quote (name));
@@ -903,16 +909,16 @@ scanargs (int argc, char **argv)
output_file = val;
else if (operand_is (name, "conv"))
conversions_mask |= parse_symbols (val, conversions,
N_("invalid conversion: %s"));
N_("invalid conversion"));
else if (operand_is (name, "iflag"))
input_flags |= parse_symbols (val, flags,
N_("invalid input flag: %s"));
N_("invalid input flag"));
else if (operand_is (name, "oflag"))
output_flags |= parse_symbols (val, flags,
N_("invalid output flag: %s"));
N_("invalid output flag"));
else if (operand_is (name, "status"))
status_flags |= parse_symbols (val, statuses,
N_("invalid status flag: %s"));
N_("invalid status flag"));
else
{
bool invalid = false;