(root)/
glibc-2.38/
misc/
bug18240.c
       1  /* Test integer wraparound in hcreate.
       2     Copyright (C) 2016-2023 Free Software Foundation, Inc.
       3     This file is part of the GNU C Library.
       4  
       5     The GNU C Library is free software; you can redistribute it and/or
       6     modify it under the terms of the GNU Lesser General Public
       7     License as published by the Free Software Foundation; either
       8     version 2.1 of the License, or (at your option) any later version.
       9  
      10     The GNU C Library is distributed in the hope that it will be useful,
      11     but WITHOUT ANY WARRANTY; without even the implied warranty of
      12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      13     Lesser General Public License for more details.
      14  
      15     You should have received a copy of the GNU Lesser General Public
      16     License along with the GNU C Library; if not, see
      17     <https://www.gnu.org/licenses/>.  */
      18  
      19  #include <errno.h>
      20  #include <limits.h>
      21  #include <search.h>
      22  #include <stdbool.h>
      23  #include <stdio.h>
      24  #include <stdlib.h>
      25  #include <sys/resource.h>
      26  
      27  static void
      28  test_size (size_t size)
      29  {
      30    int res = hcreate (size);
      31    if (res == 0)
      32      {
      33        if (errno == ENOMEM)
      34          return;
      35        printf ("error: hcreate (%zu): %m\n", size);
      36        exit (1);
      37      }
      38    char *keys[100];
      39    for (int i = 0; i < 100; ++i)
      40      {
      41        if (asprintf (keys + i, "%d", i) < 0)
      42          {
      43            printf ("error: asprintf: %m\n");
      44            exit (1);
      45          }
      46        ENTRY e = { keys[i], (char *) "value" };
      47        if (hsearch (e, ENTER) == NULL)
      48          {
      49            printf ("error: hsearch (\"%s\"): %m\n", keys[i]);
      50            exit (1);
      51          }
      52      }
      53    hdestroy ();
      54  
      55    for (int i = 0; i < 100; ++i)
      56      free (keys[i]);
      57  }
      58  
      59  static int
      60  do_test (void)
      61  {
      62    /* Limit the size of the process, so that memory allocation will
      63       fail without impacting the entire system.  */
      64    {
      65      struct rlimit limit;
      66      if (getrlimit (RLIMIT_AS, &limit) != 0)
      67        {
      68          printf ("getrlimit (RLIMIT_AS) failed: %m\n");
      69          return 1;
      70        }
      71      long target = 100 * 1024 * 1024;
      72      if (limit.rlim_cur == RLIM_INFINITY || limit.rlim_cur > target)
      73        {
      74          limit.rlim_cur = target;
      75          if (setrlimit (RLIMIT_AS, &limit) != 0)
      76            {
      77              printf ("setrlimit (RLIMIT_AS) failed: %m\n");
      78              return 1;
      79            }
      80        }
      81    }
      82  
      83    test_size (500);
      84    test_size (-1);
      85    test_size (-3);
      86    test_size (INT_MAX - 2);
      87    test_size (INT_MAX - 1);
      88    test_size (INT_MAX);
      89    test_size (((unsigned) INT_MAX) + 1);
      90    test_size (UINT_MAX - 2);
      91    test_size (UINT_MAX - 1);
      92    test_size (UINT_MAX);
      93    return 0;
      94  }
      95  
      96  #define TEST_FUNCTION do_test ()
      97  #include "../test-skeleton.c"