From 4f20b75c6133425f2b8c369bb1ecfbd7d3410353 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Tue, 11 Feb 2020 14:39:43 +1030 Subject: [PATCH] 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 --- ccan/opt/opt.c | 3 ++- ccan/opt/test/run-unregister.c | 7 +++---- 2 files changed, 5 insertions(+), 5 deletions(-) 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); -- 2.39.2