[PATCH 10/11] argp: Fix shift bug

Adhemerval Zanella adhemerval.zanella@linaro.org
Wed May 7 14:17:28 GMT 2025


>From gnulib commits 06094e390b0 and 88033d3779362a.
---
 argp/argp-parse.c | 15 +++++++++------
 1 file changed, 9 insertions(+), 6 deletions(-)

diff --git a/argp/argp-parse.c b/argp/argp-parse.c
index 82c7b784de..99f8d9ecd4 100644
--- a/argp/argp-parse.c
+++ b/argp/argp-parse.c
@@ -735,12 +735,15 @@ parser_parse_opt (struct parser *parser, int opt, char *val)
 	    }
     }
   else
-    /* A long option.  We use shifts instead of masking for extracting
-       the user value in order to preserve the sign.  */
-    err =
-      group_parse (&parser->groups[group_key - 1], &parser->state,
-		   (opt << GROUP_BITS) >> GROUP_BITS,
-		   parser->opt_data.optarg);
+    /* A long option.  Preserve the sign in the user key, without
+       invoking undefined behavior.  Assume two's complement.  */
+    {
+      int user_key =
+        ((opt & (1 << (USER_BITS - 1))) ? ~USER_MASK : 0) | (opt & USER_MASK);
+      err =
+        group_parse (&parser->groups[group_key - 1], &parser->state,
+                     user_key, parser->opt_data.optarg);
+    }
 
   if (err == EBADKEY)
     /* At least currently, an option not recognized is an error in the
-- 
2.43.0



More information about the Libc-alpha mailing list