(root)/
glibc-2.38/
libio/
tst-ftell-partial-wide.c
       1  /* Verify that ftell does not go into an infinite loop when a conversion fails
       2     due to insufficient space in the buffer.
       3     Copyright (C) 2014-2023 Free Software Foundation, Inc.
       4     This file is part of the GNU C Library.
       5  
       6     The GNU C Library is free software; you can redistribute it and/or
       7     modify it under the terms of the GNU Lesser General Public
       8     License as published by the Free Software Foundation; either
       9     version 2.1 of the License, or (at your option) any later version.
      10  
      11     The GNU C Library is distributed in the hope that it will be useful,
      12     but WITHOUT ANY WARRANTY; without even the implied warranty of
      13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      14     Lesser General Public License for more details.
      15  
      16     You should have received a copy of the GNU Lesser General Public
      17     License along with the GNU C Library; if not, see
      18     <https://www.gnu.org/licenses/>.  */
      19  
      20  #include <wchar.h>
      21  #include <stdio.h>
      22  #include <stdlib.h>
      23  #include <string.h>
      24  #include <locale.h>
      25  #include <errno.h>
      26  #include <unistd.h>
      27  
      28  static int do_test (void);
      29  #define TEST_FUNCTION do_test ()
      30  #include "../test-skeleton.c"
      31  
      32  /* Arbitrary number large enough so that the target buffer during conversion is
      33     not large enough.  */
      34  #define STRING_SIZE (1400)
      35  #define NSTRINGS (2)
      36  
      37  static int
      38  do_test (void)
      39  {
      40    FILE *fp = NULL;
      41    wchar_t *inputs[NSTRINGS] = {NULL};
      42    int ret = 1;
      43  
      44    if (setlocale (LC_ALL, "en_US.UTF-8") == NULL)
      45      {
      46        printf ("Cannot set en_US.UTF-8 locale.\n");
      47        goto out;
      48      }
      49  
      50  
      51    /* Generate input from one character, chosen because it has an odd number of
      52       bytes in UTF-8, making it easier to reproduce the problem:
      53  
      54       NAME    Hiragana letter GO
      55       CHAR    ご
      56       UTF-8   E38194
      57       UCS     3054
      58       MARC-8  692434  */
      59    wchar_t seed = L'';
      60    for (int i = 0; i < NSTRINGS; i++)
      61      {
      62        inputs[i] = malloc (STRING_SIZE * sizeof (wchar_t));
      63        if (inputs[i] == NULL)
      64  	{
      65  	  printf ("Failed to allocate memory for inputs: %m\n");
      66  	  goto out;
      67  	}
      68        wmemset (inputs[i], seed, STRING_SIZE - 1);
      69        inputs[i][STRING_SIZE - 1] = L'\0';
      70      }
      71  
      72    char *filename;
      73    int fd = create_temp_file ("tst-fseek-wide-partial.out", &filename);
      74  
      75    if (fd == -1)
      76      {
      77        printf ("create_temp_file: %m\n");
      78        goto out;
      79      }
      80  
      81    fp = fdopen (fd, "w+");
      82    if (fp == NULL)
      83      {
      84        printf ("fopen: %m\n");
      85        close (fd);
      86        goto out;
      87      }
      88  
      89    for (int i = 0; i < NSTRINGS; i++)
      90      {
      91        printf ("offset: %ld\n", ftell (fp));
      92        if (fputws (inputs[i], fp) == -1)
      93  	{
      94  	  perror ("fputws");
      95  	  goto out;
      96  	}
      97      }
      98    ret = 0;
      99  
     100  out:
     101    if (fp != NULL)
     102      fclose (fp);
     103    for (int i = 0; i < NSTRINGS; i++)
     104      free (inputs[i]);
     105  
     106    return ret;
     107  }