git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[PATCH] git-grep: don't use sscanf

From
Jim Meyering <jim@meyering.net>
Date
Mar 12, 2007, 12:11 UTC
Message-ID
<87lki2r79q.fsf@rho.meyering.net>

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>
---
 builtin-grep.c |   14 +++++++++++++-
 1 files changed, 13 insertions(+), 1 deletions(-)
diff --git a/builtin-grep.c b/builtin-grep.c
index 694da5b..9a151bf 100644
--- a/builtin-grep.c
+++ b/builtin-grep.c
@@ -431,6 +431,18 @@ 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)
+{
+	char *p;
+	errno = 0;
+	unsigned long ul = strtoul (s, &p, 10);
+	if (errno || *p || p == s || (unsigned int) ul != ul)
+		return 0;
+	*result = ul;
+	return 1;
+}
+
 int cmd_grep(int argc, const char **argv, const char *prefix)
 {
 	int hit = 0;
@@ -553,7 +565,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':
--
1.5.0.3.353.g8a3f
Message 1 of 1 in “git-grep: don't use sscanf”
  1. git-grep: don't use sscanfJim Meyering, Mar 12, 2007

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.