1 /* Test inet_pton functions.
2    Copyright (C) 2017-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 <arpa/inet.h>
20 #include <resolv/resolv-internal.h>
21 #include <stdbool.h>
22 #include <stdio.h>
23 #include <string.h>
24 #include <support/check.h>
25 #include <support/next_to_fault.h>
26 #include <support/xunistd.h>
27 #include <unistd.h>
28 
29 struct test_case
30 {
31   /* The input data.  */
32   const char *input;
33 
34   /* True if AF_INET parses successfully.  */
35   bool ipv4_ok;
36 
37   /* True if AF_INET6 parses successfully.  */
38   bool ipv6_ok;
39 
40   /* Expected result for AF_INET.  */
41   unsigned char ipv4_expected[4];
42 
43   /* Expected result for AF_INET6.  */
44   unsigned char ipv6_expected[16];
45 };
46 
47 static void
check_result(const char * what,const struct test_case * t,int family,void * result_buffer,int inet_ret)48 check_result (const char *what, const struct test_case *t, int family,
49               void *result_buffer, int inet_ret)
50 {
51   TEST_VERIFY_EXIT (inet_ret >= -1);
52   TEST_VERIFY_EXIT (inet_ret <= 1);
53 
54   int ok;
55   const unsigned char *expected;
56   size_t result_size;
57   switch (family)
58     {
59     case AF_INET:
60       ok = t->ipv4_ok;
61       expected = t->ipv4_expected;
62       result_size = 4;
63       break;
64     case AF_INET6:
65       ok = t->ipv6_ok;
66       expected = t->ipv6_expected;
67       result_size = 16;
68       break;
69     default:
70       FAIL_EXIT1 ("invalid address family %d", family);
71     }
72 
73   if (inet_ret != ok)
74     {
75       support_record_failure ();
76       printf ("error: %s return value mismatch for [[%s]], family %d\n"
77               "  expected: %d\n"
78               "  actual: %d\n",
79               what, t->input, family, ok, inet_ret);
80       return;
81     }
82   if (memcmp (result_buffer, expected, result_size) != 0)
83     {
84       support_record_failure ();
85       printf ("error: %s result mismatch for [[%s]], family %d\n",
86               what, t->input, family);
87     }
88 }
89 
90 static void
run_one_test(const struct test_case * t)91 run_one_test (const struct test_case *t)
92 {
93   size_t test_len = strlen (t->input);
94 
95   struct support_next_to_fault ntf_out4 = support_next_to_fault_allocate (4);
96   struct support_next_to_fault ntf_out6 = support_next_to_fault_allocate (16);
97 
98   /* inet_pton requires NUL termination.  */
99   {
100     struct support_next_to_fault ntf_in
101       = support_next_to_fault_allocate (test_len + 1);
102     memcpy (ntf_in.buffer, t->input, test_len + 1);
103     memset (ntf_out4.buffer, 0, 4);
104     check_result ("inet_pton", t, AF_INET, ntf_out4.buffer,
105                   inet_pton (AF_INET, ntf_in.buffer, ntf_out4.buffer));
106     memset (ntf_out6.buffer, 0, 16);
107     check_result ("inet_pton", t, AF_INET6, ntf_out6.buffer,
108                   inet_pton (AF_INET6, ntf_in.buffer, ntf_out6.buffer));
109     support_next_to_fault_free (&ntf_in);
110   }
111 
112   /* __inet_pton_length does not require NUL termination.  */
113   {
114     struct support_next_to_fault ntf_in
115       = support_next_to_fault_allocate (test_len);
116     memcpy (ntf_in.buffer, t->input, test_len);
117     memset (ntf_out4.buffer, 0, 4);
118     check_result ("__inet_pton_length", t, AF_INET, ntf_out4.buffer,
119                   __inet_pton_length (AF_INET, ntf_in.buffer, ntf_in.length,
120                                       ntf_out4.buffer));
121     memset (ntf_out6.buffer, 0, 16);
122     check_result ("__inet_pton_length", t, AF_INET6, ntf_out6.buffer,
123                   __inet_pton_length (AF_INET6, ntf_in.buffer, ntf_in.length,
124                                       ntf_out6.buffer));
125     support_next_to_fault_free (&ntf_in);
126   }
127 
128   support_next_to_fault_free (&ntf_out4);
129   support_next_to_fault_free (&ntf_out6);
130 }
131 
132 /* The test cases were manually crafted and the set enhanced with
133    American Fuzzy Lop.  */
134 const struct test_case test_cases[] =
135   {
136     {.input = ".:", },
137     {.input = "0.0.0.0",
138      .ipv4_ok = true,
139      .ipv4_expected = {0, 0, 0, 0},
140     },
141     {.input = "0.:", },
142     {.input = "00", },
143     {.input = "0000000", },
144     {.input = "00000000000000000", },
145     {.input = "092.", },
146     {.input = "10.0.301.2", },
147     {.input = "127.0.0.1",
148      .ipv4_ok = true,
149      .ipv4_expected = {127, 0, 0, 1},
150     },
151     {.input = "19..", },
152     {.input = "192.0.2.-1", },
153     {.input = "192.0.2.01", },
154     {.input = "192.0.2.1.", },
155     {.input = "192.0.2.1192.", },
156     {.input = "192.0.2.192.\377..", },
157     {.input = "192.0.2.256", },
158     {.input = "192.0.2.27",
159      .ipv4_ok = true,
160      .ipv4_expected = {192, 0, 2, 27},
161     },
162     {.input = "192.0.201.", },
163     {.input = "192.0.261.", },
164     {.input = "192.0.2\256", },
165     {.input = "192.0.\262.", },
166     {.input = "192.062.", },
167     {.input = "192.092.\256", },
168     {.input = "192.0\2562.", },
169     {.input = "192.192.0.2661\031", },
170     {.input = "192.192.00n2.1.", },
171     {.input = "192.192.2.190.", },
172     {.input = "192.255.255.2555", },
173     {.input = "192.92.219\023.", },
174     {.input = "192.\260.2.", },
175     {.input = "1:1::1:1",
176      .ipv6_ok = true,
177      .ipv6_expected = {
178        0x0, 0x1, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0,
179        0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x1
180      },
181     },
182     {.input = "2", },
183     {.input = "2.", },
184     {.input = "2001:db8:00001::f", },
185     {.input = "2001:db8:10000::f", },
186     {.input = "2001:db8:1234:5678:abcd:ef01:2345:67",
187      .ipv6_ok = true,
188      .ipv6_expected = {
189        0x20, 0x1, 0xd, 0xb8, 0x12, 0x34, 0x56, 0x78,
190        0xab, 0xcd, 0xef, 0x1, 0x23, 0x45, 0x0, 0x67
191      },
192     },
193     {.input = "2001:db8:1234:5678:abcd:ef01:2345:6789:1", },
194     {.input = "2001:db8:1234:5678:abcd:ef01:2345::6789", },
195     {.input = "2001:db8::0",
196      .ipv6_ok = true,
197      .ipv6_expected = {
198        0x20, 0x1, 0xd, 0xb8, 0x0, 0x0, 0x0, 0x0,
199        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0
200      },
201     },
202     {.input = "2001:db8::00",
203      .ipv6_ok = true,
204      .ipv6_expected = {
205        0x20, 0x1, 0xd, 0xb8, 0x0, 0x0, 0x0, 0x0,
206        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0
207      },
208     },
209     {.input = "2001:db8::1",
210      .ipv6_ok = true,
211      .ipv6_expected = {
212        0x20, 0x1, 0xd, 0xb8, 0x0, 0x0, 0x0, 0x0,
213        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1
214      },
215     },
216     {.input = "2001:db8::10",
217      .ipv6_ok = true,
218      .ipv6_expected = {
219        0x20, 0x1, 0xd, 0xb8, 0x0, 0x0, 0x0, 0x0,
220        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10
221      },
222     },
223     {.input = "2001:db8::19",
224      .ipv6_ok = true,
225      .ipv6_expected = {
226        0x20, 0x1, 0xd, 0xb8, 0x0, 0x0, 0x0, 0x0,
227        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x19
228      },
229     },
230     {.input = "2001:db8::1::\012", },
231     {.input = "2001:db8::1::2\012", },
232     {.input = "2001:db8::2",
233      .ipv6_ok = true,
234      .ipv6_expected = {
235        0x20, 0x1, 0xd, 0xb8, 0x0, 0x0, 0x0, 0x0,
236        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2
237      },
238     },
239     {.input = "2001:db8::3",
240      .ipv6_ok = true,
241      .ipv6_expected = {
242        0x20, 0x1, 0xd, 0xb8, 0x0, 0x0, 0x0, 0x0,
243        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3
244      },
245     },
246     {.input = "2001:db8::4",
247      .ipv6_ok = true,
248      .ipv6_expected = {
249        0x20, 0x1, 0xd, 0xb8, 0x0, 0x0, 0x0, 0x0,
250        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4
251      },
252     },
253     {.input = "2001:db8::5",
254      .ipv6_ok = true,
255      .ipv6_expected = {
256        0x20, 0x1, 0xd, 0xb8, 0x0, 0x0, 0x0, 0x0,
257        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x5
258      },
259     },
260     {.input = "2001:db8::6",
261      .ipv6_ok = true,
262      .ipv6_expected = {
263        0x20, 0x1, 0xd, 0xb8, 0x0, 0x0, 0x0, 0x0,
264        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x6
265      },
266     },
267     {.input = "2001:db8::7",
268      .ipv6_ok = true,
269      .ipv6_expected = {
270        0x20, 0x1, 0xd, 0xb8, 0x0, 0x0, 0x0, 0x0,
271        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x7
272      },
273     },
274     {.input = "2001:db8::8",
275      .ipv6_ok = true,
276      .ipv6_expected = {
277        0x20, 0x1, 0xd, 0xb8, 0x0, 0x0, 0x0, 0x0,
278        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8
279      },
280     },
281     {.input = "2001:db8::9",
282      .ipv6_ok = true,
283      .ipv6_expected = {
284        0x20, 0x1, 0xd, 0xb8, 0x0, 0x0, 0x0, 0x0,
285        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x9
286      },
287     },
288     {.input = "2001:db8::A",
289      .ipv6_ok = true,
290      .ipv6_expected = {
291        0x20, 0x1, 0xd, 0xb8, 0x0, 0x0, 0x0, 0x0,
292        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xa
293      },
294     },
295     {.input = "2001:db8::B",
296      .ipv6_ok = true,
297      .ipv6_expected = {
298        0x20, 0x1, 0xd, 0xb8, 0x0, 0x0, 0x0, 0x0,
299        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xb
300      },
301     },
302     {.input = "2001:db8::C",
303      .ipv6_ok = true,
304      .ipv6_expected = {
305        0x20, 0x1, 0xd, 0xb8, 0x0, 0x0, 0x0, 0x0,
306        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc
307      },
308     },
309     {.input = "2001:db8::D",
310      .ipv6_ok = true,
311      .ipv6_expected = {
312        0x20, 0x1, 0xd, 0xb8, 0x0, 0x0, 0x0, 0x0,
313        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xd
314      },
315     },
316     {.input = "2001:db8::E",
317      .ipv6_ok = true,
318      .ipv6_expected = {
319        0x20, 0x1, 0xd, 0xb8, 0x0, 0x0, 0x0, 0x0,
320        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xe
321      },
322     },
323     {.input = "2001:db8::F",
324      .ipv6_ok = true,
325      .ipv6_expected = {
326        0x20, 0x1, 0xd, 0xb8, 0x0, 0x0, 0x0, 0x0,
327        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xf
328      },
329     },
330     {.input = "2001:db8::a",
331      .ipv6_ok = true,
332      .ipv6_expected = {
333        0x20, 0x1, 0xd, 0xb8, 0x0, 0x0, 0x0, 0x0,
334        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xa
335      },
336     },
337     {.input = "2001:db8::b",
338      .ipv6_ok = true,
339      .ipv6_expected = {
340        0x20, 0x1, 0xd, 0xb8, 0x0, 0x0, 0x0, 0x0,
341        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xb
342      },
343     },
344     {.input = "2001:db8::c",
345      .ipv6_ok = true,
346      .ipv6_expected = {
347        0x20, 0x1, 0xd, 0xb8, 0x0, 0x0, 0x0, 0x0,
348        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xc
349      },
350     },
351     {.input = "2001:db8::d",
352      .ipv6_ok = true,
353      .ipv6_expected = {
354        0x20, 0x1, 0xd, 0xb8, 0x0, 0x0, 0x0, 0x0,
355        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xd
356      },
357     },
358     {.input = "2001:db8::e",
359      .ipv6_ok = true,
360      .ipv6_expected = {
361        0x20, 0x1, 0xd, 0xb8, 0x0, 0x0, 0x0, 0x0,
362        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xe
363      },
364     },
365     {.input = "2001:db8::f",
366      .ipv6_ok = true,
367      .ipv6_expected = {
368        0x20, 0x1, 0xd, 0xb8, 0x0, 0x0, 0x0, 0x0,
369        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xf
370      },
371     },
372     {.input = "2001:db8::ff",
373      .ipv6_ok = true,
374      .ipv6_expected = {
375        0x20, 0x1, 0xd, 0xb8, 0x0, 0x0, 0x0, 0x0,
376        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xff
377      },
378     },
379     {.input = "2001:db8::ffff:2\012", },
380     {.input = "22", },
381     {.input = "2222@", },
382     {.input = "255.255.255.255",
383      .ipv4_ok = true,
384      .ipv4_expected = {255, 255, 255, 255},
385     },
386     {.input = "255.255.255.255\001", },
387     {.input = "255.255.255.25555", },
388     {.input = "2:", },
389     {.input = "2:a:8:EEEE::EEEE:F:EEE8:EEEE\034*:", },
390     {.input = "2:ff:1:1:7:ff:1:1:7.", },
391     {.input = "2f:0000000000000000000000000000000000000000000000000000000000"
392      "0000000000000000000000000000000000000000000000000000000000000000000000"
393      "0G01",
394     },
395     {.input = "429495", },
396     {.input = "5::5::", },
397     {.input = "6.6.", },
398     {.input = "992.", },
399     {.input = "::",
400      .ipv6_ok = true,
401      .ipv6_expected = {
402        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
403        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0
404      },
405     },
406     {.input = "::00001", },
407     {.input = "::1",
408      .ipv6_ok = true,
409      .ipv6_expected = {
410        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
411        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1
412      },
413     },
414     {.input = "::10000", },
415     {.input = "::1:1",
416      .ipv6_ok = true,
417      .ipv6_expected = {
418        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
419        0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x1
420      },
421     },
422     {.input = "::ff:1:1:7.0.0.1",
423      .ipv6_ok = true,
424      .ipv6_expected = {
425        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xff,
426        0x0, 0x1, 0x0, 0x1, 0x7, 0x0, 0x0, 0x1
427      },
428     },
429     {.input = "::ff:1:1:7:ff:1:1:7.", },
430     {.input = "::ff:1:1:7ff:1:8:7.0.0.1", },
431     {.input = "::ff:1:1:7ff:1:8f:1:1:71", },
432     {.input = "::ffff:02fff:127.0.S1", },
433     {.input = "::ffff:127.0.0.1",
434      .ipv6_ok = true,
435      .ipv6_expected = {
436        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
437        0x0, 0x0, 0xff, 0xff, 0x7f, 0x0, 0x0, 0x1
438      },
439     },
440     {.input = "::ffff:1:7.0.0.1",
441      .ipv6_ok = true,
442      .ipv6_expected = {
443        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
444        0xff, 0xff, 0x0, 0x1, 0x7, 0x0, 0x0, 0x1
445      },
446     },
447     {.input = ":\272", },
448     {.input = "A:f:ff:1:1:D:ff:1:1::7.", },
449     {.input = "AAAAA.", },
450     {.input = "D:::", },
451     {.input = "DF8F", },
452     {.input = "F::",
453      .ipv6_ok = true,
454      .ipv6_expected = {
455        0x0, 0xf, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
456        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0
457      },
458     },
459     {.input = "F:A:8:EEEE:8:EEEE\034*:", },
460     {.input = "F:a:8:EEEE:8:EEEE\034*:", },
461     {.input = "F:ff:100:7ff:1:8:7.0.10.1",
462      .ipv6_ok = true,
463      .ipv6_expected = {
464        0x0, 0xf, 0x0, 0xff, 0x1, 0x0, 0x7, 0xff,
465        0x0, 0x1, 0x0, 0x8, 0x7, 0x0, 0xa, 0x1
466      },
467     },
468     {.input = "d92.", },
469     {.input = "ff:00000000000000000000000000000000000000000000000000000000000"
470      "00000000000000000000000000000000000000000000000000000000000000000001",
471     },
472     {.input = "fff2:2::ff2:2:f7",
473      .ipv6_ok = true,
474      .ipv6_expected = {
475        0xff, 0xf2, 0x0, 0x2, 0x0, 0x0, 0x0, 0x0,
476        0x0, 0x0, 0xf, 0xf2, 0x0, 0x2, 0x0, 0xf7
477      },
478     },
479     {.input = "ffff:ff:ff:fff:ff:ff:ff:", },
480     {.input = "\272:", },
481     {NULL}
482   };
483 
484 static int
do_test(void)485 do_test (void)
486 {
487   for (size_t i = 0; test_cases[i].input != NULL; ++i)
488     run_one_test (test_cases + i);
489   return 0;
490 }
491 
492 #include <support/test-driver.c>
493