]> git.ipfire.org Git - thirdparty/glibc.git/commitdiff
argp: Fix shift bug
authorAdhemerval Zanella <adhemerval.zanella@linaro.org>
Wed, 7 May 2025 14:17:28 +0000 (11:17 -0300)
committerAdhemerval Zanella <adhemerval.zanella@linaro.org>
Mon, 2 Jun 2025 16:32:19 +0000 (13:32 -0300)
From gnulib commits 06094e390b0 and 88033d3779362a.
Reviewed-by: Florian Weimer <fweimer@redhat.com>
argp/argp-parse.c

index 82c7b784dee8ccd0d7c613ee8dcf1ea5514760d1..99f8d9ecd408b11af03e4dc749583096c2e9e61d 100644 (file)
@@ -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