1 /* Test integer wraparound in hcreate.
2    Copyright (C) 2016-2022 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
test_size(size_t size)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
do_test(void)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"
98