Skip to content

Commit 6aead43

Browse files
meyeringJunio C Hamano
authored andcommitted
sscanf/strtoul: parse integers robustly
* builtin-grep.c (strtoul_ui): Move function definition from here, to... * git-compat-util.h (strtoul_ui): ...here, with an added "base" parameter. * builtin-grep.c (cmd_grep): Update use of strtoul_ui to include base, "10". * builtin-update-index.c (read_index_info): Diagnose an invalid mode integer that is out of range or merely larger than INT_MAX. (cmd_update_index): Use strtoul_ui, not sscanf. * convert-objects.c (write_subdirectory): Likewise. Signed-off-by: Jim Meyering <jim@meyering.net> Signed-off-by: Junio C Hamano <junkio@cox.net>
1 parent 171ddd9 commit 6aead43

File tree

4 files changed

+22
-18
lines changed

4 files changed

+22
-18
lines changed

builtin-grep.c

Lines changed: 1 addition & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -434,19 +434,6 @@ static const char emsg_missing_context_len[] =
434434
static const char emsg_missing_argument[] =
435435
"option requires an argument -%s";
436436

437-
static int strtoul_ui(char const *s, unsigned int *result)
438-
{
439-
unsigned long ul;
440-
char *p;
441-
442-
errno = 0;
443-
ul = strtoul(s, &p, 10);
444-
if (errno || *p || p == s || (unsigned int) ul != ul)
445-
return -1;
446-
*result = ul;
447-
return 0;
448-
}
449-
450437
int cmd_grep(int argc, const char **argv, const char *prefix)
451438
{
452439
int hit = 0;
@@ -569,7 +556,7 @@ int cmd_grep(int argc, const char **argv, const char *prefix)
569556
scan = arg + 1;
570557
break;
571558
}
572-
if (strtoul_ui(scan, &num))
559+
if (strtoul_ui(scan, 10, &num))
573560
die(emsg_invalid_context_len, scan);
574561
switch (arg[1]) {
575562
case 'A':

builtin-update-index.c

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -227,6 +227,7 @@ static void read_index_info(int line_termination)
227227
char *path_name;
228228
unsigned char sha1[20];
229229
unsigned int mode;
230+
unsigned long ul;
230231
int stage;
231232

232233
/* This reads lines formatted in one of three formats:
@@ -249,9 +250,12 @@ static void read_index_info(int line_termination)
249250
if (buf.eof)
250251
break;
251252

252-
mode = strtoul(buf.buf, &ptr, 8);
253-
if (ptr == buf.buf || *ptr != ' ')
253+
errno = 0;
254+
ul = strtoul(buf.buf, &ptr, 8);
255+
if (ptr == buf.buf || *ptr != ' '
256+
|| errno || (unsigned int) ul != ul)
254257
goto bad_line;
258+
mode = ul;
255259

256260
tab = strchr(ptr, '\t');
257261
if (!tab || tab - ptr < 41)
@@ -547,7 +551,7 @@ int cmd_update_index(int argc, const char **argv, const char *prefix)
547551
if (i+3 >= argc)
548552
die("git-update-index: --cacheinfo <mode> <sha1> <path>");
549553

550-
if ((sscanf(argv[i+1], "%o", &mode) != 1) ||
554+
if ((strtoul_ui(argv[i+1], 8, &mode) != 1) ||
551555
get_sha1_hex(argv[i+2], sha1) ||
552556
add_cacheinfo(mode, sha1, argv[i+3], 0))
553557
die("git-update-index: --cacheinfo"

convert-objects.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ static int write_subdirectory(void *buffer, unsigned long size, const char *base
8888
unsigned int mode;
8989
char *slash, *origpath;
9090

91-
if (!path || sscanf(buffer, "%o", &mode) != 1)
91+
if (!path || strtoul_ui(buffer, 8, &mode) != 1)
9292
die("bad tree conversion");
9393
mode = convert_mode(mode);
9494
path++;

git-compat-util.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -301,4 +301,17 @@ static inline int prefixcmp(const char *str, const char *prefix)
301301
return strncmp(str, prefix, strlen(prefix));
302302
}
303303

304+
static inline int strtoul_ui(char const *s, int base, unsigned int *result)
305+
{
306+
unsigned long ul;
307+
char *p;
308+
309+
errno = 0;
310+
ul = strtoul(s, &p, base);
311+
if (errno || *p || p == s || (unsigned int) ul != ul)
312+
return -1;
313+
*result = ul;
314+
return 0;
315+
}
316+
304317
#endif

0 commit comments

Comments
 (0)