Skip to content

Commit

Permalink
git-grep: don't use sscanf
Browse files Browse the repository at this point in the history
If you use scanf or sscanf to parse integers, your code probably
accepts bogus inputs.  For example, builtin-grep (aka git-grep) uses
sscanf(scan, "%u", &num) to parse the integer argument to -A, -B, -C.
Currently, "-C 1,000" and "-C 4294967297" are both treated just like
"-C 1":

    $ git-grep -h -C 4294967297 juggle
    out and you may find it easier to switch back and forth if you
    juggle multiple lines of development simultaneously. Of
    course, you will pay the price of more disk usage to hold

The obvious fix is to use strtoul instead.  But using a bare strtoul is
too messy, at least when done properly, so I've added a wrapper function.

The new function in the patch below belongs elsewhere if it would be
useful in replacing any of the four remaining uses of sscanf.

One final note:  With this change, I get a slightly different
diagnostic depending on the context size:

  $ ./git-grep -h -C 4294967296 juggle
  fatal: 4294967296: invalid context length argument
  [Exit 128]
  $ ./git-grep -h -C 4294967295 juggle
  grep: 4294967295: invalid context length argument

  [Exit 1]

A common convention that makes it easy to identify the source
of a diagnostic is to include the program name before the first ":".
Whether that should be "git" or "git-grep" is another question.
Using "grep" or "fatal" is misleading.

Signed-off-by: Jim Meyering <jim@meyering.net>
Signed-off-by: Junio C Hamano <junkio@cox.net>
  • Loading branch information
Jim Meyering authored and Junio C Hamano committed Mar 14, 2007
1 parent 6cd7895 commit 09f2825
Showing 1 changed file with 14 additions and 1 deletion.
15 changes: 14 additions & 1 deletion builtin-grep.c
Original file line number Diff line number Diff line change
Expand Up @@ -431,6 +431,19 @@ static const char emsg_missing_context_len[] =
static const char emsg_missing_argument[] =
"option requires an argument -%s";

static int strtoul_ui(char const *s, unsigned int *result)
{
unsigned long ul;
char *p;

errno = 0;
ul = strtoul(s, &p, 10);
if (errno || *p || p == s || (unsigned int) ul != ul)
return -1;
*result = ul;
return 0;
}

int cmd_grep(int argc, const char **argv, const char *prefix)
{
int hit = 0;
Expand Down Expand Up @@ -553,7 +566,7 @@ int cmd_grep(int argc, const char **argv, const char *prefix)
scan = arg + 1;
break;
}
if (sscanf(scan, "%u", &num) != 1)
if (strtoul_ui(scan, &num))
die(emsg_invalid_context_len, scan);
switch (arg[1]) {
case 'A':
Expand Down

0 comments on commit 09f2825

Please sign in to comment.