Blame stdio-common/tst-sscanf.c

Packit Service 82fcde
/* Copyright (C) 2000-2018 Free Software Foundation, Inc.
Packit Service 82fcde
   This file is part of the GNU C Library.
Packit Service 82fcde
   Contributed by Jakub Jelinek <jakub@redhat.com>, 2000.
Packit Service 82fcde
Packit Service 82fcde
   The GNU C Library is free software; you can redistribute it and/or
Packit Service 82fcde
   modify it under the terms of the GNU Lesser General Public
Packit Service 82fcde
   License as published by the Free Software Foundation; either
Packit Service 82fcde
   version 2.1 of the License, or (at your option) any later version.
Packit Service 82fcde
Packit Service 82fcde
   The GNU C Library is distributed in the hope that it will be useful,
Packit Service 82fcde
   but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit Service 82fcde
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit Service 82fcde
   Lesser General Public License for more details.
Packit Service 82fcde
Packit Service 82fcde
   You should have received a copy of the GNU Lesser General Public
Packit Service 82fcde
   License along with the GNU C Library; if not, see
Packit Service 82fcde
   <http://www.gnu.org/licenses/>.  */
Packit Service 82fcde
Packit Service 82fcde
#include <array_length.h>
Packit Service 82fcde
#include <stdlib.h>
Packit Service 82fcde
#include <stdio.h>
Packit Service 82fcde
#include <locale.h>
Packit Service 82fcde
Packit Service 82fcde
#ifndef CHAR
Packit Service 82fcde
# define CHAR char
Packit Service 82fcde
# define L(str) str
Packit Service 82fcde
# define SSCANF sscanf
Packit Service 82fcde
#endif
Packit Service 82fcde
Packit Service 82fcde
const CHAR *str_double[] =
Packit Service 82fcde
{
Packit Service 82fcde
  L("-.10000E+020.20000E+020.25000E+010.40000E+010.50000E+010.12500E+01"),
Packit Service 82fcde
  L("0.10000E+020.20000E+020.25000E+010.40000E+010.50000E+010.12500E+01"),
Packit Service 82fcde
  L("-1234567E0198765432E0912345678901987654321091234567890198765432109"),
Packit Service 82fcde
  L("-0.1000E+020.20000E+020.25000E+010.40000E+010.50000E+010.12500E+01")
Packit Service 82fcde
};
Packit Service 82fcde
Packit Service 82fcde
const double val_double[] =
Packit Service 82fcde
{
Packit Service 82fcde
  -.10000E+02, 0.20000E+02, 0.25000E+01, 0.40000E+01, 0.50000E+01, 0.12500E+01,
Packit Service 82fcde
  0.10000E+02, 0.20000E+02, 0.25000E+01, 0.40000E+01, 0.50000E+01, 0.12500E+01,
Packit Service 82fcde
  -1234567E01, 98765432E09, 12345678901.0, 98765432109.0, 12345678901.0,
Packit Service 82fcde
    98765432109.0,
Packit Service 82fcde
  -0.1000E+02, 0.20000E+02, 0.25000E+01, 0.40000E+01, 0.50000E+01, 0.12500E+01
Packit Service 82fcde
};
Packit Service 82fcde
Packit Service 82fcde
const CHAR *str_long[] =
Packit Service 82fcde
{
Packit Service 82fcde
  L("-12345678987654321123456789987654321123456789987654321"),
Packit Service 82fcde
  L("-12345678987654321123456789987654321123456789987654321"),
Packit Service 82fcde
  L("-12,345,678987,654,321123,456,789987,654,321123,456,789987,654,321"),
Packit Service 82fcde
  L("-12,345,678987,654,321123,456,789987,654,321123,456,789987,654,321")
Packit Service 82fcde
};
Packit Service 82fcde
Packit Service 82fcde
const CHAR *fmt_long[] =
Packit Service 82fcde
{
Packit Service 82fcde
  L("%9ld%9ld%9ld%9ld%9ld%9ld"),
Packit Service 82fcde
  L("%I9ld%I9ld%I9ld%I9ld%I9ld%I9ld"),
Packit Service 82fcde
  L("%'11ld%'11ld%'11ld%'11ld%'11ld%'11ld"),
Packit Service 82fcde
  L("%I'11ld%I'11ld%I'11ld%I'11ld%I'11ld%I'11ld")
Packit Service 82fcde
};
Packit Service 82fcde
Packit Service 82fcde
const long int val_long[] =
Packit Service 82fcde
{
Packit Service 82fcde
  -12345678, 987654321, 123456789, 987654321, 123456789, 987654321
Packit Service 82fcde
};
Packit Service 82fcde
Packit Service 82fcde
struct test
Packit Service 82fcde
{
Packit Service 82fcde
  const CHAR *str;
Packit Service 82fcde
  const CHAR *fmt;
Packit Service 82fcde
  int retval;
Packit Service 82fcde
} int_tests[] =
Packit Service 82fcde
{
Packit Service 82fcde
  { L("foo\n"), L("foo\nbar"), -1 },
Packit Service 82fcde
  { L("foo\n"), L("foo bar"), -1 },
Packit Service 82fcde
  { L("foo\n"), L("foo %d"), -1 },
Packit Service 82fcde
  { L("foo\n"), L("foo\n%d"), -1 },
Packit Service 82fcde
  { L("foon"), L("foonbar"), -1 },
Packit Service 82fcde
  { L("foon"), L("foon%d"), -1 },
Packit Service 82fcde
  { L("foo "), L("foo bar"), -1 },
Packit Service 82fcde
  { L("foo "), L("foo %d"), -1 },
Packit Service 82fcde
  { L("foo\t"), L("foo\tbar"), -1 },
Packit Service 82fcde
  { L("foo\t"), L("foo bar"), -1 },
Packit Service 82fcde
  { L("foo\t"), L("foo %d"), -1 },
Packit Service 82fcde
  { L("foo\t"), L("foo\t%d"), -1 },
Packit Service 82fcde
  { L("foo"), L("foo"), 0 },
Packit Service 82fcde
  { L("foon"), L("foo bar"), 0 },
Packit Service 82fcde
  { L("foon"), L("foo %d"), 0 },
Packit Service 82fcde
  { L("foo "), L("fooxbar"), 0 },
Packit Service 82fcde
  { L("foo "), L("foox%d"), 0 },
Packit Service 82fcde
  { L("foo bar"), L("foon"), 0 },
Packit Service 82fcde
  { L("foo bar"), L("foo bar"), 0 },
Packit Service 82fcde
  { L("foo bar"), L("foo %d"), 0 },
Packit Service 82fcde
  { L("foo bar"), L("foon%d"), 0 },
Packit Service 82fcde
  { L("foo (nil)"), L("foo %p"), 1},
Packit Service 82fcde
  { L("foo (nil)"), L("foo %4p"), 0},
Packit Service 82fcde
  { L("foo "), L("foo %n"), 0 },
Packit Service 82fcde
  { L("foo%bar1"), L("foo%%bar%d"), 1 },
Packit Service 82fcde
  /* Some OSes skip whitespace here while others don't.  */
Packit Service 82fcde
  { L("foo \t %bar1"), L("foo%%bar%d"), 1 }
Packit Service 82fcde
};
Packit Service 82fcde
Packit Service 82fcde
struct test double_tests[] =
Packit Service 82fcde
{
Packit Service 82fcde
  { L("-1"), L("%1g"), 0 },
Packit Service 82fcde
  { L("-.1"), L("%2g"), 0 },
Packit Service 82fcde
  { L("-inf"), L("%3g"), 0 },
Packit Service 82fcde
  { L("+0"), L("%1g"),  },
Packit Service 82fcde
  { L("-0x1p0"), L("%2g"), 1 },
Packit Service 82fcde
  { L("-..1"), L("%g"), 0 },
Packit Service 82fcde
  { L("-inf"), L("%g"), 1 }
Packit Service 82fcde
};
Packit Service 82fcde
Packit Service 82fcde
struct test2
Packit Service 82fcde
{
Packit Service 82fcde
  const CHAR *str;
Packit Service 82fcde
  const CHAR *fmt;
Packit Service 82fcde
  int retval;
Packit Service 82fcde
  char residual;
Packit Service 82fcde
} double_tests2[] =
Packit Service 82fcde
{
Packit Service 82fcde
  { L("0e+0"), L("%g%c"), 1, 0 },
Packit Service 82fcde
  { L("0xe+0"), L("%g%c"), 2, '+' },
Packit Service 82fcde
  { L("0x.e+0"), L("%g%c"), 2, '+' },
Packit Service 82fcde
};
Packit Service 82fcde
Packit Service 82fcde
static int
Packit Service 82fcde
do_test (void)
Packit Service 82fcde
{
Packit Service 82fcde
  double d[6];
Packit Service 82fcde
  long l[6];
Packit Service 82fcde
  int i, j;
Packit Service 82fcde
  int tst_locale;
Packit Service 82fcde
  int result = 0;
Packit Service 82fcde
Packit Service 82fcde
  tst_locale = 1;
Packit Service 82fcde
  if (tst_locale)
Packit Service 82fcde
    if (setlocale (LC_ALL, "en_US.ISO-8859-1") == NULL)
Packit Service 82fcde
      {
Packit Service 82fcde
	puts ("Failed to set en_US locale, skipping locale related tests");
Packit Service 82fcde
	tst_locale = 0;
Packit Service 82fcde
      }
Packit Service 82fcde
Packit Service 82fcde
  for (i = 0; i < 4; ++i)
Packit Service 82fcde
    {
Packit Service 82fcde
      if (SSCANF (str_double[i], L("%11lf%11lf%11lf%11lf%11lf%11lf"),
Packit Service 82fcde
		  &d[0], &d[1], &d[2], &d[3], &d[4], &d[5]) != 6)
Packit Service 82fcde
	{
Packit Service 82fcde
	  printf ("Double sscanf test %d wrong number of "
Packit Service 82fcde
		  "assigned inputs\n", i);
Packit Service 82fcde
	  result = 1;
Packit Service 82fcde
	}
Packit Service 82fcde
      else
Packit Service 82fcde
	for (j = 0; j < 6; ++j)
Packit Service 82fcde
	  if (d[j] != val_double[6 * i + j])
Packit Service 82fcde
	    {
Packit Service 82fcde
	      printf ("Double sscanf test %d failed (%g instead of %g)\n",
Packit Service 82fcde
		      i, d[j], val_double[6 * i + j]);
Packit Service 82fcde
	      result = 1;
Packit Service 82fcde
	      break;
Packit Service 82fcde
	    }
Packit Service 82fcde
    }
Packit Service 82fcde
Packit Service 82fcde
  for (i = 0; i < 4; ++i)
Packit Service 82fcde
    {
Packit Service 82fcde
      if (SSCANF (str_long[i], fmt_long[i],
Packit Service 82fcde
		  &l[0], &l[1], &l[2], &l[3], &l[4], &l[5]) != 6)
Packit Service 82fcde
	{
Packit Service 82fcde
	  printf ("Integer sscanf test %d wrong number of "
Packit Service 82fcde
		  "assigned inputs\n", i);
Packit Service 82fcde
	  result = 1;
Packit Service 82fcde
	}
Packit Service 82fcde
      else
Packit Service 82fcde
	for (j = 0; j < 6; ++j)
Packit Service 82fcde
	  if (l[j] != val_long[j])
Packit Service 82fcde
	    {
Packit Service 82fcde
	      printf ("Integer sscanf test %d failed (%ld instead %ld)\n",
Packit Service 82fcde
		      i, l[j], val_long[j]);
Packit Service 82fcde
	      result = 1;
Packit Service 82fcde
	      break;
Packit Service 82fcde
	    }
Packit Service 82fcde
Packit Service 82fcde
      if (! tst_locale)
Packit Service 82fcde
	break;
Packit Service 82fcde
    }
Packit Service 82fcde
Packit Service 82fcde
  for (i = 0; i < array_length (int_tests); ++i)
Packit Service 82fcde
    {
Packit Service 82fcde
      long dummy;
Packit Service 82fcde
      int ret;
Packit Service 82fcde
Packit Service 82fcde
      if ((ret = SSCANF (int_tests[i].str, int_tests[i].fmt,
Packit Service 82fcde
			 &dummy)) != int_tests[i].retval)
Packit Service 82fcde
	{
Packit Service 82fcde
	  printf ("int_tests[%d] returned %d != %d\n",
Packit Service 82fcde
		  i, ret, int_tests[i].retval);
Packit Service 82fcde
	  result = 1;
Packit Service 82fcde
	}
Packit Service 82fcde
    }
Packit Service 82fcde
Packit Service 82fcde
  for (i = 0; i < array_length (double_tests); ++i)
Packit Service 82fcde
    {
Packit Service 82fcde
      double dummy;
Packit Service 82fcde
      int ret;
Packit Service 82fcde
Packit Service 82fcde
      if ((ret = SSCANF (double_tests[i].str, double_tests[i].fmt,
Packit Service 82fcde
			 &dummy)) != double_tests[i].retval)
Packit Service 82fcde
	{
Packit Service 82fcde
	  printf ("double_tests[%d] returned %d != %d\n",
Packit Service 82fcde
		  i, ret, double_tests[i].retval);
Packit Service 82fcde
	  result = 1;
Packit Service 82fcde
	}
Packit Service 82fcde
    }
Packit Service 82fcde
Packit Service 82fcde
  for (i = 0; i < array_length (double_tests2); ++i)
Packit Service 82fcde
    {
Packit Service 82fcde
      double dummy;
Packit Service 82fcde
      int ret;
Packit Service 82fcde
      char c = 0;
Packit Service 82fcde
Packit Service 82fcde
      if ((ret = SSCANF (double_tests2[i].str, double_tests2[i].fmt,
Packit Service 82fcde
			 &dummy, &c)) != double_tests2[i].retval)
Packit Service 82fcde
	{
Packit Service 82fcde
	  printf ("double_tests2[%d] returned %d != %d\n",
Packit Service 82fcde
		  i, ret, double_tests2[i].retval);
Packit Service 82fcde
	  result = 1;
Packit Service 82fcde
	}
Packit Service 82fcde
      else if (ret == 2 && c != double_tests2[i].residual)
Packit Service 82fcde
	{
Packit Service 82fcde
	  printf ("double_tests2[%d] stopped at '%c' != '%c'\n",
Packit Service 82fcde
		  i, c, double_tests2[i].residual);
Packit Service 82fcde
	  result = 1;
Packit Service 82fcde
	}
Packit Service 82fcde
    }
Packit Service 82fcde
Packit Service 82fcde
  /* BZ #16618
Packit Service 82fcde
     The test will segfault during SSCANF if the buffer overflow
Packit Service 82fcde
     is not fixed.  The size of `s` is such that it forces the use
Packit Service 82fcde
     of malloc internally and this triggers the incorrect computation.
Packit Service 82fcde
     Thus the value for SIZE is arbitrariy high enough that malloc
Packit Service 82fcde
     is used.  */
Packit Service 82fcde
  {
Packit Service 82fcde
#define SIZE 131072
Packit Service 82fcde
    CHAR *s = malloc ((SIZE + 1) * sizeof (*s));
Packit Service 82fcde
    if (s == NULL)
Packit Service 82fcde
      abort ();
Packit Service 82fcde
    for (size_t i = 0; i < SIZE; i++)
Packit Service 82fcde
      s[i] = L('0');
Packit Service 82fcde
    s[SIZE] = L('\0');
Packit Service 82fcde
    int i = 42;
Packit Service 82fcde
    /* Scan multi-digit zero into `i`.  */
Packit Service 82fcde
    if (SSCANF (s, L("%d"), &i) != 1)
Packit Service 82fcde
      {
Packit Service 82fcde
	printf ("FAIL: bug16618: SSCANF did not read one input item.\n");
Packit Service 82fcde
	result = 1;
Packit Service 82fcde
      }
Packit Service 82fcde
    if (i != 0)
Packit Service 82fcde
      {
Packit Service 82fcde
	printf ("FAIL: bug16618: Value of `i` was not zero as expected.\n");
Packit Service 82fcde
	result = 1;
Packit Service 82fcde
      }
Packit Service 82fcde
    free (s);
Packit Service 82fcde
    if (result != 1)
Packit Service 82fcde
      printf ("PASS: bug16618: Did not crash.\n");
Packit Service 82fcde
#undef SIZE
Packit Service 82fcde
  }
Packit Service 82fcde
Packit Service 82fcde
Packit Service 82fcde
  return result;
Packit Service 82fcde
}
Packit Service 82fcde
Packit Service 82fcde
#define TEST_FUNCTION do_test ()
Packit Service 82fcde
#include "../test-skeleton.c"