From e35b6ac56f6582f85319ebc86d4a9b42ca5a21cb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?SZEDER=20G=C3=A1bor?= Date: Sat, 10 Jun 2017 13:41:01 +0200 Subject: [PATCH 1/5] revision.h: turn rev_info.early_output back into an unsigned int MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit rev_info.early_output started out as an unsigned int in cdcefbc97 (Add "--early-output" log flag for interactive GUI use, 2007-11-03), but later it was turned into a single bit in a bit field in cc243c3ce (show: --ignore-missing, 2011-05-18) without explanation, though the code using it still expects it to be a regular integer type and uses it as a counter. Consequently, any even number given via '--early-output=', or indeed a plain '--early-output' defaulting to 100 effectively disabled the feature. Turn rev_info.early_output back into its origin unsigned int data type, making '--early-output' work again. Signed-off-by: SZEDER Gábor Reviewed-by: Jeff King Signed-off-by: Junio C Hamano --- revision.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/revision.h b/revision.h index 9fac1a607d..f801118e10 100644 --- a/revision.h +++ b/revision.h @@ -74,8 +74,9 @@ struct rev_info { /* topo-sort */ enum rev_sort_order sort_order; - unsigned int early_output:1, - ignore_missing:1, + unsigned int early_output; + + unsigned int ignore_missing:1, ignore_missing_links:1; /* Traversal flags */ From 9ada7aee198c3644604eac1ff7cc50284b48d85f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?SZEDER=20G=C3=A1bor?= Date: Fri, 9 Jun 2017 20:17:30 +0200 Subject: [PATCH 2/5] revision.c: stricter parsing of '--no-{min,max}-parents' MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit These two options are parsed using starts_with(), allowing things like 'git log --no-min-parents-foobarbaz' to succeed. Use strcmp() instead. Signed-off-by: SZEDER Gábor Reviewed-by: Jeff King Signed-off-by: Junio C Hamano --- revision.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/revision.c b/revision.c index b37dbec378..8a40cc7b34 100644 --- a/revision.c +++ b/revision.c @@ -1777,11 +1777,11 @@ static int handle_revision_opt(struct rev_info *revs, int argc, const char **arg revs->max_parents = 1; } else if (starts_with(arg, "--min-parents=")) { revs->min_parents = atoi(arg+14); - } else if (starts_with(arg, "--no-min-parents")) { + } else if (!strcmp(arg, "--no-min-parents")) { revs->min_parents = 0; } else if (starts_with(arg, "--max-parents=")) { revs->max_parents = atoi(arg+14); - } else if (starts_with(arg, "--no-max-parents")) { + } else if (!strcmp(arg, "--no-max-parents")) { revs->max_parents = -1; } else if (!strcmp(arg, "--boundary")) { revs->boundary = 1; From dffc651ed191ff0eb3cfd0e8df83a423b4dae994 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?SZEDER=20G=C3=A1bor?= Date: Fri, 9 Jun 2017 20:17:31 +0200 Subject: [PATCH 3/5] revision.c: stricter parsing of '--early-output' MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The parsing of '--early-output' with or without its optional integer argument allowed bogus options like '--early-output-foobarbaz' to slip through and be ignored. Fix it by parsing '--early-output' in the same way as other options with an optional argument are parsed. Furthermore, use strtoul_ui() to parse the optional integer argument and to refuse negative numbers. While at it, use skip_prefix() instead of starts_with() and magic numbers. Signed-off-by: SZEDER Gábor Reviewed-by: Jeff King Signed-off-by: Junio C Hamano --- revision.c | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/revision.c b/revision.c index 8a40cc7b34..b942fed748 100644 --- a/revision.c +++ b/revision.c @@ -1750,16 +1750,13 @@ static int handle_revision_opt(struct rev_info *revs, int argc, const char **arg } else if (!strcmp(arg, "--author-date-order")) { revs->sort_order = REV_SORT_BY_AUTHOR_DATE; revs->topo_order = 1; - } else if (starts_with(arg, "--early-output")) { - int count = 100; - switch (arg[14]) { - case '=': - count = atoi(arg+15); - /* Fallthrough */ - case 0: - revs->topo_order = 1; - revs->early_output = count; - } + } else if (!strcmp(arg, "--early-output")) { + revs->early_output = 100; + revs->topo_order = 1; + } else if (skip_prefix(arg, "--early-output=", &optarg)) { + if (strtoul_ui(optarg, 10, &revs->early_output) < 0) + die("'%s': not a non-negative integer", optarg); + revs->topo_order = 1; } else if (!strcmp(arg, "--parents")) { revs->rewrite_parents = 1; revs->print_parents = 1; From 479b3d978597110208d5a7623a626b28d5c801e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?SZEDER=20G=C3=A1bor?= Date: Fri, 9 Jun 2017 20:17:32 +0200 Subject: [PATCH 4/5] revision.c: use skip_prefix() in handle_revision_opt() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Instead of starts_with() and a bunch of magic numbers. Signed-off-by: SZEDER Gábor Reviewed-by: Jeff King Signed-off-by: Junio C Hamano --- revision.c | 48 +++++++++++++++++++++++------------------------- 1 file changed, 23 insertions(+), 25 deletions(-) diff --git a/revision.c b/revision.c index b942fed748..bb2e094549 100644 --- a/revision.c +++ b/revision.c @@ -1690,8 +1690,8 @@ static int handle_revision_opt(struct rev_info *revs, int argc, const char **arg revs->max_count = atoi(argv[1]); revs->no_walk = 0; return 2; - } else if (starts_with(arg, "-n")) { - revs->max_count = atoi(arg + 2); + } else if (skip_prefix(arg, "-n", &optarg)) { + revs->max_count = atoi(optarg); revs->no_walk = 0; } else if ((argcount = parse_long_opt("max-age", argv, &optarg))) { revs->max_age = atoi(optarg); @@ -1772,12 +1772,12 @@ static int handle_revision_opt(struct rev_info *revs, int argc, const char **arg revs->min_parents = 2; } else if (!strcmp(arg, "--no-merges")) { revs->max_parents = 1; - } else if (starts_with(arg, "--min-parents=")) { - revs->min_parents = atoi(arg+14); + } else if (skip_prefix(arg, "--min-parents=", &optarg)) { + revs->min_parents = atoi(optarg); } else if (!strcmp(arg, "--no-min-parents")) { revs->min_parents = 0; - } else if (starts_with(arg, "--max-parents=")) { - revs->max_parents = atoi(arg+14); + } else if (skip_prefix(arg, "--max-parents=", &optarg)) { + revs->max_parents = atoi(optarg); } else if (!strcmp(arg, "--no-max-parents")) { revs->max_parents = -1; } else if (!strcmp(arg, "--boundary")) { @@ -1859,14 +1859,15 @@ static int handle_revision_opt(struct rev_info *revs, int argc, const char **arg revs->verbose_header = 1; revs->pretty_given = 1; get_commit_format(NULL, revs); - } else if (starts_with(arg, "--pretty=") || starts_with(arg, "--format=")) { + } else if (skip_prefix(arg, "--pretty=", &optarg) || + skip_prefix(arg, "--format=", &optarg)) { /* * Detached form ("--pretty X" as opposed to "--pretty=X") * not allowed, since the argument is optional. */ revs->verbose_header = 1; revs->pretty_given = 1; - get_commit_format(arg+9, revs); + get_commit_format(optarg, revs); } else if (!strcmp(arg, "--expand-tabs")) { revs->expand_tabs_in_log = 8; } else if (!strcmp(arg, "--no-expand-tabs")) { @@ -1884,26 +1885,23 @@ static int handle_revision_opt(struct rev_info *revs, int argc, const char **arg revs->show_signature = 1; } else if (!strcmp(arg, "--no-show-signature")) { revs->show_signature = 0; - } else if (!strcmp(arg, "--show-linear-break") || - starts_with(arg, "--show-linear-break=")) { - if (starts_with(arg, "--show-linear-break=")) - revs->break_bar = xstrdup(arg + 20); - else - revs->break_bar = " .........."; + } else if (!strcmp(arg, "--show-linear-break")) { + revs->break_bar = " .........."; revs->track_linear = 1; revs->track_first_time = 1; - } else if (starts_with(arg, "--show-notes=") || - starts_with(arg, "--notes=")) { + } else if (skip_prefix(arg, "--show-linear-break=", &optarg)) { + revs->break_bar = xstrdup(optarg); + revs->track_linear = 1; + revs->track_first_time = 1; + } else if (skip_prefix(arg, "--show-notes=", &optarg) || + skip_prefix(arg, "--notes=", &optarg)) { struct strbuf buf = STRBUF_INIT; revs->show_notes = 1; revs->show_notes_given = 1; - if (starts_with(arg, "--show-notes")) { - if (revs->notes_opt.use_default_notes < 0) - revs->notes_opt.use_default_notes = 1; - strbuf_addstr(&buf, arg+13); - } - else - strbuf_addstr(&buf, arg+8); + if (starts_with(arg, "--show-notes=") && + revs->notes_opt.use_default_notes < 0) + revs->notes_opt.use_default_notes = 1; + strbuf_addstr(&buf, optarg); expand_notes_ref(&buf); string_list_append(&revs->notes_opt.extra_notes_refs, strbuf_detach(&buf, NULL)); @@ -1940,8 +1938,8 @@ static int handle_revision_opt(struct rev_info *revs, int argc, const char **arg revs->abbrev = 0; } else if (!strcmp(arg, "--abbrev")) { revs->abbrev = DEFAULT_ABBREV; - } else if (starts_with(arg, "--abbrev=")) { - revs->abbrev = strtoul(arg + 9, NULL, 10); + } else if (skip_prefix(arg, "--abbrev=", &optarg)) { + revs->abbrev = strtoul(optarg, NULL, 10); if (revs->abbrev < MINIMUM_ABBREV) revs->abbrev = MINIMUM_ABBREV; else if (revs->abbrev > 40) From 8b1d9136e1ca0125ad6f62667b039f1f59513e5a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?SZEDER=20G=C3=A1bor?= Date: Fri, 9 Jun 2017 20:17:33 +0200 Subject: [PATCH 5/5] revision.c: use skip_prefix() in handle_revision_pseudo_opt() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Instead of starts_with() and a bunch of magic numbers. Signed-off-by: SZEDER Gábor Reviewed-by: Jeff King Signed-off-by: Junio C Hamano --- revision.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/revision.c b/revision.c index bb2e094549..2f6f75f960 100644 --- a/revision.c +++ b/revision.c @@ -2099,20 +2099,20 @@ static int handle_revision_pseudo_opt(const char *submodule, } else if ((argcount = parse_long_opt("exclude", argv, &optarg))) { add_ref_exclusion(&revs->ref_excludes, optarg); return argcount; - } else if (starts_with(arg, "--branches=")) { + } else if (skip_prefix(arg, "--branches=", &optarg)) { struct all_refs_cb cb; init_all_refs_cb(&cb, revs, *flags); - for_each_glob_ref_in(handle_one_ref, arg + 11, "refs/heads/", &cb); + for_each_glob_ref_in(handle_one_ref, optarg, "refs/heads/", &cb); clear_ref_exclusion(&revs->ref_excludes); - } else if (starts_with(arg, "--tags=")) { + } else if (skip_prefix(arg, "--tags=", &optarg)) { struct all_refs_cb cb; init_all_refs_cb(&cb, revs, *flags); - for_each_glob_ref_in(handle_one_ref, arg + 7, "refs/tags/", &cb); + for_each_glob_ref_in(handle_one_ref, optarg, "refs/tags/", &cb); clear_ref_exclusion(&revs->ref_excludes); - } else if (starts_with(arg, "--remotes=")) { + } else if (skip_prefix(arg, "--remotes=", &optarg)) { struct all_refs_cb cb; init_all_refs_cb(&cb, revs, *flags); - for_each_glob_ref_in(handle_one_ref, arg + 10, "refs/remotes/", &cb); + for_each_glob_ref_in(handle_one_ref, optarg, "refs/remotes/", &cb); clear_ref_exclusion(&revs->ref_excludes); } else if (!strcmp(arg, "--reflog")) { add_reflogs_to_pending(revs, *flags); @@ -2122,14 +2122,14 @@ static int handle_revision_pseudo_opt(const char *submodule, *flags ^= UNINTERESTING | BOTTOM; } else if (!strcmp(arg, "--no-walk")) { revs->no_walk = REVISION_WALK_NO_WALK_SORTED; - } else if (starts_with(arg, "--no-walk=")) { + } else if (skip_prefix(arg, "--no-walk=", &optarg)) { /* * Detached form ("--no-walk X" as opposed to "--no-walk=X") * not allowed, since the argument is optional. */ - if (!strcmp(arg + 10, "sorted")) + if (!strcmp(optarg, "sorted")) revs->no_walk = REVISION_WALK_NO_WALK_SORTED; - else if (!strcmp(arg + 10, "unsorted")) + else if (!strcmp(optarg, "unsorted")) revs->no_walk = REVISION_WALK_NO_WALK_UNSORTED; else return error("invalid argument to --no-walk");