(root)/
glibc-2.38/
stdio-common/
test-vfprintf.c
       1  /* Tests of *printf for very large strings.
       2     Copyright (C) 2000-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 <array_length.h>
      20  #include <locale.h>
      21  #include <mcheck.h>
      22  #include <stdint.h>
      23  #include <stdio.h>
      24  #include <stdlib.h>
      25  #include <string.h>
      26  #include <unistd.h>
      27  #include <sys/stat.h>
      28  #include <libc-diag.h>
      29  
      30  
      31  const char *locs[] =
      32  {
      33    "C", "de_DE.ISO-8859-1", "de_DE.UTF-8", "ja_JP.EUC-JP"
      34  };
      35  
      36  char large[50000];
      37  
      38  static int
      39  do_test (void)
      40  {
      41    char buf[25];
      42    size_t i;
      43    int res = 0;
      44    int fd;
      45  
      46    mtrace ();
      47  
      48    strcpy (buf, "/tmp/test-vfprintfXXXXXX");
      49    fd = mkstemp (buf);
      50    if (fd == -1)
      51      {
      52        printf ("cannot open temporary file: %m\n");
      53        exit (1);
      54      }
      55    unlink (buf);
      56  
      57    for (i = 0; i < array_length (locs); ++i)
      58      {
      59        FILE *fp;
      60        struct stat st;
      61        int fd2;
      62  
      63        setlocale (LC_ALL, locs[i]);
      64  
      65        memset (large, '\1', sizeof (large));
      66        large[sizeof (large) - 1] = '\0';
      67  
      68        fd2 = dup (fd);
      69        if (fd2 == -1)
      70  	{
      71  	  printf ("cannot dup for locale %s: %m\n",
      72  		  setlocale (LC_ALL, NULL));
      73  	  exit (1);
      74  	}
      75  
      76        if (ftruncate (fd2, 0) != 0)
      77  	{
      78  	  printf ("cannot truncate file for locale %s: %m\n",
      79  		  setlocale (LC_ALL, NULL));
      80  	  exit (1);
      81  	}
      82  
      83        fp = fdopen (fd2, "a");
      84        if (fp == NULL)
      85  	{
      86  	  printf ("cannot create FILE for locale %s: %m\n",
      87  		  setlocale (LC_ALL, NULL));
      88  	  exit (1);
      89  	}
      90  
      91        fprintf (fp, "%s", large);
      92        fprintf (fp, "%.*s", 30000, large);
      93        large[20000] = '\0';
      94        /* We're testing a large format string here and need to generate it
      95           to avoid this source file being ridiculous.  So disable the warning
      96           about a generated format string.  */
      97        DIAG_PUSH_NEEDS_COMMENT;
      98        DIAG_IGNORE_NEEDS_COMMENT (4.9, "-Wformat-security");
      99        fprintf (fp, large);
     100        DIAG_POP_NEEDS_COMMENT;
     101        fprintf (fp, "%-1.300000000s", "hello");
     102  
     103        if (fflush (fp) != 0 || ferror (fp) != 0 || fclose (fp) != 0)
     104  	{
     105  	  printf ("write error for locale %s: %m\n",
     106  		  setlocale (LC_ALL, NULL));
     107  	  exit (1);
     108  	}
     109  
     110        if (fstat (fd, &st) != 0)
     111  	{
     112  	  printf ("cannot stat for locale %s: %m\n",
     113  		  setlocale (LC_ALL, NULL));
     114  	  exit (1);
     115  	}
     116        else if (st.st_size != 50000 + 30000 + 19999 + 5)
     117  	{
     118  	  printf ("file size incorrect for locale %s: %jd instead of %jd\n",
     119  		  setlocale (LC_ALL, NULL),
     120  		  (intmax_t) st.st_size,
     121  		  (intmax_t) 50000 + 30000 + 19999 + 5);
     122  	  res = 1;
     123  	}
     124        else
     125  	printf ("locale %s OK\n", setlocale (LC_ALL, NULL));
     126      }
     127  
     128    close (fd);
     129  
     130    return res;
     131  }
     132  
     133  #define TEST_FUNCTION do_test ()
     134  #include "../test-skeleton.c"