From: Rusty Russell Date: Tue, 11 Feb 2020 04:09:43 +0000 (+1030) Subject: opt: fix opt_unregister. X-Git-Url: http://git.ozlabs.org/?a=commitdiff_plain;h=4f20b75c6133425f2b8c369bb1ecfbd7d3410353;p=ccan opt: fix opt_unregister. Instead of memmoving N structs, we were memmoving N bytes. But why did the test pass then? It was doing memmove(..., 1) instead of memmove(..., sizeof(struct opt_table)! Because the two structures were really similar; the main difference was the first entry, which points to the name. But they were allocated consecutively, and Intel being little-endian, the only difference was the first byte! Thus memmove(1) was enough to make it "work". Change two options in the test to be sufficiently different, and the bug shows up. Signed-off-by: Rusty Russell --- diff --git a/ccan/opt/opt.c b/ccan/opt/opt.c index d4601dfb..d376a598 100644 --- a/ccan/opt/opt.c +++ b/ccan/opt/opt.c @@ -189,7 +189,8 @@ bool opt_unregister(const char *names) if (found == -1) return false; opt_count--; - memmove(&opt_table[found], &opt_table[found+1], opt_count - found); + memmove(&opt_table[found], &opt_table[found+1], + (opt_count - found) * sizeof(opt_table[found])); return true; } diff --git a/ccan/opt/test/run-unregister.c b/ccan/opt/test/run-unregister.c index 06bf58a0..d2dc469b 100644 --- a/ccan/opt/test/run-unregister.c +++ b/ccan/opt/test/run-unregister.c @@ -10,11 +10,10 @@ int main(int argc, char *argv[]) { const char *myname = argv[0]; - plan_tests(14); + plan_tests(15); - /* Simple short arg.*/ opt_register_noarg("--aaa|-a", test_noarg, NULL, "AAAAAAll"); - opt_register_noarg("-b", test_noarg, NULL, "AAAAAAll"); + opt_register_arg("-b", test_arg, NULL, "bbb", "b"); /* We can't unregister wrong ones, but can unregister correct one */ ok1(!opt_unregister("--aaa")); @@ -22,7 +21,7 @@ int main(int argc, char *argv[]) ok1(opt_unregister("--aaa|-a")); /* Arg parsing works as if we'd never registered it */ - ok1(parse_args(&argc, &argv, "-b", NULL)); + ok1(parse_args(&argc, &argv, "-bbbb", NULL)); ok1(argc == 1); ok1(argv[0] == myname); ok1(argv[1] == NULL);